Bryan Dellinger Bryan Dellinger - 6 days ago 7
Javascript Question

DataTable losing fnCreatedCell after onClick event

Here is a fiddle that shows the problem: http://jsfiddle.net/LkqTU/32602/

If you go to the fiddle you will notice the last column is a link. If you click the checkbox on the first column you lose the link. I would like to keep the link.

I am creating the link in the DataTable like so...

{
data: 'dept',
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
$(nTd).html("<a href='Freight_ITN.aspx?scn=" + oData.dept + "' target='_blank'>" + "ITN ENTRY" + "</a>");
}


The
onClick
event of the checkbox is where I am losing my link (I think):

$('#mytable tbody').on('click', 'input[type="checkbox"]', function (e) {
var active = $(this).prop('checked');
var $row = $(this).closest('tr');
console.log($row);
var record = oTable.row($row).data();
record.active = active;
//console.log(record);
oTable.row($row).data(record).draw(false);
});


I noticed that DataTable has a
fnDrawCallback
, however it appears to be deprecated, and I'm unsure how to use it to get my link back.

Answer

You need add the rendering function to the column definitions configuration for your DataTable.

See the following example: http://jsfiddle.net/34ufp3ps/1/

columnDefs: [{
  render: function(value, type, record, cellIndex) {
    if (record.active) {
        return value; // If selected, show the value instead of a link.
    } else {
        return '<a href="Freight_ITN.aspx?scn=' + value + '" target="_blank">' + 'ITN ENTRY</a>';
    }
  },
  targets: 4 // Column #4 (Dept)
}]

Code

I made your class names Capitalized and added a convenience insert() method for proper OOP encapsulation of your Model object.

function Employee(id, firstName, lastName, dept, active, displayAsLink) {
  var self = this;
  this.id = id;
  this.firstName = firstName;
  this.lastName = lastName;
  this.dept = dept;
  this.active = active;
  this.displayAsLink = displayAsLink;
}

function EmployeeModel() {
  var self = this;
  this.employees = [];
}
EmployeeModel.prototype.insert = function(employee) {
  this.employees.push(employee);
}

var myModel = new EmployeeModel();

$(document).ready(function() {
  myModel.insert(new Employee('1', 'Clara', 'Dellinger', 'IT', false, true));
  myModel.insert(new Employee('2', 'John', 'Smith', 'HR', false, true));
  myModel.insert(new Employee('3', 'Fred', 'Jones', 'Finance', false, false));
  myModel.insert(new Employee('4', 'Mary', 'Jans', 'Finance', false, false));
  myModel.insert(new Employee('5', 'Bob', 'Jones', 'IT', false, false));
  myModel.insert(new Employee('6', 'Fred', 'Thebes', 'HR', false, true));
  myModel.insert(new Employee('7', 'Sally', 'Jane', 'HR', false, true));
  myModel.insert(new Employee('8', 'Patrick', 'Roberts', 'HR', false, true));
  myModel.insert(new Employee('9', 'Lisa', 'Myers', 'Lab', false, true));
  myModel.insert(new Employee('10', 'Roscoe', 'Coletrain', 'Security', false, true));

  var table = $('#mytable').DataTable({
    data: myModel.employees,
    columns: [{
      data: 'active',
      render: function(data, type, row) {
        if (type === 'display') {
          return '<input type="checkbox" class="editor-active">';
        }
        return data;
      },
      className: "dt-body-center"
    }, {
      data: 'id'
    }, {
      data: 'firstName'
    }, {
      data: 'lastName'
    }, {
      data: 'dept'
    }],
    columnDefs: [{
      render: function(value, type, record, cellIndex) {
        if (record.active) {
          return value;
        } else {
          return '<a href="Freight_ITN.aspx?scn=' + value + '" target="_blank">' + 'ITN ENTRY</a>';
        }
      },
      targets: 4 // Column #4 (Dept)
    }],
    rowCallback: function(row, data) {
      // Set the checked state of the checkbox in the table
      $('input.editor-active', row).prop('checked', data.active);
    },
    aaSorting: [
      [3, 'asc']
    ],
  });

  $('#mytable tbody').on('click', 'input[type="checkbox"]', function(e) {
    var active = $(this).prop('checked');
    var $row = $(this).closest('tr');
    var employee = table.row($row).data();
    employee.active = active;
    //console.log(employee);
    table.row($row).data(employee).draw(false);
  });

  $.fn.dataTable.ext.search.push(
    function(oSettings, aData, iDataIndex) {
      var isSelected = aData[0];
      var keywords = $("#mysearch").val().toLowerCase().split(' ');
      var matches = 0;
      for (var k = 0; k < keywords.length; k++) {
        var keyword = keywords[k];
        for (var col = 0; col < aData.length; col++) {
          if (aData[col].toLowerCase().indexOf(keyword) > -1) {
            matches++;
            break;
          }
        }
      }
      return (matches == keywords.length) || (isSelected === 'true')
    }
  );

  $('#mysearch').keyup(function() {
    table.draw();
  });
});
.dataTables_filter {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/js/jasny-bootstrap.min.js"></script>
<script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-3.2.0.js"></script>

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="http://cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/css/jasny-bootstrap.min.css" rel="stylesheet" />

<div>
  <input type="text" id="mysearch" name="mysearch" placeholder="search" />
</div>

<table class="table" id="mytable">
  <thead>
    <tr>
      <th>Select</th>
      <th>Id</th>
      <th>First</th>
      <th>Last</th>
      <th>Dept</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>

Comments