Row.add() fails after doing a DOM sort

Row.add() fails after doing a DOM sort

c55v8c55v8 Posts: 12Questions: 2Answers: 0
edited October 2014 in Free community support

I am using DataTables 1.10.2. Both my row.add() and DOM sorting are working fine -- initially. Meaning on initial load table load, row.add() is working. But after I do a DOM sort on a column, suddenly row.add() is not functioning anymore.

The browser console shows that the error is occurring at line 213 of the jquery.dataTables.js ( (_pluck_order function):

out.push( a[ order[i] ][ prop ][ prop2 ] );

And the error is:

"Unable to get property '6' of undefined or null reference"

Any ideas?

My DataTable initialization:

    $(document).ready(function() {    

        /*** START: DataTable functions for sorting on DOM table fields ***/
        /* Create an array with the values of all the input boxes in a column */
        $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )
        {
            return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
                return $('input', td).val();
            } );
        }

        /* Create an array with the values of all the input boxes in a column, parsed as numbers */
        $.fn.dataTable.ext.order['dom-text-numeric'] = function  ( settings, col )
        {
            return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
                return $('input', td).val() * 1;
            } );
        }

        /* Create an array with the values of all the select options in a column */
        $.fn.dataTable.ext.order['dom-select'] = function  ( settings, col )
        {
            return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
                return $('select', td).val();
            } );
        }

        /* Create an array with the values of all the checkboxes in a column */
        $.fn.dataTable.ext.order['dom-checkbox'] = function  ( settings, col )
        {
            return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
                return $('input', td).prop('checked') ? '1' : '0';
            } );
        }           
        /*** END: DataTable functions for sorting on DOM table fields ***/

        //Datatable transform
        var t = $('#approveCrewDetTable').DataTable( {        
            "paging":   false, //disable paging functionality since we want to use scrolling instead
            "scrollY": "325px", //set vertical scroll area
            "scrollCollapse": true,
            "deferRender": true, //defers rendering for performance enhancement or so the API says     
            //"ordering": true,        
            //"info":     true,
            "columns": [
                            { "searchable": false, "orderable": false },
                            { "searchable": false, "orderable": false },
                            { "searchable": false, "orderable": false },
                            { "searchable": false, "orderable": false },
                            { "searchable": false, "orderable": false },
                            { "searchable": false, "orderable": false },
                            { "searchable": true,  "orderable": true, "orderDataType": "dom-text", type: 'string' }, //In Time
                            { "searchable": false, "orderable": false },
                            { "searchable": true,  "orderable": true, "orderDataType": "dom-text", type: 'string' }, //Out Time
                            { "searchable": false, "orderable": false },
                            { "searchable": false, "orderable": false },
                            { "searchable": false, "orderable": false },
                            { "searchable": false, "orderable": false }
                         ]
        });

Add row code snippet:

            var newRow = t.row.add( [
                "<center> <input id='acCB" + counter + "' name='acCB" + counter + "' type='checkbox' onClick='javascript:toggleHighlightRow(this, " + counter + ");' /><input id='acEdited" + counter + "' name='acEdited" + counter + "' type='hidden' value='true'/></center>",
                '',
                "<center><select id='acOpDD" + counter + "' name='acOpDD" + counter + "' class='select' style='width:45px'></select></center>",
                "<center><select id='acPosDD" + counter + "' name='acPosDD" + counter + "' class='select' style='width:35px'></select></center>",
                "<center><select id='acShiftDD" + counter + "' name='acShiftDD" + counter + "' class='select' style='width:30px'><option value='1' >1</option><option value='2' >2</option><option value='3' >3</option></select></center>",
                "<center><input type='text' size='9' id='acDetInDate" + counter + "' name='acDetInDate" + counter + "' onChange='checkDateTimeCollision();' /></center>",
                "<center><input type='textbox' size='7' placeholder='hh:mm:ss' onblur='isValidTime(this);' /></center>",
                "<center><input type='text' size='9' id='acDetOutDate" + counter + "' name='acDetOutDate" + counter + "' onChange='checkDateTimeCollision();' /></center>",
                "<center><input type='textbox' size='7' placeholder='hh:mm:ss' onblur='isValidTime(this);' /></center>",
                '<center>00:00</center>',
                "<center><input type='button'/></center>",
                "<center><input type='text' size='9' onblur='checkDateTimeCollision();'/></center>",
                '<center></center>'
            ] ).draw().node();

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin
    edited October 2014

    Can you link to a test case showing the problem please, as per the forum rules?

    Here is a test case based on my own example showing it working as expected: http://live.datatables.net/genezika/1/edit .

    I would also suggest trying the latest version (the nightly) as the first port of call rather then continuing to use an old version.

    Allan

  • c55v8c55v8 Posts: 12Questions: 2Answers: 0
    edited October 2014

    Thanks for the reply Allan and I apologize for not being aware of the forum rules.

    Here's my test case using all the latest versions (same as your original test case):

    http://live.datatables.net/genezika/2/edit

    And here are the steps to replicate:

    1. Click Add Row button (new row will be added at the bottom as expected)
    2. In the new row, put "07:00:00" under "In Time" column
    3. Click "In Time" column to sort (new row will go on top as expected)
    4. Click Add Row button -- This is where it FAILS -- No new row is added and JS Bin console shows "Script error. (line 0)"
  • c55v8c55v8 Posts: 12Questions: 2Answers: 0
    edited October 2014

    And just some additional observations:

    1. You can also add multiple rows successively and it is working fine. But the moment you sort "In Time" column, Add Row ceases to work.

    2. The issue doesn't appear on regular (non DOM) sorting. In the updated test case below, I have enabled sorting on "Status" column which is just a regular string/text column. Add row still works after doing a sort on this column. Also interestingly enough, after doing the replication steps in my previous post, doing a sort on "Status" will make the new row that failed to show up initially, magically appear.

    http://live.datatables.net/genezika/3/edit

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin
    Answer ✓

    Excellent - thanks for the test case.

    I think I see the problem - you have deferRender enabled, but the sort function is using column().nodes(). This is conflicting because the API method is trying to access the node before it exists (due to deferRender).

    I don't think the API should be throwing quite that error, so I'll look into that, however, it is still an error state and to allow this to work (i.e. to be able to access the nodes) you need to remove the deferRender. Without that it appears to work as expected.

    Allan

  • c55v8c55v8 Posts: 12Questions: 2Answers: 0

    That's it! You nailed it! Thank you very much and I appreciate the prompt response.

This discussion has been closed.