ypnos-web / cakephp-datatables

CakePHP3 Plugin for DataTables plug-in for jQuery
MIT License
27 stars 24 forks source link

Cannot convert value of type `string` to integer #75

Open nikitamaximov opened 5 years ago

nikitamaximov commented 5 years ago

This is a weird one, clearly I'm doing something wrong, just wondering if you can point me to the right direction. When i let my INT columns be searchable, the search field doesn't accept string values (Err: Cannot convert value of type string to integer), however when I specify my INT columns with 'searchable' => false and I mean all of them, the string columns become searchable, but not the int columns obviously.

My Controller

            $columns = [
            [
                'field' => 'BigDatas.id',   //INT Column
                'data' => 'id',
            ],
            [
                'title' => __('Amount'),   //String Column
                'field' => 'BigDatas.amount',
                'data' => 'amount',
            ],
            [
                'title' => __('Unit'),    //INT Column
                'field' => 'BigDatas.unit',
                'data' => 'unit',
            ],
            [
                'title' => __('Stir'),    //String Column
                'field' => 'BigDatas.stir', 
                'data' => 'stir',
            ]
        ];

        $data = $this->DataTables->find('BigDatas', 'all', [
            'order' => ['id' => 'asc']
        ], $columns);

        $this->set('columns', $columns);
        $this->set('data', $data);
        $this->set('_serialize', array_merge($this->viewVars['_serialize'], ['data']));

My Template

$options = [
    'ajax' => [
        'url' => $this->Url->build() // current controller, action, params
    ],
    'data' => $data,
    'deferLoading' => $data->count(), 
    'columns' => $columns,
    'order' => [0, 'asc'], 
];
echo $this->DataTables->table('bigdatas-table', $options, ['class' => 'table table-striped']);
ypnos-web commented 5 years ago

That's interesting. Where does the error occur in the code? A backtrace would be even better.

nikitamaximov commented 5 years ago

I'm fairly new to js, not quite sure how to trace. But i have a feeling it's a cakephp issue (at the bottom), since something calls function to check if it's a valid integer type

Actual Exception

{
    "message": "Cannot convert value of type `string` to integer",
    "url": "\/BigDatas?draw=2\u0026amp;columns%5B0%5D%5Bdata%5D=id\u0026amp;columns%5B0%5D%5Bname%5D=\u0026amp;columns%5B0%5D%5Bsearchable%5D=true\u0026amp;columns%5B0%5D%5Borderable%5D=true\u0026amp;columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=\u0026amp;columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false\u0026amp;columns%5B1%5D%5Bdata%5D=amount\u0026amp;columns%5B1%5D%5Bname%5D=\u0026amp;columns%5B1%5D%5Bsearchable%5D=true\u0026amp;columns%5B1%5D%5Borderable%5D=true\u0026amp;columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=\u0026amp;columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false\u0026amp;columns%5B2%5D%5Bdata%5D=unit\u0026amp;columns%5B2%5D%5Bname%5D=\u0026amp;columns%5B2%5D%5Bsearchable%5D=true\u0026amp;columns%5B2%5D%5Borderable%5D=true\u0026amp;columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=\u0026amp;columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false\u0026amp;columns%5B3%5D%5Bdata%5D=stir\u0026amp;columns%5B3%5D%5Bname%5D=\u0026amp;columns%5B3%5D%5Bsearchable%5D=true\u0026amp;columns%5B3%5D%5Borderable%5D=true\u0026amp;columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=\u0026amp;columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false\u0026amp;order%5B0%5D%5Bcolumn%5D=0\u0026amp;order%5B0%5D%5Bdir%5D=asc\u0026amp;start=0\u0026amp;length=10\u0026amp;search%5Bvalue%5D=z\u0026amp;search%5Bregex%5D=false\u0026amp;_=1560767739335",
    "code": 500,
    "file": "\/var\/www\/myapp2\/vendor\/cakephp\/cakephp\/src\/Database\/Type\/IntegerType.php",
    "line": 64
}

First Exception DOMException: Failed to execute 'querySelectorAll' on 'Document': '.panel-summary:contains(xhr)' is not a valid selector.

Stack Trace

  1. db (jquery.js:formatted:344)
  2. find (jquery.js:formatted:1169)
  3. n.fn.init (jquery.js:formatted:1191)
  4. n (jquery.js:formatted:22)
  5. onRequest (toolbar-app.js:281)
  6. onMessage (toolbar-app.js:275)
  7. (anonymous) (toolbar-app.js:314)
  8. postMessage (async)
  9. (anonymous) (toolbar.js?1560353218:71)
  10. XMLHttpRequest.send (async)
  11. (anonymous) (VM499:1)
  12. window.XMLHttpRequest.send (toolbar.js?1560353218:91)
  13. send (jquery-3.3.1.js:9600)
  14. ajax (jquery-3.3.1.js:9206)
  15. _fnBuildAjax (jquery.dataTables.js:3948)
  16. _fnAjaxUpdate (jquery.dataTables.js:3968)
  17. _fnDraw (jquery.dataTables.js:3431)
  18. searchFn (jquery.dataTables.js:4210)
  19. (anonymous) (jquery.dataTables.js:1629)
  20. dispatch (jquery-3.3.1.js:5183)
  21. elemData.handle (jquery-3.3.1.js:4991)

Searching for 'z' when all 4 columns are searchable

/src/Database/ValueBinder.php (line 148)
[
    ':c0' => [
        'value' => 'z',
        'type' => 'integer',
        'placeholder' => 'c0'
    ],
    ':c1' => [
        'value' => 'z%',
        'type' => 'string',
        'placeholder' => 'c1'
    ],
    ':c2' => [
        'value' => 'z',
        'type' => 'integer',
        'placeholder' => 'c2'
    ],
    ':c3' => [
        'value' => 'z%',
        'type' => 'string',
        'placeholder' => 'c3'
    ]
]

Searching for 'z' when only 2 (string) columns are searchable

/src/Database/ValueBinder.php (line 148)
[
    ':c0' => [
        'value' => 'z%',
        'type' => 'string',
        'placeholder' => 'c0'
    ],
    ':c1' => [
        'value' => 'z%',
        'type' => 'string',
        'placeholder' => 'c1'
    ]
]

The binded value is being casted as the type of the db column it's searching through, just not sure why the datatables search function goes through ValueBinder

leandrop20 commented 4 years ago

Uou!

In Component...

private function _addCondition($column, $value, $type = 'and') { ... if (strpos(strtolower($comparison), 'like') !== false) { ... } else if (!($comparison === '=' && is_numeric($value))) {//I ADDED THIS AND WORKED! return; }

frent commented 4 years ago

Uou!

In Component...

private function _addCondition($column, $value, $type = 'and') { ... if (strpos(strtolower($comparison), 'like') !== false) { ... } else if (!($comparison === '=' && is_numeric($value))) {//I ADDED THIS AND WORKED! return; }

I think the comparison === might be overkill at this moment. You already know that it's not LIKE. So a check if the value is not numeric only the is_numeric would be enough.