stateLoadParams.dt not getting called after first load.

stateLoadParams.dt not getting called after first load.

tfntfn Posts: 7Questions: 0Answers: 0
                            $table.one( 'stateLoadParams.dt', function (e, settings, columnDataFromDt) {
                                if(columnDataFromDt['columns'][columnDefKey]){
                                    columnDataFromDt['columns'][columnDefKey]['search']['search'] = columnDetails['column_filter_options']['attributes']['value'];
                                }
                            });

Hi, I have code like this, and when I do $dt.state.clear(); and window.location.reload()
The stateLoadParams.dt event never gets fired, until I run the code a 2nd time.

Is there a bug with this, or how am I supposed to deal with it, all I found was this:
https://datatables.net/forums/discussion/51369/stateloadparams-not-fired-in-first-visit
which seems to describe the problem, but I'm not really seeing a solution.
Do I need to initiailze the datatable after the page reloads?

Thanks

Replies

  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,770

    When you use state.clear() the saved state is empty, actually {}. When the Datatable is initialized it fetches the saved state. If empty the stateLoadParams event is not fired since there is nothing loaded. Here is a quick example to demonstrate:
    https://live.datatables.net/koxokale/1/edit

    Use these steps:

    1. Open the browser's console
    2. Click "Run with JS" and you will see output similar to this:
    stateLoadCallback {time: 1683577699132, start: 0, length: 10, order: Array(1), search: {…}, …}
    stateLoadParams event {time: 1683577699132, start: 0, length: 10, order: Array(1), search: {…}, …}
    stateSaveCallback {time: 1683577703369, start: 0, length: 10, order: Array(1), search: {…}, …}
    
    1. Clear the console output
    2. Click the "Clear state' button and you will see an empty set of data is saved:
    stateSaveCallback {}
    
    1. Clear the console output
    2. Click "Run with JS" and you will see output similar to this:
    stateLoadCallback {}
    stateSaveCallback {time: 1683577895444, start: 0, length: 10, order: Array(1), search: {…}, …}
    

    There is no state loaded so the stateLoadParams event doesn't fire. I suspect this is expected behavior.

    What problem are you trying to solve when there is no state loaded?

    Kevin

  • tfntfn Posts: 7Questions: 0Answers: 0

    I have a page with a datatable and on the page there is a "Reset" button, which calls $dt.state.clear(); and window.location.reload();

    I have a button called "Apply Setting" which will do an ajax call and load a new datatable.
    Under normal circumstances, when clicking "Apply Setting", it will work, calling both the

    $table.one( 'stateLoadParams.dt', function (e, settings, columnDataFromDt) {
        if(columnDataFromDt['columns'][columnDefKey]){
            columnDataFromDt['columns'][columnDefKey]['search']['search'] = columnDetails['column_filter_options']['attributes']['value'];
        }
    });
    

    and then the inside columnDataFromDt['columns'][columnDefKey]['search']['search'] = columnDetails['column_filter_options']['attributes']['value']; will get called, thus populating the filter.

    However, when I use the debugger if I click the "Reset" button, the state clears and the page reloads, the debugger only gets to the $table.one('stateLoadParams.dt' line and the anonymous function never gets fired.

    Am I doing something wrong? Do you understand what I am getting at?

  • tfntfn Posts: 7Questions: 0Answers: 0

    Is there a command I can run after the page reloads to ensure that the next time a datatable gets loaded that it will call 'stateLoadParams.dt'

  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,770

    However, when I use the debugger if I click the "Reset" button, the state clears and the page reloads, the debugger only gets to the $table.one('stateLoadParams.dt' line and the anonymous function never gets fired.

    Yes, because there is no state to load once its cleared. This is from the stateLoadParams docs:

    the event is fired when the table is loading state from the stored data

    Does this make sense?

    Do you understand what I am getting at?

    Sounds like you want to repopulate the column search values when clicking the "Apply Setting" button and that you want this to happen even if the state has been cleared. Is this correct?

    Kevin

  • tfntfn Posts: 7Questions: 0Answers: 0

    Yes Kevin,
    that is correct, I am trying to Load a bunch of filters (search) when i click Apply Setting.
    Which event would be most suitable? https://datatables.net/reference/event/
    Thank you for taking the time to help me!

  • tfntfn Posts: 7Questions: 0Answers: 0

    I was thinking about using the preDraw but it only takes (e, settings), whereas stateLoadParams takes function( e, settings, json ) and the json can be manipulated.
    How would you do it?

  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,770

    To rephrase my understanding you want to clear the Datatable state but retain the column search values so on reload you still have access to these. If this is the case one option might be to use stateSaveParams to clear all but the search parameters you want to save. Use a global variable as a flag to determine whether to clear the state parameters or not. For example:

    Global flag:

    var clearStates = false;
    

    stateSaveParams:

      "stateSaveParams": function (settings, data) {
        if (clearStates) {
            // Code to clear the desired states
        }
      }
    

    See the stateSaveCallback for details of the stateSave object.

    Reset event handler:

    clearStates = true;
    $dt.state.save();  // Force stateSaveParams to run to clear the states
    clearStates = false;
    window.location.reload();
    

    Kevin

  • tfntfn Posts: 7Questions: 0Answers: 0

    I don't think that will work, how do I "undo" the dt.state.save() ?

  • tfntfn Posts: 7Questions: 0Answers: 0

    My code is here, does this help at all? This is happening via ajax:

        var _handleDataTable = function (data) {
            var formExisted = false;
            if(data['form_id']){
                var $form = $('#'+data['form_id']);
                formExisted = !!($form.length);
            } else {
                var $form = $('<form></form>');
            }
            var $table = $('<table class="display table" cellspacing="0" width="100%"></table>');
            if(data['dom_location'] && data['form_id']) {
                $('#'+data['dom_location']).append($table);
            } else {
                $form.append($table);
            }
            $form.attr('id', 'frm-' + data['id_suffix']);
            $table.attr('id', 'tbl-' + data['id_suffix']);
            triggerEvent('portalapp_before_build_datatable', {'data': data, 'form': $form, 'table': $table});
            if (data['form'] && data['form']['attributes']) {
                $.each(data['form']['attributes'], function (attrKey, attrVal) {
                    addAttribute($form, attrKey, attrVal);
                });
            }
            if (data['table'] && data['table']['attributes']) {
                $.each(data['table']['attributes'], function (attrKey, attrVal) {
                    addAttribute($table, attrKey, attrVal);
                });
            }
            var columnsWithPeriod = {};
            if (data['table'] && data['table']['columns']) {
                var $tableHeadRow = $('<tr></tr>');
                var $tableHeadSearchRow = $('<tr></tr>');
                $.each(data['table']['columns'], function (columnKey, columnDetails) {
                    var columnDefKey = data['column_properties'][columnKey]['column_def_key'];
                    if(columnKey.match(/\./g)){
                        columnsWithPeriod[columnKey] = columnDefKey;
                    }
                    var $column = $('<th>' + columnDetails['label'] + '</th>');
                    var value = '', defaultValue = '';
                    if (columnDetails['attributes']) {
                        value = columnDetails['attributes']['value'];
                        $.each(columnDetails['attributes'], function (colAttrKey, colAtrrVal) {
                            addAttribute($column, colAttrKey, colAtrrVal);
                        });
                    }
                    if(columnDetails['column_filter_options']){
                        defaultValue = columnDetails['column_filter_options']['default_value'];
                    }
                    $tableHeadRow.append($column);
                    if(data['clear_search_flag']) {
                        $table.one( 'stateLoadParams.dt', function (e, settings, columnDataFromDt) {
                            if(columnDataFromDt['columns'][columnDefKey]){
                                if(columnDataFromDt['columns'][columnDefKey]){}
                                columnDataFromDt['columns'][columnDefKey]['search']['search'] = defaultValue || value || '';
                            }
                        });
                    }
    
                    if (columnDetails['column_filter_options']) {
                        var dynamicData = null;
                        var $searchInputTh = $('<th></th>');
                        if(!columnDetails['column_filter_options']['id'] && (columnDetails['column_filter_options']['attributes'] && !columnDetails['column_filter_options']['attributes']['id'])){
                            columnDetails['column_filter_options']['id'] = data['id_suffix']+'-search-'+columnKey;
                        }
                        if(columnDetails['column_filter_options']['attributes']) {
                            //Is there a dynamic value?
                            if (helpers.isValueNotNullOrEmpty(columnDetails['column_filter_options']['attributes']['dynamic'])) {
                                //Yes, now let's calculate an actual value (based on the date picker presetRanges)
                                var val = null;
                                var dtopts = PortalApp.helpers.DatePickerRangeOpts;
                                for(var k in dtopts.presetRanges){
                                    var r = dtopts.presetRanges[k];
                                    if (r && r.text && r.text === columnDetails['column_filter_options']['attributes']['dynamic']){
                                        dynamicData = r.text;
                                        var dateObj = {};
                                        dateObj.start = r.dateStart();
                                        dateObj.end = r.dateEnd();
                                        dateObj.start = dateObj.start.format('YYYY-MM-DD') + ' 00:00:00';
                                        dateObj.end = dateObj.end.format('YYYY-MM-DD') + ' 23:59:59';
                                        val = JSON.stringify(dateObj);
                                        break;
                                    }
                                }
                                //we no longer need the attribute
                                delete columnDetails.column_filter_options.attributes.dynamic;
    
                                if (val) {
                                    columnDetails.column_filter_options.attributes.value = val;
                                    $table.one('stateLoadParams.dt', function (e, settings, columnDataFromDt) {
                                        if (columnDataFromDt['columns'][columnDefKey]) {
                                            columnDataFromDt['columns'][columnDefKey]['search']['search'] = val;
                                        }
                                    });
                                }else{
                                    //No value was found for the given dynamicData given. Do nothing.
                                }
                            }else if(helpers.isValueNotNullOrEmpty(columnDetails['column_filter_options']['attributes']['value'])){
                                $table.one( 'stateLoadParams.dt', function (e, settings, columnDataFromDt) {
                                    if(columnDataFromDt['columns'][columnDefKey]){
                                        columnDataFromDt['columns'][columnDefKey]['search']['search'] = columnDetails['column_filter_options']['attributes']['value'];
                                    }
                                });
                            } else if(helpers.isValueNotNullOrEmpty(columnDetails['column_filter_options']['default_value'])){
                                $table.one( 'stateLoadParams.dt', function (e, settings, columnDataFromDt) {
                                    if(columnDataFromDt['columns'][columnDefKey]){
                                        columnDataFromDt['columns'][columnDefKey]['search']['search'] =  columnDetails['column_filter_options']['default_value'];
                                    }
                                });
                            }
                        }
    
                        var $searchElement = PortalAppForm.createElement(columnDetails['column_filter_options']);
    
                        $searchInputTh.append($searchElement);
                        $tableHeadSearchRow.append($searchInputTh);
                        $(document).one('portalapp_after_build_datatable', function (e, d) {
                            PortalApp.helpers.app.tempVars['last_datatable'] = d['datatable'];
                            _handleDataTableSearch($searchElement, d['datatable'], data, columnDetails, columnKey, columnDefKey);
                            applyDateRangePicker('.datarange');
                            if (dynamicData){
                                //make sure the data-dynamic attribute is set just in case the user saves the layout
                                $searchElement.attr('data-dynamic', dynamicData);
                                //show in hover title
                                setTimeout(function(){
                                    PortalApp.helpers.DynamicSetNearElement($searchElement[0], dynamicData);
                                }, 1000);
                            }
                        });
                    } else {
                        $tableHeadSearchRow.append('<th></th>');
                    }
                });
                var $tableHead = $('<thead></thead>').append($tableHeadRow).append($tableHeadSearchRow);
                $table.append($tableHead);
            }
    ...
    
    
  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,770

    Here is an example of what I was describing:
    https://live.datatables.net/koxokale/3/edit

    If the flag is set it sets the state save object to the Datatables default values in stateSaveParams, but leaves the columns alone. This allows stateLoadParams to be called when the date is cleared. But state.clear() is not used so there is a saved state.

    Does this help?

    There is a lot to study in your code but it looks like you are looping through all the columns and trying to set the saved column search values based on data from the ajax request.

    Kevin

  • kthorngrenkthorngren Posts: 20,309Questions: 26Answers: 4,770

    I don't totally understand your solution, requirements or code. Maybe instead of setting the saved column search values based on the ajax response (assuming I understand what you are doing) maybe you can bypass this and just set the column search values directly. It doesn't seem like you are using the saved column search values but what is returned in the ajax response.

    Kevin

Sign In or Register to comment.