setFormatter not being called on empty Array

setFormatter not being called on empty Array

johnhpejohnhpe Posts: 12Questions: 3Answers: 0
edited January 2018 in Editor

I am using EDITOR and one of the fields (named fields) is a multiple select dropdown. It all works fine except when the field is cleared of all selections. In such a case I can confirm that the JSON data returned and POSTED back to the ajax file is a zero length array which is correct. However the setFormatter is not triggered at all in such as case. I have confirmed this by putting some debug code into the setFormatter function to write to a file. It only writes to the file when there is data in $val. i.e. not an empty array. The result is that as setFormatter is not being called it does not update the field in the database.

Here is the JS

editor = new $.fn.dataTable.Editor( {
            ajax: "ajax/manQueries.php",
            table: "#example",
            fields: [ 
                { label: "ID:",
                    name: "id",
                    type: 'hidden'
                }, {
                    label: "Title:",
                    name: "title"
                }, {
                    label: "Description:",
                    name: "description",
                    className: "smallArea",
                    type: "textarea"
                }, {
                    label: "Query:",
                    name: "query",
                    type: "textarea",
                },{
                    label: "Notes:",
                    name: "notes",
                    type: "textarea"
                },{
                    label: "Footer:",
                    name: "totals",
                    type: "text"
                },{
                    label: "Column Format:",
                    name: "totals_format",
                    type: "text"
                },{
                    label: "Prompted Fields",
                    className: "widthAuto",
                    name: "fields",
                    type: "select",
                    multiple: true,
                    seperator: ',',
                    options: [
                        { label: 'Year', value: 'year' },
                        { label: 'Month', value: 'month' }
                    ]
                },{
                    label: "Sort by Query:",
                    name: "order",
                    type: "checkbox",
                    separator: "|",
                    options: [{label: '', value: 1}]
                },{
                    label: "No. of Rows to display:",
                    name: "pages",
                    type: "select",
                    options: [{label: '10', value: 10},{label: '50', value: 50},{label: '100', value: 100},{label: '500', value: 500},{label: '1000', value: 1000},{label: '10000', value: 10000}]
                } 
            ],
        } );

And here is the ajax file

```
<?php
session_start();

include( "../JS/Editor-1.7.0/php/DataTables.php" );

use
DataTables\Editor,
DataTables\Editor\Field,
DataTables\Editor\Format,
DataTables\Editor\Mjoin,
DataTables\Editor\Options,
DataTables\Editor\Upload,
DataTables\Editor\Validate;

$editor = Editor::inst( $db, 'bookingdb'.$_SESSION['id'].'.customQueries')
->field(
Field::inst( 'id' ),
Field::inst( 'title' )->validator(Validate::required()),
Field::inst( 'description' )->validator(Validate::required()),
Field::inst( 'query' )->setFormatter( function ($val, $data) { return htmlspecialchars_decode(preg_replace("/\s+/", " ", $val));})->validator(Validate::required()),
Field::inst( 'notes' ),
Field::inst( 'order' )->setFormatter( function ( $val, $data) { return !$val ? 0 : 1; } ),
Field::inst( 'totals' )->setFormatter( function ($val, $data) { return preg_replace('/\s+/','',$val); }),
Field::inst( 'totals_format' ),
Field::inst( 'fields' )->getFormatter( function ($val, $data) { return unserialize($val); })->setFormatter(function ($val, $data){
$f = fopen('debug.txt','a');
fwrite($f,date("H:i:s\n\n"));
fwrite($f,"Value is:\n " . print_r($val,1));
fclose($f);
return serialize($val);
}),
Field::inst( 'pages' )
)
->process($_POST)
->json();

<?php > ``` ?>

I have spent a lot of time on this and think that this is a bug in the PHP file as it is not calling setFormatter when $val is empty. Or is this by design?

Just to confirm here is the JSON data from console.log

Replies

  • johnhpejohnhpe Posts: 12Questions: 3Answers: 0

    After nearly a day of troubleshooting this I am convinced it is a problem in the way the PHP library handles and empty array.

    As a workaround I have added the "preSubmit" method to check if the array is empty, if it is then I rewrite it with ['Bert']. This then causes the setFormatter to be called and I check if the $val[0] == 'Bert' then replace with NULL.

    This is a big cludge but the only way I can get this to work.....

    Snippet of preSubmit

    editor.on('preSubmit',function(e,data,action) { 
                $.each(data.data, function(index, value) { 
                    if (value.fields.length == 0) { 
                        data.data[index].fields = ['Bert'];
                    }
                });
            });
    

    And updated ajax file. I also changed the [un]serialize function to implode/explode
    ```
    <?php
    session_start();

    include( "../JS/Editor-1.7.0/php/DataTables.php" );

    use
    DataTables\Editor,
    DataTables\Editor\Field,
    DataTables\Editor\Format,
    DataTables\Editor\Mjoin,
    DataTables\Editor\Options,
    DataTables\Editor\Upload,
    DataTables\Editor\Validate;

    $editor = Editor::inst( $db, 'bookingdb'.$_SESSION['id'].'.customQueries')
    ->field(
    Field::inst( 'id' ),
    Field::inst( 'title' )->validator(Validate::required()),
    Field::inst( 'description' )->validator(Validate::required()),
    Field::inst( 'query' )->setFormatter( function ($val, $data) { return htmlspecialchars_decode(preg_replace("/\s+/", " ", $val));})->validator(Validate::required()),
    Field::inst( 'notes' ),
    Field::inst( 'order' )->setFormatter( function ( $val, $data) { return !$val ? 0 : 1; } ),
    Field::inst( 'totals' )->setFormatter( function ($val, $data) { return preg_replace('/\s+/','',$val); }),
    Field::inst( 'totals_format' ),
    Field::inst( 'fields' )
    ->getFormatter( function ($val, $data) { return explode(',',$val); })
    ->setFormatter(function ($val, $data){ return $val[0] == 'Bert' ? null : implode(',', $val);
    }),
    Field::inst( 'pages' )
    )
    ->process($_POST)
    ->json();

    <?php > ``` ?>
This discussion has been closed.