State persistence/loading: Better way to handle column mismatch?

State persistence/loading: Better way to handle column mismatch?

dclar43dclar43 Posts: 47Questions: 13Answers: 2

Currently I'm persisting states in a simple database table that users can pull from to have different 'views' or filter sets. An issue I've run into is when I add new columns to the table the 'outdated' states are disregarded and the default state is used instead. The reason for this is the following section from core.state.js

// Number of columns have changed - all bets are off, no restore of settings  
if ( s.columns && columns.length !== s.columns.length ) {  
    callback();  
    return;  
}

This is my current solution:

/**  
 * When columns are added to the table old states will be  
 * ignored and the default table state will be loaded instead.  
 *  
 * This function will append a generic column object for each missing column  
 * @param settings  
 * @param state  
 */  
function FixMissingColumns(settings, state) {  
    // I check if 'columns' exists because I handle state clearing by storing an empty object {}  
    if("columns" in state && state["columns"].length < settings.aoColumns.length) {  
        for(var i = state["columns"].length; i < settings.aoColumns.length; i++) {  
            state["columns"][i] = {  
                search: {  
                    caseInsensitive: true,  
                    regex: false,  
                    search: "",  
                    smart: true  
                },  
                visible: false  
            };  
        }  
    }  
}  

Is there a better way to handle this? I was unable to find a way to ask DataTables for a default state or just a default column state. I don't like that I'm having to use a hard coded object since that can cause issues if this structure changes in the future.

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    The reason I don't have this in DataTables core is that it presumes that the columns are being added to the end of the table's existing columns. That isn't always true in the cases that DataTables can be used for. Consider for example you have saved a date / time filter on column index 0 and then insert a new column to the left of it which is an integer. There is a decent chance that it might cause a Javascript error attempting to use save date / time search information on an integer column.

    The only way I can see of attempting to make this reliable is to check the data source name for the saved column (i.e. columns.data) - if a column doesn't match the information stored, then assume its a new column and inject a structure as you have done. That wouldn't work for array data sourced tables, but it would be okay for object based tables. But its a fair amount of code to add to the core for a case that doesn't happen too often, which is why I've taken the route I have.

    Allan

  • dclar43dclar43 Posts: 47Questions: 13Answers: 2

    The reason I don't have this in DataTables core is that it presumes that the columns are being added to the end of the table's existing columns. That isn't always true in the cases that DataTables can be used for. Consider for example you have saved a date / time filter on column index 0 and then insert a new column to the left of it which is an integer. There is a decent chance that it might cause a Javascript error attempting to use save date / time search information on an integer column.

    Oh, I totally agree this method shouldn't be in the core for the reasons you've stated.

    I should have been more clear I suppose. My main question was regarding this

    and inject a structure as you have done.

    I was just unsure if there was a way to retrieve a template of sorts for how a column is represented in the state. Here is how it's currently generated, but if that changes in the future then the hard coded structure in my above function would break.

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    Answer ✓

    Oops - I see! Currently no - there is no modal object for that in DataTables. However, it is worth noting that all of the options stored in the state saving object should be optional. If they don't exist then DataTables should fill them in with defaults. e.g. you can use stateSaveParams to delete the search information and it will still work.

    The state object structure is documented in the stateSaveCallback documentation. I consider this to be a public API and any changes would be breaking backwards compatibility.

    Allan

  • dclar43dclar43 Posts: 47Questions: 13Answers: 2

    Okay, sounds good. I'll keep my current solution in place for now.

    Thanks for the help!

  • Borsti26Borsti26 Posts: 5Questions: 2Answers: 0

    Hi dclar43,

    can you tell me how to implement your function FixMissingColumns.

    Thanks.
    BR

This discussion has been closed.