DynTable

The DynTable contains a previously defined collection of numeric or textual typed fields referenced by names. You can get/set this elements as a simple object attribute or even do arithmetic operation on all of them or store/load the whole object to/from database by simple api calls.
The DynTable class elements can be show or edit as a simple two dimensional html table with the specified column and row names. The editing is achieved through ajax functions.

dyntable2.png

Because the DynTable class is inheritable in your codes, you can extend the functions of the base class to meet your special needs. The class contains many redefineable methods to easy extend base functions.

Let's see a simple example of DynTable

$definition = [
     'rows' => [0 => 'Apple',1 => 'Plum',2 => 'Pear',3 => 'Nut',],
     'cols' => [0 => 'Good (Kg)',1 => 'Decent (kg)',2 => 'Waste (kg)'],
     'default_type' => 'num',
     'datacells' => [
         'applegood'   => ['row' => 0,'col' => 0],
         'appledecent' => ['row' => 0,'col' => 1],
         'applewaste'  => ['row' => 0,'col' => 2],
         'plumgood'    => ['row' => 1,'col' => 0],
         'plumdecent'  => ['row' => 1,'col' => 1],
         'plumwaste'   => ['row' => 1,'col' => 2],
         'peargood'    => ['row' => 2,'col' => 0],
         'peardecent'  => ['row' => 2,'col' => 1],
         'pearwaste'   => ['row' => 2,'col' => 2],
         'nutgood'     => ['row' => 3,'col' => 0],
         'nutwaste'    => ['row' => 3,'col' => 2],
     ],
     'table_border' => '1',
];

$d = new DynTable($definition);

$d->zeroData();

$d->nutgood = 12;
$d->applegood = 200;
$d->applewaste = 23;
$d->plumgood = 68;
$d->plumdecent = 12;

print $d->getHtml();

The code above generates the following table in the browser

dyntable1.png

Methods of DynTable class

Constructor:

Methods:

The following methods does nothing, they can be re defined in subclasses to achieve special needs.

Attributes of DynTable:

Every defined field is accessible for read and write as object attribute. Except that ones there are more attributes to read:

Data definition structure

The data definition array is php associative array structure to driven DynTable object features, specify fields, look and feel, and other features of the generated tables or database values. This definition structure described here is passed to the constructor of DynTable. (Above)

The structure : Top level attributes

List of top level attributes/features:





Data definition structure repository

You can add the data definition array of DynTable to the same repository as SpeedForm definitions. Use the same HOOK_datadef_repository hook to add a data definition structure to the repository, see documentation here.

You can use the same datadef_from_repository('repository_name') function to get the definition.

Note: The definition which are stored in the repository will be processed by sql schema requisites check tool unless you set the sql_schema_bypass toplevel attribute to true !

A complex example

Let's see a complex example of using DynTable. Here we will define a DynTable and build an edit interface which immediately store the edited table to the database.

First of all, let's put the definition of our DynTable to the data definition structure repository:

function hook_mymodule_datadef_repository()
{
    return [
        'fruitsdef' => 'generate_fruits_def',
    ];
}

function generate_fruits_def()
{
    return [
        'sqltable' => 'fruit_harvest',
        'idfield' => 'year',

        'table_border' => '1',

        'popupedit_ajaxurl' => 'ajaxfruitedit',
        'popupedit_ajaxsubtype' => 'fruits',
        'popupedit_title' => 'Set the selected item',
        'popupedit_btntext' => 'Modify',

        'rows' => [
            0 => 'Apple',
            1 => 'Plum',
            2 => 'Pear',
            3 => 'Nut',
        ],
        'cols' => [
            0 => 'Good (Kg)',
            1 => 'Decent (kg)',
            2 => 'Waste (kg)'
        ],
        'default_type' => 'num',
        'datacells' => [
            'applegood'   => ['row' => 0, 'col' => 0],
            'appledecent' => ['row' => 0, 'col' => 1],
            'applewaste'  => ['row' => 0, 'col' => 2],
            'plumgood'    => ['row' => 1, 'col' => 0],
            'plumdecent'  => ['row' => 1, 'col' => 1],
            'plumwaste'   => ['row' => 1, 'col' => 2],
            'peargood'    => ['row' => 2, 'col' => 0],
            'peardecent'  => ['row' => 2, 'col' => 1],
            'pearwaste'   => ['row' => 2, 'col' => 2],
            'nutgood'     => ['row' => 3, 'col' => 0],
            'nutwaste'    => ['row' => 3, 'col' => 2],
        ],
    ];
}

Now we have our definition in the repository, let's create a page where we put an edit page for one instance of the table. The Id is received in url parameter.

function hook_mymodule_defineroute()
{
    $r = [];
    $r[] = [
        'path' => 'editfruittable/{id}',
        'callback' => 'pc_editfruittable',
    ];

    $r[] = [
        "path" => "ajaxfruitedit",
        "callback" => 'aj_fruitedit',
        "type" => "ajax",
    ];
    return $r;
}

function pc_editfruittable()
{
    par_def('id','number0');

    ob_start();
    print "My DynTable:<br/>";

    $d = new DynTable(datadef_from_repository('fruitsdef'));
    $d->readFromDatabase(par('id'));
    print $d->getHtml();

    return ob_get_clean();
}

Here comes the ajax handler which save the edited value to the database and update the table in the browser.

function aj_fruitedit()
{
    par_def('subtype','text1ns');
    par_def('value','textbase64');
    par_def('modname','text1ns');
    par_def('id','text1ns');

    $subtype = par('subtype');
    $mname = par('modname');
    $mvalue = base64_decode(par('value'));
    $id = par('id');

    if($subtype == 'fruits')
    {
        $dmod = new DynTable(datadef_from_repository('fruitsdef'));
        if(!$dmod->readFromDatabase($id))
        {
            $dmod->setDataFromAjax($mname, floatval($mvalue), 'fromajax');
            $dmod->saveToDatabase();
            $dmod->ajax_add_refreshHtmlTable(false);
            return;
        }
        load_loc('error','Error, ...');
    }
}