tigrang / cakephp-datatable

JQuery DataTable plugin server-side processing component for CakePHP
47 stars 29 forks source link

Unable to call ajax for a stateSave/stateLoad callback #64

Closed fr0z3nfyr closed 9 years ago

fr0z3nfyr commented 9 years ago

Thanks for fixing the link in wiki.

TL;DR; Jump to Summary to just know the problem I implemented your fantastic plugin in my project and it works flawlessly for what has been promised. I had a server-side stateSave and stateLoad functionality using ajax in my original original code before the implementation of this plugin. After I wrote my CakePHP views using this plugin, I noticed that I didn't need to initialize dataTable() any more because it is done in the helper. However, I still tried to re-initialize DT in my view and add stateSave: true and include the stateSaveCallback etc in it, everything still works except that my ajax requests are not called. I checked in firebug to confirm this.

I checked-out my old code without plugin and tried it, there the callbacks work flawlessly. Any ideas?

By the way, below is a sample of original code that I had for stateSave: View:

    $(document).ready(function(){
        $('#test').dataTable( {
              "stateSave": true,
              "stateSaveCallback": function (settings, data) {
                e.preventDefault(); 
                // Send an Ajax request to the server with the state object
                $.ajax( {
                  "url": "users/save_state",
                  "data": data,
                  "dataType": "json",
                  "type": "POST",
                  "success": function () {console.log("ca");}
                } );
                e.preventDefault(); //added to make sure page is not re-loaded, should normally work fine even without this
              },
               "stateLoadCallback": function (settings) {
                    var o;
                    e.preventDefault();
                    $.ajax( {
                      "url": "users/get_state",
                      "async": false,
                      "dataType": "json",
                      "success": function (json) {
                        o = json;
                      }
                    } );
                    e.preventDefault(); 
                    return o;
                  }
            } );
    });

AppController functions: (I'm sure there's nothing wrong here but still including for your reference. Probably you can generalize and incorporate in plugin :P)

    public function save_state() {
        $this->autoRender = false;
        $this->loadModel('GridState');

        $table = $this->modelClass; // returns name of current model (or model class)
        $user_id = $this->Session->read('Auth.User.id');
        // get existing record (so we can get value of `id` field)
        $existing = $this->GridState->find('first',array('conditions'=>array('user_id'=>$user_id, 'table'=>$table)));

        // if record exists, map data to correct record `id`
        if ($existing) {
            $this->request->data['GridState']['id'] = $existing['GridState']['id'];
        }

        // save data to table (`id` above determines if INSERT or UPDATE)
        $this->request->data['GridState']['json_data'] = json_encode($_POST);
        $this->request->data['GridState']['user_id'] = $user_id;
        $this->request->data['GridState']['table'] = $table;
        $this->GridState->save($this->request->data);
    }

    public function get_state() {
        $this->autoRender = false;
        $this->loadModel('GridState');

        $table = $this->modelClass;
        $user_id = $this->Session->read('Auth.User.id');

        $this->response->type('json');

        $data = $this->GridState->find('first',array('conditions'=>array('GridState.user_id'=>$user_id, 'table'=>$table)));
        $json = $data['GridState']['json_data'];
        $this->response->body($json);
    }

Summary: I need help with using server side stateSave and stateLoad callbacks. Unable to get the ajax to call call my functions if I use the plugin. Ajax works without the plugin. I was also wondering how I can get the column filters to work (input/select filters on my column headers don't even appear)? I use YADCF plugin, but I can also go without it. Thanks.

fr0z3nfyr commented 9 years ago

OK. my bad. I think my issue report is similar to #42 I tried setting scriptBlock to false like this in helpers, but then I get a blank table:

        'DataTable.DataTable' => array(
           'scriptBlock' => false,
        )

No errors in firebug. Disabled YADCF and still no data.

tigrang commented 9 years ago

At this point you'll have to output the init script yourself. Use the original init code you had above $('#test').dataTable( {... but extend the dataTableSettings js var which has the column configs.

In your console look at the value of dataTableSettings and you'll see what I mean. Extend it with your saveState config and then call the jquery plugin yourself.

fr0z3nfyr commented 9 years ago

Hi, sorry to bug you... where in firebug console exactly? I couldn't find anything called dataTableSettings. I was also looking at DataTableComponent.php in Component folder before I read your reply to see if I can make some additions there but realised that YADCF settings will not be same on all views, though I can generalize stateSaveCallback.and stateLoadCallback. Now after reading your reply, I think you suggest a much better approach.

Can you help me with an example of what you exactly meant above?

tigrang commented 9 years ago

In console just type 'dataTableSettings' and press enter.

Check https://github.com/tigrang/cakephp-datatable/issues/42#issuecomment-36807840 for an example.

fr0z3nfyr commented 9 years ago

Ohh ok, understood. Let me try this in my multiple situations. I will test in each case and post back. Thanks for an amazingly excellent support!!

fr0z3nfyr commented 9 years ago

Excellent..! this solution worked till the point of allowing me to add additional settings like you suggested (disabling scriptBlock and adding my custom settings to dataTableSettings). Only change that I made in solution from #42 was to change var model = table.attr('data-model'); to var model = table.attr('data-config');. without it, I would get a TypeError: settings is undefined.

Now, I'm stuck with implementation of YADCF. Can you help? No matter what I tried, I continuously kept getting this error pointing to yadcf library:

TypeError: oTable.settings is not a function
var instance = oTable.settings()[0].oInstance,

I don't think this is a bug in YADCF, but it is unable to get the columns. I even tried with .DataTable() instead .dataTable() as I'm using DT 1.10.6

EDIT: A discussion with the author of other plugin is here: http://stackoverflow.com/questions/31045543/. Solved the issue of filter inputs not appearing but the filters don't work. :( Can you please look at the link too?

fr0z3nfyr commented 9 years ago

UPDATE: Solved the issue. Just as a side note, the column filters are messed up if in congig, i set a field to null (useField => false). without it everything works charmingly.

tigrang commented 9 years ago

null means it's not a database column. sortable and searchable get set to false. false means it is a database column, but you don't want any searching or sorting allowed on the column.

I haven't look at YADCF so I'm not sure why it would be an issue, but Im glad you got it working.