On click event failing when using responsive

On click event failing when using responsive

classic12classic12 Posts: 228Questions: 60Answers: 4

I have added the responsive extension and it works great for mobile.
I have added button in column 4.
I have the following test code that fails when the screen re-sizes and the button is now not in the same row. (ie they are above each other)

error is :

TypeError: undefined is not an object (evaluating 'data[0]').
line 139 column 20


$('#DataTable1 tbody').on( 'click', 'button', function () { var data = table.row( $(this).parents('tr') ).data(); alert( data[0] +"'s salary is: "+ data[ 2 ] ); } ); } } ); btnLocal2.onclick=function(){ data1 = [["Tom","Upright","5555","http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg"],["Andy","Upright","5555","http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg"],["John","Upright","5555","http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg"],["Paul4","Upright","5555","http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg"],["Paul5","Upright","5555","http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg"],["Paul6","Upright","5555","http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg"],["Paul7","Upright","5555","http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg"],["Paul8","Upright","5555","http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg"]] $("#DataTable1").dataTable().fnDestroy(); $('#DataTable1').empty(); var table = $('#DataTable1').DataTable( { dom: 'Bfrtip', responsive: true, autoWidth: false, buttons: [ 'copy', 'excel', 'pdf' ], data: data1, "columnDefs": [ { "title" : 'Salary', width : "14%", "targets": 2, "data": 2, "render": function (data, type, full, meta ) { return '<input type="text" name="'+data+'" value = '+data+'>' } }, { "title" : 'Link', width : "14%", "targets": 3, "data": 3, "render": function ( data, type, row, meta ) { return '<img src="'+data+'" style="height:50px;width:50px;"/>' } }, { "title" : 'Position', width : "14%", "targets": 1, "data": 1, "render": function ( data, type, row, meta ) { return '<input type="text" name="'+data+'" value = '+data+'>' } }, { "title" : 'Name', width : "14%", "targets": 0, "data": 0, "render": function ( data, type, row, meta ) { return '<input type="text" name="'+data+'" value = '+data+'>' } }, { "targets": 4, width : "14%", "data": null, "defaultContent": "<button>Click!</button>" }, { "targets": 5, width : "14%", "data": null, "className" : "dropzone", "action" : "/file-upload" }, { "title" : '5th COL', width : "14%", "targets": 6, "data": null, "className" : "dropzone", "action" : "/file-upload" } ] } );

Any ideas why ?

Cheers

Steve Warby

This question has an accepted answers - jump to answer

Answers

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Link to demo

    http://www.toolfolks.com/surplusAdmin2/

    Work in progress so may fail....

    Cheers

    Steve Warby

  • Tester2017Tester2017 Posts: 145Questions: 23Answers: 17
    edited November 2017

    This is your button position before the table is becoming "smaller".

    <tr role="row" class="odd">
        <td tabindex="0" class="sorting_1">565</td>
        <td>1318</td>
        <td>2017-11-02</td>
        <td><img src="http://www.toolfolks.com/techy/quoteImages/565_1.jpg" style="height:50px;width:50px;"></td>
        <td>15000 x desperado bar runners £5000 cash take all 11 x pallets</td>
        <td class="dropzone uploadServer dz-clickable" style="">
            <div class="dz-default dz-message">
                <span>Drop files here or click to upload</span>
            </div>
        </td>
        <td style=""><
            button>Click!</button>
        </td>
    </tr>
    

    And this is your button position after the table becomes smaller and fields were rendered:

    <tr class="child">
        <td class="child" colspan="5">
            <ul data-dtr-index="0" class="dtr-details">
                <li data-dtr-index="5" data-dt-row="0" data-dt-column="5">
                    <span class="dtr-title">Internal</span>
                    <span class="dtr-data"></span>
                </li>
                <li data-dtr-index="6" data-dt-row="0" data-dt-column="6">
                    <span class="dtr-title">Button</span>
                    <span class="dtr-data">
                        <button>Click!</button>
                    </span>
                </li>
            </ul>
        </td>
    </tr>
    

    And this is you jQuery event to respond on button clicks:

    //alert( 'Table redrawn' );
    // allows the on click to show which row. Has to be after the dataTable is created.
    $('#dtQuotes tbody').on( 'click', 'button', function () {
    var data = tableObject.row( $(this).parents('tr') ).data();
    alert( "Quote ID = " + data[0] +"' Date created =  "+ data[ 2 ] );
    

    Your event is trying to get something that is not present anymore. So you might modify your event e.g. add a class "i_am_at_another_position_now" to the button when the button
    is rendered to a child row.

    Then in your event function, you test if the button has this "i_am_at_another_position_now" and if so you are calling your data fields in another way, if not you call your data as you already did.

    To change the class of your button you have to use the response option of DataTables,
    which might look a little bit like this. It is only an example.

    table = $(`#myTable`).DataTable(
    {
        responsive:
        {
            details: {
                renderer: function(api, rowIdx, columns)
                {
                    var data = $.map(columns, function(col, i)
                    {
                        switch (col.hidden)
                        {
                            case true:
    
                                if ( [ pseudo code: if this column is my button])
                                {
                                    /*  Show memo complete. */
                                    col[`data`] = [ pseudo code: modify the data of your button by adding some class]
    
                                    //  ! important you can not use things like addClass etc.. because data is here
                                    //  simple text. It is not an object. So you have to resolve it in a way like
                                    //  col[`data`].replace(`button`, `button class="i_am_at_another_position_now"`);
                                }
    
                                return `<li data-dtr-index="` +
                                    col[`columnIndex`] +
                                    `" data-dt-row="` +
                                    col[`rowIndex`] +
                                    `" data-dt-column="` +
                                    col[`columnIndex`] +
                                    `"><span class="dtr-title">` +
                                    col[`title`] +
                                    `</span></td><td>&nbsp;<span class="dtr-data">` +
                                    col[`data`] +
                                    `</span></li>`;
    
                                break;
    
                            case false:
                                return ``;
                        }
    
                    }).join(``);
    
                    return data
                        ?
                            $(`<table/>`).append(`<ul data-dtr-index="`+columns[`rowIndex`]+`" class="dtr-details">`+data+`</ul>`)
                        :
                            false;
                }
            }
        },
    

    With browsers like Google Chrome and FireFox, you can inspect elements on your page. And then you will see the same results as I placed in the beginning of my comment.

    Another tool which might be interesting is Visual Event made by Allan from DataTables. You can find it here: https://github.com/DataTables/VisualEvent

  • Tester2017Tester2017 Posts: 145Questions: 23Answers: 17

    Instead of adding a new class to your button there must be a more simple and elegant way to check if your button is still visible in the main table, or in a child row.

    But I have not worked with that yet. I only know that if a column is not present anymore in the table it will receive as style "display: none".

    So maybe you only have to check for: $selecter.attr('style') = "display: none;"

    At least you know why things are happening and for sure you will receive a better solution than mine.

  • allanallan Posts: 61,833Questions: 1Answers: 10,133 Site admin
    Answer ✓

    You need to determine if your button is in the child row or not. The child row cannot be used as a selector for row(). So something like this would do it: http://live.datatables.net/yiyudapi/1/edit .

    You aren't the first to trip over this - I might make it so that the child row can be used as a selector in future, although my concern is about the performance impact.

    Allan

  • classic12classic12 Posts: 228Questions: 60Answers: 4

    Thanks for the info guys.
    Allan's code worked great....

This discussion has been closed.