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();
?>

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();
    ?>
    
This discussion has been closed.