user908094
user908094

Reputation: 390

DataTables with TableTools fnSelect() fires twice on row select

I am attempting to capture row selection via a (DataTable) TableTools button's fnSelect() (to do some pre-processing of the row's data) ie. the user selects a row, some manipulation of the row data is done; then user can click the button.

Problem is that the event (ie selecting the row) appears to fire twice -- the console.log() is clearly output twice...

And I've tried this using various versions of jQuery but always with the same result.

My table's definition is as follows:

$('#example').DataTable( {
  dom: 'T<"clear">lfrtip',
  tableTools: {
    "sRowSelect": "single",
    "aButtons": [
      {
        sExtends:"text",
        sNewLine: "<br/>", 
        sButtonText: "edit",
        fnSelect: function(nButton, oConfig, nRow){

          // replicates the behaviour of the select_single button
          // ie disable button unless a row is selected
          var iSelected = this.fnGetSelected().length;
          if ( iSelected == 1 ) {
            $(nButton).removeClass( this.classes.buttons.disabled );
          } else {
            $(nButton).addClass( this.classes.buttons.disabled );
          }
          // "do something" is output twice.
          console.log("[edit button's fnSelect()] do something"); 
          // so this would be a problem...
          // row_data = this.fnGetSelectedData()[0]);
          // do some function(row_data){}
        },
      },
   ],
 }
});

And I have a jsfiddle demonstrating this problem/behaviour.

I'd be grateful if anyone could shed some light on what I'm doing wrong (before I yell 'bug'!!)

Many thanks.

Upvotes: 2

Views: 1851

Answers (1)

Max
Max

Reputation: 78

You can think of fnSelect event as of 'on select state change'. That said, most of the time* it fires twice indeed: the first time for the previously selected row (select out) and the second time for the row you've just selected (select in).

One can easily distinguish between those two events by the means of .hasClass('selected') condition. So your code should be modified to look like this:

"fnSelect": function ( nButton, oConfig, nRow ) {
    if ($(nRow).hasClass('selected')) {
      // Do something with the newly selected row.
      alert($(nRow).html());
    }
    else {
      // Do something with the previously selected row.
      alert($(nRow).html());
}

*The only exception is when you click the currently selected row. Then fnSelect fires just once.

Another approach is to use the DataTables API:

var table = $('#example').DataTable();

$('#example tbody').on( 'click', 'tr', function () {
    if ( $(this).hasClass('selected') ) {
        // Do something in case the currently selected row has been clicked (that is 'de-selected').
        $(this).removeClass('selected');
        alert($(this).html());
    }
    else {
        // Do something in case a non-selected row has been clicked.
        table.$('tr.selected').removeClass('selected');
        $(this).addClass('selected');
        alert($(this).html());
    }
} );

Row selection API explained: http://www.datatables.net/examples/api/select_single_row.html

Upvotes: 2

Related Questions