Topics

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(
    array(
        'label' => 'Button text',
        'class' => 'someClassToBeAddedToTheButton',

        'data' => 'any data to be available for jQuery'
    )
)

since 4.5.0 you can add Select and custom Html too:

'actions' = array(

    array(
        'type' => 'Select',

        'class' => 'someClassToBeAddedToTheSelect',
        'label' => 'Someting meaninful',
        'values' => array(array('label' => 'A', 'value' => '1'), ...),
        'itemClass' => 'classNameToAddToEachSelectItem'

    ),

    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) {
    unset($actions['add']);
    return $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 the 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 the field in update form. (since 4.0.17)
attributes assocative array of keys/values to be added to the inputs HTML tag
defaultValue Default value that has to be assigned to the field when creating a 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 a user hovers the field with a mouse.
ignoreDb Don't write data of this field to the database. Basically, that means the field won't work unless you will handle writing the value to the database on your own by catching afterInsert, afterUpdate, etc. settings. (since 4.6.3)
label Field's label.
multilingual Set field to be multilingual (1) or not (0). Defaults to 0.
layout

Field layout. Available options:

  • \Ip\Form\Field::LAYOUT_DEFAULT
  • \Ip\Form\Field::LAYOUT_BLANK
  • \Ip\Form\Field::LAYOUT_NO_LABEL

(since 4.3.0)

note Shows a note below 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 the 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 the full class name as a string.

transformations

An array of transformations to be applied to the user entered the 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 the full class name including namespace in transformations array.

values

Available only in Select field. Usage example below:

'values' => array(
    array('young', 'Young'),
    array('old', 'Old')
)

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');

See also

comments powered by Disqus