How to load state with less columns than the DataTable initialisation

How to load state with less columns than the DataTable initialisation

nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

Hi everyone! When i have to add more columns to my datatable initialisation, the stateLoadCallback doesn't load the content properly. Someone can help me? Thanks!

Answers

  • kthorngrenkthorngren Posts: 21,174Questions: 26Answers: 4,923

    Can you post your Datatables code so we can see what you are trying to do in the stateLoadCallback? Or better is a link to your page or a test case showing the issue.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    I'll try to explain a little more about it. We save the state content in the Database. So, when we need to add more columns to the DataTable, the previous states stop working because the number of the columns in the json state from the db isn't the same of the DataTable initialisation.

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0
    edited February 2021

    The stateLoadCallback:

      $.ajax({
            url: url,
            data: {
                id_modelo: id_config,
                tipo_doc: $('.content').data('tipo'),
                tipo: 'datatable_' + $('.content').data('tipo')
            },
            async: false,
            type: 'GET',
            dataType: 'JSON',
            success: function (json) {
                callback(json);
            }
        });
    

    Edited by Kevin:  Syntax highlighting. Details on how to highlight code using markdown can be found in this guide

  • kthorngrenkthorngren Posts: 21,174Questions: 26Answers: 4,923

    I created a test case but don't see any issues.
    http://live.datatables.net/xivifowu/11/edit

    You can add or remove columns and it seems to work.

    Are you doing something more than what you posted? Are you getting errors? Please describe the problem you are having.

    Can you please post a link to your page or a test case showing the issue.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    I saw your demo and actually it's the opposite, datatable needs to have 1 more column than json, with another data, then you can see the problem.

  • kthorngrenkthorngren Posts: 21,174Questions: 26Answers: 4,923
    edited February 2021

    Ok, lets change it a bit, comment out the last column:

            "columns": [
              { "data": "name", title: 'Name' },
                { "data": "position", title: 'Position' },
                { "data": "office", title: 'Office' },
                { "data": "extn", title: 'Extn' },
                { "data": "start_date", title: 'Date' },
                //{ "data": "salary", title: 'Salary' },
            ],
    

    Reload the page and the stateLoadCallback has only the five columns:

    {time: 1612301370877, start: 0, length: 10, order: Array(1), search: {…}, …}
    columns: Array(5)
    0: {visible: true, search: {…}}
    1: {visible: true, search: {…}}
    2: {visible: true, search: {…}}
    3: {visible: true, search: {…}}
    4: {visible: true, search: {…}}
    length: 5
    

    Add the last column:

            "columns": [
              { "data": "name", title: 'Name' },
                { "data": "position", title: 'Position' },
                { "data": "office", title: 'Office' },
                { "data": "extn", title: 'Extn' },
                { "data": "start_date", title: 'Date' },
                { "data": "salary", title: 'Salary' },
            ],
    

    Reload the page and the stateLoadCallback shows the same five columns. There are no errors and the Salary column is shown.

    Maybe you can tell me how to recreate the issue with this test case. Also you didn't answer my questions:

    Are you doing something more than what you posted? Are you getting errors? Please describe the problem you are having.

    EDIT: Here is the updated test case:
    http://live.datatables.net/xivifowu/14/edit

    Kevin

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    Hi! No, i'm not getting any errors.

    The datatable has 1 more column than the json in my case, you can see here: live.datatables.net/xeyutize/1/edit

  • kthorngrenkthorngren Posts: 21,174Questions: 26Answers: 4,923

    This error is being shown:

    DataTables warning: table id=example - Requested unknown parameter 'cte_peso' for row 0, column 6. For more information about this error, please see http://datatables.net/tn/4

    The reason is that the Ajax response from loading the table, ie, "ajax": "/ajax/objects.txt", does not have the object cte_peso. This error is not coming from using statesave.

    If your JSON response doesn't have the object defined you can use defaultContent. Like this:
    http://live.datatables.net/xeyutize/2/edit

    Kevin

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    Sorry for my bad communication in English.

    This defaultContent didn't work. So i'll try to show a little more about how i'm doing this here.

    My table:

        $('#table').DataTable({
                columns: [{
                    title: 'Marcs',
                    render: $.fn.dataTable.render.marcador('marcs')
                }, {
                    title: 'Emit',
                    render: $.fn.dataTable.render('emit', true)
                }, {
                    title: 'Emit CN',
                    visible: false,
                    render: $.fn.dataTable.render.cnpj('emit_cn')
                }],
                stateLoadCallback{
                $.ajax({
                      url: url,
                      data: {
                          id_modelo: id_config,
                          tipo_doc: $('.content').data('tipo'),
                          tipo: 'datatable_' + $('.content').data('tipo')
                       },
                       async: false,
                       type: 'GET',
                       dataType: 'JSON',
                       success: function (json) {
                           callback(json);
                       }
               });
            }
       });
    

    So, in my json state i have the values for marcs and emit but not for emit_cn. Because of this nothing happens.

  • kthorngrenkthorngren Posts: 21,174Questions: 26Answers: 4,923

    What is your data source?

    Why are you using async: false,?

    Because of this nothing happens.

    Does this mean the Datatable doesn't appear?

    Kevin

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    I have an database with a lot of states saved. So the user can change between those states, he can save an state with some order and some columns and another one different and i get these states from there.

    Actually there is no difference between async: false or true here for what i can see.

    The DataTable appear, but only like in "default" state.

  • kthorngrenkthorngren Posts: 21,174Questions: 26Answers: 4,923

    The DataTable appear, but only like in "default" state.

    When I asked What is your data source? I want to know where the row data comes from. Is it loaded into the DOM, are you using ajax, etc.

    Can you post a link to your page or a test case replicating the issue? I'm trying to replicate it for you but that is not working because I don't have the specifics of your solution.

    Kevin

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    I'll create a test case for you to check and i'll bring for you shortly.

    Thank you for your attention.

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    Hi. I'm bringing the test case and i'll show you in parts.

    I'm getting this same JSON from DB for both DataTables:

    {"time": 9999999999999, "order": [[5, "asc"]], "start": 0, "length": 10, "search": {"regex": false, "smart": true, "search": "", "caseInsensitive": true}, "columns": [{"visible": true}, {"visible": true}, {"visible": true}, {"visible": true}, {"visible": true}, {"visible": true}, {"visible": true}], "ColReorder": [6, 5, 4, 3, 2, 1, 0]}
    

    This first case shows the DataTable with 7 columns as the JSON. All is working so far, including order, ColReorder.
    Link to the case: https://testedevdocs.000webhostapp.com/
    DataTable without the new column:

    $('#table-documentos').DataTable({
        responsive: true,
        colReorder: true,
        stateSave: true,
        columns: [{
            title: 'Emitente',
            data: 'name'
        }, {
            title: 'Emitente CNPJ',
            data: 'position'
        }, {
            title: 'Emitente Município',
            data: 'salary'
        }, {
            title: 'Emitente Endereço',
            data: 'start_date'
        }, {
            title: 'Emitente Bairro',
            data: 'office'
        }, {
            title: 'Emitente CEP',
            data: 'extn'
        }, {
            title: 'Emitente teste',
            data: 'emit_teste'
        }],
        ajax: {
            type: 'POST',
            url: '/data.txt'
            //https://testedevdocs.000webhostapp.com/data.txt
        },
        stateSaveCallback: function(settings, data) {
            return false;
        },
        stateLoadCallback: function(settings) {
            var o;
            $.ajax({
                async: false,
                url: '/dbtest.php',
                dataType: 'json',
                success: function(json) {
                    o = json;
                }
            });
            return JSON.parse(o);
        }
    });
    

    And now the problem begins. Here in this another case i've add a new column to the DataTable and to the data.
    Because of this new column the Order, ColReorder, from JSON isn't working anymore. I think the DataTable shows as something like a "Default State". But the data is still showing.
    Link to the case: https://testedevdocs.000webhostapp.com/new_columns/
    DataTable with the new column:

    $('#table-documentos').DataTable({
        responsive: true,
        colReorder: true,
        stateSave: true,
        columns: [{
            title: 'Emitente',
            data: 'name'
        }, {
            title: 'Emitente CNPJ',
            data: 'position'
        }, {
            title: 'Emitente Município',
            data: 'salary'
        }, {
            title: 'Emitente Endereço',
            data: 'start_date'
        }, {
            title: 'Emitente Bairro',
            data: 'office'
        }, {
            title: 'Emitente CEP',
            data: 'extn'
        }, {
            title: 'Emitente UF',
            data: 'emit_uf'
            //New Column
        }, {
            title: 'Emitente teste',
            data: 'emit_teste'
        }],
        ajax: {
            type: 'GET',
            url: '/new_columns/data.txt'
            //https://testedevdocs.000webhostapp.com/new_columns/data.txt
        },
        stateSaveCallback: function(settings, data) {
            return false;
        },
        stateLoadCallback: function(settings, callback) {
            var o;
            $.ajax({
                async: false,
                url: '/new_columns/dbtest.php',
                dataType: 'json',
                success: function(json) {
                    o = json;
                }
            });
            return JSON.parse(o);
        }
    });
    

    I hope with this you can see what's happening.
    Thank you for all the support.

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    Sorry, actually those are the DataTables:
    Without the new column:

    $('#table-documentos').DataTable({
        responsive: true,
        colReorder: true,
        stateSave: true,
        columns: [{
            title: 'Name',
            data: 'name'
        }, {
            title: 'Position',
            data: 'position'
        }, {
            title: 'Salary',
            data: 'salary'
        }, {
            title: 'Start Date',
            data: 'start_date'
        }, {
            title: 'City',
            data: 'office'
        }, {
            title: 'CEP',
            data: 'extn'
        }, {
            title: 'Phone',
            data: 'phone'
        }],
        ajax: {
            type: 'POST',
            url: '/data.txt'
            //https://testedevdocs.000webhostapp.com/data.txt
        },
        stateSaveCallback: function(settings, data) {
            return false;
        },
        stateLoadCallback: function(settings) {
            var o;
            $.ajax({
                async: false,
                url: '/dbtest.php',
                dataType: 'json',
                success: function(json) {
                    o = json;
                }
            });
            return JSON.parse(o);
        }
    });
    

    With the new column:

    $('#table-documentos').DataTable({
        responsive: true,
        colReorder: true,
        stateSave: true,
        columns: [{
            title: 'Name',
            data: 'name'
        }, {
            title: 'Position',
            data: 'position'
        }, {
            title: 'Salary',
            data: 'salary'
        }, {
            title: 'Start Date',
            data: 'start_date'
        }, {
            title: 'City',
            data: 'office'
        }, {
            title: 'CEP',
            data: 'extn'
        }, {
            title: 'UF',
            data: 'emit_uf'
            //New Column
        }, {
            title: 'Phone',
            data: 'phone'
        }],
        ajax: {
            type: 'GET',
            url: '/new_columns/data.txt'
            //https://testedevdocs.000webhostapp.com/new_columns/data.txt
        },
        stateSaveCallback: function(settings, data) {
            return false;
        },
        stateLoadCallback: function(settings, callback) {
            var o;
            $.ajax({
                async: false,
                url: '/new_columns/dbtest.php',
                dataType: 'json',
                success: function(json) {
                    o = json;
                }
            });
            return JSON.parse(o);
        }
    });
    

    The only difference between this and the previous answer are only the names of the columns.
    Thank you!

  • kthorngrenkthorngren Posts: 21,174Questions: 26Answers: 4,923

    And now the problem begins. Here in this another case i've add a new column to the DataTable and to the data.
    Because of this new column the Order, ColReorder, from JSON isn't working anymore. I think the DataTable shows as something like a "Default State"

    Thanks for the added detail to understand the problem you are having. @allan or @colin can confirm but I suspect you are correct that Datatables will use defaults if the column definitions are different.

    Sounds like you might need to use stateSaveParams to save additional information about the table that you can use in stateLoadParams to manipulate the table ordering and column ordering as appropriate.

    Kevin

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    I see. Actually I was trying to manipulate adding name do the columns through SaveParams and then doing this:

    stateLoadParams: function(settings, data) {
        var colunas_visible = [];
    
        settings._iDisplayLength = data.length;
    
        for (var i = 0; i < data.columns.length; i++) {
            if (data.columns[i].visible)
                colunas_visible.push(data.columns[i].nome);
        }
    
        for (var i = 1; i < settings.aoColumns.length; i++) {
            if ($.inArray(settings.aoColumns[i].name, colunas_visible) !== -1)
                settings.aoColumns[i].bVisible = true;
            else
                settings.aoColumns[i].bVisible = false;
        }
    
        console.log(settings);
        console.log(data);
    },
    

    But i don't know how to manipulate the ColReorder.

  • kthorngrenkthorngren Posts: 21,174Questions: 26Answers: 4,923

    The colReorder.order() API is used to get and set the column order.

    Kevin

  • nathanbobatonathanbobato Posts: 12Questions: 1Answers: 0

    Interesting, the problem is that i don't know which is the new index. The new index could be index 40 and the 40 was a index that is visible in the json, so intead of show the old data, it will show the new data field for index 40.

    But i'll try something and i'm wait for the confirm for Allan and Colin.

    Thank you.

  • kthorngrenkthorngren Posts: 21,174Questions: 26Answers: 4,923

    The column-reorder event might be useful for you to keep track of the column reordering changes.

    Kevin

This discussion has been closed.