Demo | Documentation | Download

Files Needed:

- Click here to download CI Flexigrid with samples

Introduction:

This is an example on how to setup a grid like in the demonstration. I assume that you already have some bases on CI before reading this, if you dont, read their excellent documentation here.
I'm sorry for any misspellings.
I strongly advise to download the example and look at the code while reading this, it will be much easier.

Setup:

After downloading and extracting the library, config file and helper, import the country.sql table to your database and create 2 controllers, 1 model and 1 view:

- Controller flexigrid.php - This controller can be named anything, its the controller that's going to configure and generate the grid's structure (javascript) and load the view

- Controller ajax.php - This is the controller thats going to handle the AJAX requests

- Model ajax_model.php - This is the model thats going to make all the database calls that the ajax controller needs

- View flexigrid.php - This is the view thats going to display it all

Before continuing make sure you have the CI URL helper and the CI Database Library in "autoload". Also you need the $config['base_url'] in the config.php file correctly set, with ending slash. (eg. http://flexigridci/)

Flexigrid Controller:

As said before, in this controller we are going to setup the grid's structure.
First of all, we must load the flexigrid helper: function Flexigrid ()
{
parent::Controller();
$this->load->helper('flexigrid');
}
Next, we have to create an array with all the columns that you want the grid to have, based on your query, so we can build the column header.
For example, for the query "SELECT id,iso,name,printable_name,iso3,numcode FROM country" we have to build the following array (insert the code below in the index function of your controller):
$colModel['id'] = array('ID',40,TRUE,'center',2);
$colModel['iso'] = array('ISO',40,TRUE,'center',0);
$colModel['name'] = array('Name',180,TRUE,'left',1);
$colModel['printable_name'] = array('Printable Name',120,TRUE,'left',0);
$colModel['iso3'] = array('ISO3',130, TRUE,'left',0);
$colModel['numcode'] = array('Number Code',80, TRUE, 'right',1);
$colModel['actions'] = array('Actions',80, FALSE, 'right',0);
How to build this array:

- The index of the array $colModel has to be exactly the same name as the column in the database. (eg: column id -> id, column name -> name etc)

- 1st value of the array is label thats going to show in the column header

- 2nd value is the width of the column in pixels

- 3rd value determines if the column is sortable: TRUE or FALSE

- 4th value determines the columns identation: "left", "right" or "center"

- 5th value determines if that column is searchable with Flexigrid's search feature: 2 -> yes and default, 1 -> yes, 0 -> no

- 6th value determines if that column is hidden by default: TRUE or FALSE (This is Optional)


Now, to setup the other parameters like "width", "height", and every other parameter that's available on FlexiGrid we have to create another array:
$gridParams = array(
'width' => 'auto',
'height' => 400,
'rp' => 15,
'rpOptions' => '[10,15,20,25,40]',
'pagestat' => 'Displaying: {from} to {to} of {total} items.',
'blockOpacity' => 0.5,
'title' => 'Hello',
'showTableToggleBtn' => true
);
This array is simple; the array index is the name of the param like width, height, etc (look above for some examples. you can see all of these in the beginning of flexigrid.js) and the value of the array is the value of the param.

Also, you can store various FlexiGrid configuration arrays in a CI configuration file and load them depending on your needs.

Mandatory: use boolean and numeric values for parameters with bool or numeric values (eg.: Use TRUE instead of 'TRUE' or 400 instead of '400')


Now that we have the column array built and the parameters set, if we want to add some buttons to the top of the grid, like "Delete", "Select All", etc we have to build another array (this is optional). In this example we will have: "Delete", "Select All", "DeSelect All":
$buttons[] = array('Delete','delete','test');
$buttons[] = array('separator');
$buttons[] = array('Select All','add','test');
$buttons[] = array('DeSelect All','delete','test');
$buttons[] = array('separator');
How to build this array:

- 1st value of the array is button's label

- 2nd value is the CSS class of the button, so you can add a nice icon like in the demonstration

- 3rd value is the JavaScript function that's going to be called when you press the button

- As you noticed, I added a 'separator' value to the array, this will add a separator between buttons.


Now that we have our column header, buttons and parameters set, lets build the grid's javascript. To do this we call a helper function:
$grid_js = build_grid_js('flex1',site_url("/ajax"),$colModel,'id','asc',$gridParams,$buttons); Description of the function's parameters in order:

- Grid id, or the tables's id where the grid is going to be displayed

- URI of the controller that handles the ajax requests, in this case, the index method of the ajax controller handles this job. (/ajax)

- Column header array

- The name of the column that's going to be sorted by default

- Default sort order

- Array with aditional parameters (This param is optional)

- Button array (This param is optional. If you want to use buttons without sending "aditional parameters" set "aditional paramenters" to NULL)

Finally, we setup a data array to send to the view. $data['js_grid'] = $grid_js;
$this->load->view('flexigrid',$data); //Load view

Ajax Model:

This is the model thats going to make all the database calls that the ajax controller needs. In this model, we need to call a Flexigrid lib function to help build the query according to the grid's request. This function adds the limit, order and search functionality of the grid.
To do that, we have to build the querys. We can use two methods, one with CI's active record, the other one without. I advise the active record aproach, its more clean and less likely to fail.

WITH ACTIVE RECORD (recommended):

First, we build the query that's going to return the contents of the grid and execute it: //Select table name
$table_name = "country";

//Build contents query
$this->db->select('id,iso,name,printable_name,iso3,numcode')->from($table_name);
$this->CI->flexigrid->build_query();//Add search, order and limit

//Get contents
$return['records'] = $this->db->get();
Then we build and execute the COUNT query, that's going to count the total results returned by the content query: //Build count query
$this->db->select('count(id) as record_count')->from($table_name);
$this->CI->flexigrid->build_query(FALSE); //Add search, order and limit
$record_count = $this->db->get();
$row = $record_count->row();

//Get Record Count
$return['record_count'] = $row->record_count;
Notice that in the COUNT query, when we call the "build_query" function, we pass a bool parameter (FALSE). This is for the "build_query" function to ignore the LIMIT part of the query (we want to count all values).
The $return array must have the indexes as above.

WITHOUT ACTIVE RECORD:

First, we build the querys: $querys['main_query'] = "SELECT id,iso,name,printable_name,iso3,numcode FROM country {SEARCH_STR}";
$querys['count_query'] = "SELECT count(id) as record_count FROM country {SEARCH_STR}";
Two things:
- We ALWAYS need two querys, one to retreive the records, another that serves only as record counting. The querys must always be inserted in an array with the indexes as above.
- In order to have the Flexigrid search function, you have always to include the "{SEARCH_STR}" string at the very end of the query.

Note: I never tried this with querys that have aggregate functions that require GROUP BY. So if anyone encounters problems please notify me. If you use the active record aproach its likely that you'll not have any problems.

Now we call the build_querys function, that processes the querys. $build_querys = $this->CI->flexigrid->build_querys($querys,TRUE); Description of the function's parameters in order:

- Array with both querys

- Use WHERE or AND, depending if there already is a WHERE or not in the query: TRUE -> use WHERE, FALSE -> use AND. In this case its TRUE, because there is no WHERE in the query.

This function will return an array with 2 indexes; main_query and count_query, that are the two processed querys.

Now we make a final array with the results: //Get contents
$return['records'] = $this->db->query($build_querys['main_query']);
//Get record count
$get_record_count = $this->db->query($build_querys['count_query']);
$row = $get_record_count->row();
$return['record_count'] = $row->record_count;
The $return array must have the indexes as above.

Ajax Controller:

Now we move on to the Ajax controller. This is the controller that holds the methods that are called when there's an AJAX request.
Again, we must load some flexigrid componentes like the library and model: function Ajax ()
{
parent::Controller();
$this->load->model('ajax_model');
$this->load->library('flexigrid');
}
Now, lets start by validating the columns that are going to be sortable and searchable. This is an optional choice but prevents some undesired searching or sorting if someone messes the JS code: $valid_fields = array('id','iso','name','printable_name','iso3','numcode');
$this->flexigrid->validate_post('id','asc',$valid_fields);
In the $valid_fields array you just have to include all the columns that are sortable / searchable, defined in the $colModel array above.

The validate_post funciton executes the validation. Parameters in order:

- Name of the default sorting column

- Default sorting order

- Array with the valid fields

Next lets get the records from the database and turn them into JSON format to send to the grid.
There are two ways of doing this. The simpler and best way, envolves using the php JSON Extension that needs to be installed on PHP. If you use this method, you increase the performance and reduce the code: //Get countries
$records = $this->ajax_model->get_countries();

/*
* Json build WITH json_encode.
*/
foreach ($records['records']->result() as $row)
{
$record_items[] = array($row->id,
$row->id,
$row->iso,
$row->name,
''.addslashes($row->printable_name).'',
$row->iso3,
$row->numcode,
'<a href=\'#\'><img border=\'0\' src=\''.$this->config->item('base_url').'public/images/close.png\'></a> '
);
}

//Print please
$this->output->set_header($this->config->item('json_header'));
$this->output->set_output($this->flexigrid->json_build($records['record_count'],$record_items));
If you do not have the JSON PHP Extension installed, you can use the following method: //Get countries
$records = $this->ajax_model->get_countries();

//Init json build
if ($this->flexigrid->init_json_build($records['record_count']))
{
//Add records
foreach ($records['records']->result() as $row)
{
$record_item = array($row->id,
$row->id,
$row->iso,
$row->name,
'<span style=\'color:#ff4400\'>'.addslashes($row->printable_name).'</span>',
$row->iso3,
$row->numcode,
'<a href=\'#\'><img border=\'0\' src=\''.$this->config->item('base_url').'public/images/close.png\'></a> '
);
$this->flexigrid->json_add_item($record_item);
}
//Last item added, close up.
$this->flexigrid->json_add_item();
}

//Print please
$this->output->set_header($this->config->item('json_header'));
$this->output->set_output($this->flexigrid->json_build);
In both aproaches, we loop through all records. In each record an array is formed ($record_item) with the formated data. In the second aproach, some extra functions are called to build the JSON code. This is ignored on the first aproach.

There are two very important things about this array ($record_item or $record_items):

- The first value of the array MUST be some sort of unique id of the record so it can be used later for operations such as "Delete" etc.

- The values of the array MUST be in the same order as the values in the $colModel array. id -> id, iso -> iso, etc.

Now all its left is to return the output. To do that, we have to call a couple of CI functions, set_header and set_output. You can read about them here.

Flexigrid View:

Finally, we setup the view: <html>
<head>
<title>Flexigrid Implemented in CodeIgniter</title>
<script type="text/javascript" src="<?=$this->config->item('base_url');?>public/js/jquery.pack.js"></script>
<script type="text/javascript" src="<?=$this->config->item('base_url');?>public/js/flexigrid.pack.js"></script>
</head>
<body>

<?=$js_grid;?>

<table id="flex1" style="display:none"></table>

</body>
</html>
We print the $js_grid variable, passed by the flexigrid controller that contains the javascript code, and insert the table id "flex1" where the grid is going to apear.

The End:

I hope I was clear enough. This example is meant only to give the users an idea of how to use this implementation. I advise to look at the code, that is fully commented, to understand how it works and hopefully give some feedback to improve the system.
The CodeIgniter discussion thread on this lib is here. You're free to leave your feedback/flames :)

Download:

- Click here to download CI Flexigrid with samples