Luis Alvarado Luis Alvarado - 1 year ago 84
jQuery Question

Mark Selected Datatable Row based on Column Values

I am trying to mark several rows as SELECTED in a Datatable based on 2 column values each row has (The row has 3 columns but only the first 2 are the ones that I need to compare).

It currently works like this:

  1. The Datatable is populated with several cities (Nothing marked as Selected yet). This are all cities from another source where users can select or deselect cities. But they see the total cities.

  2. I then send an AJAX call with the user id to retrieve the actual selected cities so far.

  3. When I receive the cities already selected, I want to be able to search the datatable by the first 2 columns, which are city and state. If column 1 and 2 match the information that was retrieved on step 2, the mark it as selected (Visually mark the row as a selected row).

Any idea is appreciated. Currently what I have been doing is the following:


var maxOptions = serviceAreas.columns(0).data().eq(0).length;
data.forEach(function(item) {

for (var totalOptions = 0; totalOptions < maxOptions; totalOptions++) {

checkedOption = serviceAreas.row(totalOptions).data()[0] + ',' + serviceAreas.row(totalOptions).data()[1];

if (item == checkedOption) {

So after this works but it takes too long since it has to parse the whole table for each matched location. I am trying to avoid the whole parsing the whole table and simply do something like:

If item is found in the datatable, mark it as selectable go for the next one.

Answer Source

You could create a "keymap" over the options. By that you can skip the (slow) outer forEach loop completely. Also you only need to call the expensive table().row().data() chain once per row.

var maxOptions = serviceAreas.columns(0).data().eq(0).length,
    checkedOption, rowData,
    options = [];

//create a lookup table
for (var i = 0; i<data.length; i++) {
    options[data[i]] = true
for (var totalOptions = 0; totalOptions < maxOptions; totalOptions++) {
    //only read data once per row
    rowData = serviceAreas.row(totalOptions).data()
    checkedOption = rowData[0] + ',' + rowData[1];
    //select() if checkedOption exists as key in options
    if (options[option]) serviceAreas.row(totalOptions).select();

Completely untested of course, cannot replicate your scenario easily, but this should certainly work a lot faster.