7

I have a jQuery event bound to an element within a data table which fires without issue when the table is full width. However, when the table is collapsed and data tables responsive is applied the event doesn't fire. There isn't anything in the console about any errors.

You can see the code below and try it out on jsfiddle here:

Js-Fiddle Here

Click on the trash can and you get a popup. Resize the page until the table has collapsed. Open out the column to reveal the trash can and when you click it nothing happens.

Any ideas?

<!DOCTYPE html>
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">

<link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.7/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/tabletools/2.2.3/css/dataTables.tableTools.min.css">
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/responsive/1.0.6/css/dataTables.responsive.css">
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script type="text/javascript" src="//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="//cdn.datatables.net/tabletools/2.2.3/js/dataTables.tableTools.min.js"></script>
<script type="text/javascript" src="//cdn.datatables.net/responsive/1.0.6/js/dataTables.responsive.min.js"></script>

<script>
$(document).ready(function() {

// load data tables if element found
if (document.getElementById('data-table')) {
    $('#data-table').DataTable({
        "responsive": true,
        "paging":   true,
        "searching": true,
        "ordering": false,
        "info":     false
    } );
}

$(".deleteMe").bind('click', function () { 

    var dataString = $(this).attr('data');

    alert(dataString);
});

});

</script>
</head>
<body>

<table width="100%" id="data-table" class="display dataTable">
<thead>
<tr>
<th>Col</th>
<th>Col</th>
<th>Col</th>
<th>Col</th>
<th>Col</th>
<th width="10%">Actions</th>
</tr>
</thead>
<tbody>
<tr>
    <td>asfas</td>
    <td align="middle">fgfg</td>
    <td align="middle">COMPLETED</td>
    <td align="middle">4</td>
    <td align="middle">4</td>
    <td width="10%">
        <a href="#">
            <i alt="Delete" class="fa fa-trash fa-lg deleteMe" id="questionDelete" data="some text 1"></i>
        </a>
    </td>
</tr>
<tr>
    <td>sdfs</td>
    <td align="middle">test</td>
    <td align="middle">2014-02-28</td>
    <td align="middle">1</td>
    <td align="middle">0</td>
    <td width="10%">
        <a href="#">
            <i alt="Delete" class="fa fa-trash fa-lg deleteMe" id="questionDelete" data="some text 2"></i>
        </a>
    </td>
</tr>
<tr>
    <td>sfdsf</td>
    <td align="middle">fgfg</td>
    <td align="middle">COMPLETED</td>
    <td align="middle">4</td>
    <td align="middle">4</td>
    <td width="10%">
        <a href="#">
            <i alt="Delete" class="fa fa-trash fa-lg deleteMe" id="questionDelete" data="some text 3"></i>
        </a>
    </td>
</tr>
</tbody>
</table>

</body>
</html>
1
  • FYI, this isn't valid HTML markup, IDs must be unique on document context Commented May 14, 2015 at 13:22

3 Answers 3

22

I would suggest use .on instead and attach your click function and data attribute to <a> instead of <i> as below:

DEMO HERE

Your last column of each row would change to

<td width="10%">
    <a href="#" class="deleteMe" data="some text 1">
        <i alt="Delete" class="fa fa-trash fa-lg" id="questionDelete" ></i>
    </a>
</td>

Same for other columns which is there in demo

JS for delete would be:

$(".dataTable").on('click','.deleteMe', function () { 
    var dataString = $(this).attr('data');
    alert(dataString);
});
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks @Guruprasad Rao that seems to work but I don't understand why. Are you able to explain why? Thanks.
Even am not sure but since the position of control in DOM gets changed it might not be able to find it. I feel that's the reason.
Datatables on jquery call sizes everything up. Doing widths declarations that it can't natively or adding/removing not via the API causes oddness to happen on resize.
This was a huge help. I'm doing this in angular, so put this in a directive and accessing my controller in the link function to call functions on it.
It works because when datatables drops data into the child row, it doesn't do it by fetching the DOM element, it does it by grabbing the raw HTML from within the cell. Since HTML doesn't carry listeners, the button is duplicated, but the listener is not. Attaching the listener to the table sidesteps this issue, since the table is always there.
0

The reason why this doesn't work is because datatables fires a "fnDraw" event each time it's asked to resize, paginate or in short, render something.

Your "deleteMe" elements are initially bound to the table when first rendered, but the $(".deleteMe").bind('click', function () { } is not called when your tables are resized.

Luckily, you can bind an event listener which fires each time the table is asked to be redrawn:

if (document.getElementById('data-table')) {
  $('#data-table').DataTable({
     "responsive": true,
     "paging":   true,
     "searching": true,
     "ordering": false,
     "info":     false,
     //add a listener to fire when redrawn:
     "fnDrawCallback" : function(oSettings) {
        setDeleteMeEvent()
     }
   });
}

function setDeleteMeEvent() {
  //Ensure that prior event is take off the DOM
  $(".deleteMe").unbind('click')
  $(".deleteMe").bind('click', function () { 
  var dataString = $(this).attr('data');
  alert(dataString);
}

You have to unbind the previous click event or otherwise unexpected things will happen. Likely multiple event handlers will stack on the dom causing your click event to fire once per redraw.

More info on (an apparently updated) draw callback is documented: https://datatables.net/reference/option/drawCallback

Also note that @Guruprasad's answer works because you're binding a click event to the entire table itself.

I've updated your fiddle here: http://jsfiddle.net/eggmatters/891mdyvy/16/

1 Comment

You Fiddle code has a bug. The event does not fire when the column is collapsed for responsive display.
0

for me i just gave .table-responsive class a min-height of 200px and it worked awesome.

componentDidMount(){
    this._isMounted = true

      $('.table-responsive').css( "min-height", "200px" );
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.