How to select and check a row in createdRow event?

How to select and check a row in createdRow event?

jstuardojstuardo Posts: 104Questions: 41Answers: 0

Hello...

I have a DataTable with Select extesion and this code in createdRow event:

$(row).addClass('selected'); $(row).select();

with that, only the row is hightlighted but the checkbox is not checked. How can I do it?

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975
    edited October 7

    $(row).addClass('selected');

    This won't select the row. It just highlights the row making it look selected. Look at the info element under the table and it won't show any rows as selected.

    $(row).select();

    This is executing the jQuery select() method not the Datatables row().select() API.

    Try this instead:

    this.api().row( row ).select();
    

    Kevin

  • jstuardojstuardo Posts: 104Questions: 41Answers: 0

    How can I access the API globally?

    In createdRow I am calling other function with only 2 parameters, row and data, and I cannot add a third one.

    So by callng this.api().row(row).select(); throws an error.

    Jaime

  • allanallan Posts: 63,691Questions: 1Answers: 10,500 Site admin
    var table = new DataTable('#myTable', ... );
    

    then table is the API instance. You'd use that. Or you can do:

    var table = new DataTable.Api('#myTable');
    

    if you need an API instance to an existing DataTable and you can't access the variable you previously created.

    Beyond that, we'd need to see your code.

    Allan

  • jstuardojstuardo Posts: 104Questions: 41Answers: 0
    edited October 8

    But isn't there a problem to call new for every created row?

    This is my createdRow code:

    createdRow: function (row, data, dataIndex) { if (typeof rowCallback === 'function') rowCallback(row, data); else if (!data.habilitado) { $(row).children('td').addClass('text-danger'); } }

    where rowCallback is an external function that is passed to a common function to initialize the grid.

    For this case, that rowCallback is this (actually this is surrounded by an if condition but it is not meaningful for this problem):

    function (row, data) { this.api().row(row).select(); }

    Jaime

  • allanallan Posts: 63,691Questions: 1Answers: 10,500 Site admin
    rowCallback: function (tr, data) {
      if ( data.whatever ) {
        this.api().row(tr).select();
      }
    }
    

    Allan

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975
    Answer ✓

    I see two options:

    1. Add a third parameter to your custom rowCallback function that is the Datatable API. If something calls it and doesn't pass the third parameter then it will be undefined in the function or you can set a default value.
    2. If you don't want to add the third parameter then use the jQuery click() API to click the appropriate selector in the row to select the row.

    Kevin

  • jstuardojstuardo Posts: 104Questions: 41Answers: 0
    edited October 8

    Thanks Kevin, I chose to add a third parameter. If that is not used by other callers, it does not matter.

    That way it works, but with a side effect. It works only for the first time.

    Let me tell you now that I have the DataTable inside a bootstrap modal. When the modal is closed, I am calling

    function unInitializeGrid(grid) {
            grid.clear();
            grid.destroy();
    }
    

    where grid is the DataTable. After doing that, I destroy the modal.

    When I open the modal for the second time, I get this error:

    Uncaught TypeError: Cannot read properties of undefined (reading 'id')
    at HTMLTableElement.<anonymous> (grid.js:171:60)
    at HTMLTableElement.dispatch (jquery.min.js:2:39997)
    at v.handle (jquery.min.js:2:37968)
    at Object.trigger (jquery.min.js:2:70063)
    at HTMLTableElement.<anonymous> (jquery.min.js:2:70665)
    at Function.each (jquery.min.js:2:3129)
    at ce.fn.init.each (jquery.min.js:2:1594)
    at ce.fn.init.trigger (jquery.min.js:2:70640)
    at d (datatables.min.js:33:2656)
    at X.<anonymous> (datatables.min.js:33:10833)

    Is this the proper way to completely free DataTable resources?

    The line #171 of grid.js is line 4 of this one:

    grid.on('select', function (e, dt, type, indexes) {
            if (type === 'row') {
                console.log(simpleDataGrid.rows(indexes).data());
                var id = simpleDataGrid.rows(indexes).data()[0].id;
                $('#' + name + '#chk_' + id).prop('checked', true);
            }
    

    where grid is the DataTable.

    When calling for the second time, the call to simpleDataGrid.rows(indexes).data() returns an empty array. That is why the error.

    That does not happen if I don't call this.api().row(tr).select();. It seems, I need to free Select extension resources.

    Any more advice, please?

    Thanks
    Jaime

  • kthorngrenkthorngren Posts: 21,449Questions: 26Answers: 4,975
    edited October 8

    Are grid and simpleDataGrid referencing the same Datatable? If so its possible simpleDataGrid is pointing to the old reference. If not then its confusing to my why you have a select event for one Datatable but reference another with the row indexes.

    You may need to dig a bit deeper in the select event to understand why simpleDataGrid.rows(indexes).data() returns an empty array. Like what is the value of indexes.

    Its hard to say what the problem might be with just the code snippets. We will need to understand your code flow to help debug. Please provide a link to a test case replicating the issue.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • jstuardojstuardo Posts: 104Questions: 41Answers: 0

    Hi Kevin... yes... sorry for my mistake. simpleDataGrid and grid is the same DataTable.

    However, the problem was my fault. I had this in DataTable:

    .on('select', function (e, dt, type, indexes) {
                if (type === 'row') {
                    console.log(simpleDataGrid.rows(indexes).data());
                    var id = simpleDataGrid.rows(indexes).data()[0].id;
                    $('#' + name + '#chk_' + id).prop('checked', true);
                }
            }).on('deselect', function (e, dt, type, indexes) {
                if (type === 'row') {
                    var id = simpleDataGrid.rows(indexes).data()[0].id;
                    $('#' + name + '#chk_' + id).prop('checked', false);
                }
    

    I am not sure why I did that, but I inherited that code when I used other checkbox in an older version of DataGrid.

    I have removed those "on" and it is working properly now. Thanks.

Sign In or Register to comment.