Grid (CRUD)
Grid is a set of classes that helps you to create a management interface for records in the database. To create a fully functional manager just create AdminController.php file in your plugin and put the code bellow. Replace tableName with actual table you already have in your database. Grid will automatically fetch all fields and create interface to edit records. You will find it in administration menu after refreshing the browser.
<?php namespace Plugin\MyPlugin; class AdminController { public function index() { $config = array( 'table' => 'table_name_without_prefix' ); return ipGridController($config); } }
For Grid to work properly SQL table should have:
- the same prefix as other ImpressPages tables
- a field with a name id and auto increment attribute switched on. Set idField attribute if your auto-increment field is called differently.
Common Grid options
<?php namespace Plugin\MyPlugin; class AdminController { public function index() { $config = array( 'title' => 'MyPlugin', 'table' => 'my_plugin', 'sortField' => 'personOrder', 'createPosition' => 'top', 'pageSize' => 5, 'fields' => array( array( 'label' => 'Name', 'field' => 'name', ), array( 'type' => 'Select', 'label' => 'Age', 'field' => 'age', 'values' => array( array('young', 'Young'), array('old', 'Old') ) ), array( 'type' => 'Checkbox', 'label' => 'In love', 'preview' => true, 'field' => 'inLove' ), array( 'type' => 'RepositoryFile', 'label' => 'CV', 'preview' => true, 'field' => 'cv' ) ) ); return ipGridController($config); } }
Full Grid options list
Grid option | Description |
actions |
Array of actions buttons to be added at the top of the grid. Eg. 'actions' => array( 'data' => 'any data to be available for jQuery' since 4.5.0 you can add Select and custom Html too: 'actions' = array( array( 'class' => 'someClassToBeAddedToTheSelect', ), array ( 'type' => 'Html', 'html' => '<div>Your custom HTML</div>' ) |
actionsFilter |
Function to filter action buttons array. The difference to 'actions' setting is that this method allows not only to add new buttons, but also remove them or swap the order. Available since 4.5.0.
'actionsFilter' => function ($actions) { |
afterCreate | PHP callable. Eg. function($id, $postData){ ... } |
afterDelete | PHP callable. Eg. function($id){ ... } |
afterMove | PHP callable. Eg. function($id){ ... } |
afterUpdate | PHP callable. Eg. function($id, $postData){ ... } |
allowCreate | If set to false, does not allow creating new grid records. |
allowDelete | If set to false, does not allow to delete grid records. |
allowSearch | If set to false, removes grid search functionality. |
allowSort | If set to false, does not allow to sort records |
allowUpdate | If set to false, does not allow updating grid records. |
beforeCreate | PHP callable. Eg. function($postData){ ... } |
beforeDelete | PHP callable. Eg. function($id){ ... } |
beforeMove | PHP callable. Eg. function($id){ ... } |
beforeUpdate | PHP callable. Eg. function($id, $postData){ ... } |
breadcrumbField | Database field value that has to be used in breadcrumb. Meaningful only in nested grid. If ommited, GRID's title option is used. Available since 4.2.4 |
createFilter | PHP callable to filter data before inserting new record. (Available since 4.2.1. Callable e.g. function($data) { ... } |
createFormFilter | PHP callable to filter update form object. Callable e.g. function (\Ip\Form $form) { ... }. Available since 4.4.1. |
createPosition | Position for newly added records can be either top or bottom. By default, new records are displayed on the top of the list. |
deleteWarning | Message to be displayed when deleting grid's record. |
fields | Fields that have to be listed in admin. See bellow for more detailed description. |
filter | SQL where clause surrounded by brackets. Eg. " (`score` > 25) " |
gatewayData | associative array of GET data to be passed to the controller on each GRID operation. Useful if you want to alter GRID's config depending on GET params. |
layout | E.g. 'Plugin/xxx/view/customLayout.php'. See Ip\Internal\Grid\view\layout.php for example layout. |
pageSize | Number of items per single page. |
selectFields | SQL query string defining fields to be selected. If ommited, GRID uses '*' to select all fields in the table. Available since 4.0.17 |
sortField | Name of dedicated field used for record sorting. In SQL table, this field should have a DOUBLE data type. |
sortDirection | 'asc' by default. Set to 'desc' to invert the order. |
table | Grid table name in SQL database (without a prefix). This is a required parameter. |
title | Grid title displayed on the top of grid's page. |
updateFilter | PHP callable to filter data before updating the database. (Available since 4.0.17). Callable eg. function($id, $data) |
updateFormFilter | PHP callable to filter update form object. Callable e.g. function (\Ip\Form $form) { ... }. Available since 4.4.1. |
Each field specific options
By default, if the fields key is not set, the grid displays records from all SQL table columns as text strings. You can manually control fields that have to be available in management by providing array of fields. Each array item may have following options:
Grid field option | Description |
allowCreate | Set to false to disable field in create form. (since 4.0.17) |
allowOrder | Allow records to be ordered by this field (since 4.4.0) |
allowUpdate | Set to false to disable field in update form. (since 4.0.17) |
defaultValue | Default value that has to be assigned to the field when creating new record. |
field | Database column name. |
fileLimit | Available only in RepositoryFile field. Default value 1. Set null to upload an unlimited number of files. (since 4.0.17) |
hint | Shows a hint when user hovers the field with mouse. |
label | Field's label. |
multilingual | Set field to be multilingual (1) or not (0). Defaults to 0. |
layout |
Field layout. Available options:
(since 4.3.0) |
note | Shows a note bellow the field. |
preview |
Method to display field's data in record list. By default just puts the value from the database as it is. You can set any PHP callable or string to modify preview in a way you like. See the file Ip\Internal\Email\AdminController.php for sample usage. If you like to exclude field from listing in records list, set false. If you want your own function to generate the preview, set it in this way 'preview' => function($fieldValue, $dbRecord){ return 'xxx'; } |
type |
Field type. See bellow for available field types. The default field type is Text. You can introduce your own field types. In that case provide full calss name as a string. |
transformations |
An array of transformations to be applied to the user entered value before storing to the database. Eg. array('Trim', 'UpperCase'). List of available default transformations: LowerCase, Trim, UpperCase, UpperCaseFirst, NullIfEmpty. You can create your own transformations by implement \Ip\Internal\Grid\Model\Transformation interface. After doing so, use full class name including namespace in transformations array. |
values |
Available only in Select field. Usage example below: 'values' => array( |
validators | An array of validators. See data validation section bellow. |
Field types
- Checkbox
- Checkboxes
- Color
- Currency
- Grid (since 4.1.3)
- Info (since 4.3.0)
- Integer
- Radio (since 4.2.3)
- RepositoryFile
- RichText
- Select
- Text
- Textarea
- Url (since 4.2.6)
You can extend \Ip\Internal\Grid\Model\Field class and create your own type. Add full class name as a string to the 'type' option to use your own class.
<?php namespace Plugin\MyPlugin; class AdminController { public function index() { $config = array( 'table' => 'my_plugin', 'fields' => array( array( 'type' => 'Plugin\MyPlugin\CustomGridFieldClass', 'label' => 'xxx', 'field' => 'xxx' ), ) ) return ipGridController($config); } }
Data validation
Grid data can be automatically validated. See validators page for a list of default validators, provided with ImpressPages.
You can add any number of validators to a field. The sample bellow adds three validators: the first validator makes the field required, the second one verifies the field against regular expression, and the third validator verifies that the field's value does not belong to an array.
'validators' => array( 'Required', array('Regex', '/^([^\/\\\])+$/', 'You can\'t use slash in URL.'), array('NotInArray', $languageUrls, 'Already taken'), )
If needed, you can create your own custom validator.
Tabs (since 4.1.3)
Very large tables are not easy to edit in one long form. ImpressPages GRID supports tabs to slice huge records into portions.
Example GRID configuration with tabs
<?php namespace Plugin\MyPlugin; class AdminController { public function index() { $config = array( 'title' => 'Person list', 'table' => 'gridExample', 'fields' => array( array( 'label' => 'Tab1', 'type' => 'Tab' ), array( 'label' => 'First name', 'field' => 'FirstName', 'validators' => array('Required') ), array( 'label' => 'Last name', 'field' => 'LastName' ), array( 'type' => 'Select', 'label' => 'Sex', 'field' => 'Sex', 'values' => array( array('female', 'Female'), array('male', 'Male') ) ), array( 'label' => 'Tab2', 'type' => 'Tab' ), array( 'label' => 'Phone', 'field' => 'Phone', ) //... ) ); return ipGridController($config); } }
Nested GRID (subGRID) (since 2.1.3)
Nested grid allows to manage records in multiple tables. Eg. bellow shows how to create GRID configuration which gives the management of persons and unlimited photo records for each of them.
<?php namespace Plugin\MyPlugin; class AdminController { public function index() { $config = array( 'title' => 'Person list', 'table' => 'person', 'fields' => array( array( 'label' => 'First name', 'field' => 'FirstName' ), array( 'label' => 'Last name', 'field' => 'LastName' ), array( 'label' => 'Photos', 'type' => 'Grid', 'field' => 'personId', 'config' => array( 'title' => 'Photos', 'connectionField' => 'personId', 'table' => 'person_photo', 'fields' => array( array( 'label' => 'Title', 'field' => 'title' ), array( 'label' => 'Image', 'field' => 'image', 'type' => 'RepositoryFile' ) ) ) ) ) ); return ipGridController($config); } }
The nesting is achieved by adding a field of type "Grid". This type of field has it's own 'config' option where you put the same options as in root level grid config. There is just one additional setting - connectionField . This tells the system which field does the connection between the tables. Here is the database structure needed for example to work:
CREATE TABLE IF NOT EXISTS `ip_person` ( `id` int(11) NOT NULL AUTO_INCREMENT, `FirstName` varchar(255) DEFAULT NULL, `LastName` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `ip_person_photo` ( `id` int(11) NOT NULL AUTO_INCREMENT, `personId` int(11) NOT NULL, `title` varchar(255) DEFAULT NULL, `image` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Recursive nesting (since 4.1.3)
You can make your GRID recursive. In this way mimic something like directory tree. Example configuration of recursive node tree holding a title for each node.
<?php namespace Plugin\MyPlugin; class AdminController { public function index() { //GRID config for a single node $recursiveConfig = array( 'title' => 'Nodes', 'table' => 'node', 'connectionField' => 'parentId', 'fields' => array( array( 'label' => 'Title', 'field' => 'title' ), array( 'label' => 'Subnodes', 'type' => 'Grid', 'connectionField' => 'parentId' //config of a subgrid field will be added bellow with recursion to itself ) ) ); //make GRID config recursive $recursiveConfig['fields'][1]['config'] = &$recursiveConfig; //root node GRID config. The difference from above is just the filter '`parentId` = 0' and the title $rootConfig = array( 'title' => 'Tree', 'table' => 'node', 'filter' => '`parentId` = 0', 'fields' => array( array( 'label' => 'Title', 'field' => 'title' ), array( 'label' => 'Subnodes', 'type' => 'Grid', 'config' => $recursiveConfig ) ) ); return ipGridController($rootConfig); } }
Database table required for this example to work
CREATE TABLE IF NOT EXISTS `ip_node` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `parentId` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
JavaScript events
Grid triggers following JavaScript events
Event | Comment | Data |
init.ipGrid | Grid has been initialized | -- |
afterRecordDeleted.ipGrid | since 4.2.8 | id |
beforeRecordDeleted.ipGrid | since 4.2.8 | id |
createModalOpen.ipGrid | since 4.2.8 | $modal |
htmlChanged.ipGrid | user has taken some action that lead to refresh of the whole HTML | -- |
searchModalOpen.ipGrid | since 4.2.8 | $modal |
updateModalOpen.ipGrid | since 4.2.8 | $modl |
If you need to execute your own JavaScript on GRID initialization default jQuery on ready event won't work, because GRID loads content dynamically. You have to catch one of following events: htmlChanged.ipGrid or init.ipGrid to execute your own JS on GRID's content. These events appear almost at the same time. There is just GRID's JavaScript initialization in between.
$('.ipsGrid').on('init.ipGrid', function () { alert('Your code goes here'); });
Grid methods
GRID is written as a jQuery plugin and has just one refresh method at the moment. If you add your own JavaScript that removes / adds / modifies the data in the database using AJAX, you can use this method to refresh the GRID afterwards.
$('.ipsGrid').ipGrid('refresh');