Conditionally applying and removing css based on a table row clicked I've a added a click event to each row on a table element. Which I then use the $this context from the event to add some css styling to that clicked row.

The behavior is as follows:

IF tr doesn't have kpi-selected css applied
WHEN tr is clicked on table
THEN remove css style from all other tr elements
THEN add css style to clicked row's label
AND search the datatable for the clicked label's KPI


What I've noticed during testing is that the gulf between clicking and the css style being added to the element is very slow.

Question:

How can I optimize this code to improve speed between clicking a tr and applying the required css?

JSFiddle:

http://jsfiddle.net/brianVarleyHPE/mtkndq3e/

Gist of code: In the real implementation there will be more than one section-list table, this is a gist showing only one.

HTML

&lt;div class="block-wrap section" style="border-color: #01a982;"&gt;
    &lt;label class="section-title"&gt;Availability By Asset Criticality&lt;/label&gt;
    &lt;table class="section-list"&gt;
        &lt;tr id="normalAvailability"&gt;
            &lt;td class="td_title"&gt;Normal&lt;input id="lblNormal" type="hidden" value="Normal"&gt;&lt;/td&gt;
            &lt;td class="kpi-info"&gt;&lt;label class="big"&gt;2&lt;/label&gt;&lt;/td&gt;
            &lt;td class="td_title"&gt;&lt;img class="index_icon" src="~/Images/Picture8.png" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr id="small_tr"&gt;
            &lt;td&gt;&lt;/td&gt;
            &lt;td id="small_td"&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr id="mcAvailability"&gt;
            &lt;td class="td_title"&gt;Mission Critical&lt;input id="lblMC" type="hidden" value="Mission Critical"&gt;&lt;/td&gt;
            &lt;td class="kpi-info"&gt;&lt;label class="big"&gt;0&lt;/label&gt;&lt;/td&gt;
            &lt;td class="td_title"&gt;&lt;img class="index_icon" src="~/Images/Picture8.png" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr id="eeAvailability"&gt;
            &lt;td class="td_title"&gt;Entity Essential&lt;input id="lblEE" type="hidden" value="Entity Essentiall"&gt;&lt;/td&gt;
            &lt;td class="kpi-info"&gt;&lt;label class="big"&gt;1&lt;/label&gt;&lt;/td&gt;
            &lt;td class="td_title"&gt;&lt;img class="index_icon" src="~/Images/Picture8.png" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
&lt;/div&gt;    


CSS:

.kpi-selected label { 
    border:3px solid #0CA281;
    padding: 3px;
    border-radius:30px;
    -webkit-border-radius:30px;
    -moz-border-radius:30px;
}


JS

 $(".section-list").on('click', 'tr', function (e) {


        $('.section-list tr').removeClass("kpi-selected");


        if ($(this).attr('id') === "normalAvailability") {

            handleKPI_Selection($(this), 1, 'Normal');
        }
        else if ($(this).attr('id') === "mcAvailability") {

            handleKPI_Selection($(this), 1, 'Mission Critical');
        }
        else if ($(this).attr('id') === "eeAvailability") {

            handleKPI_Selection($(this), 1, 'Entity Essential');
        }


    });


    function handleKPI_Selection(td, index, searchFilter) {

        td.toggleClass("kpi-selected");
        if (td.hasClass("kpi-selected") &amp;&amp; index !== 0) {

            historyTable.search('').columns().search('').draw();
            historyTable.columns(index).search(searchFilter);
            historyTable.draw();
        } else {
            historyTable.search('').columns().search('').draw();
        }

    }
Should your &lt;tr&gt; elements be using normalAvailability, mcAvailabilty, etc. as ID's or as classes?
It looks like you are passing a &lt;tr&gt; element to handleKPI_Selection() not a &lt;td&gt;, so perhaps the parameter should be renamed.
I don't really see great value in your handleKPI_Selection() function being separated out. If don't see where the first conditional case would ever be triggered based on what you have shown (where index value is always 0).  This calls into question you whole design, which seems to alwasy want to pass in a searchFilter value, but then never use it.
Are you sure toggleClass("kpi-selected") is what you want to do here?  What if user repeatedly clicks the same row?
This following conditional seems unnecessary.


Your code:

    if ($(this).attr('id') === "normalAvailability") {

        handleKPI_Selection($(this), 0, 'Normal');
    }
    else if ($(this).attr('id') === "mcAvailability") {

        handleKPI_Selection($(this), 0, 'Mission Critical');
    }
    else if ($(this).attr('id') === "eeAvailability") {

        handleKPI_Selection($(this), 0, 'Entity Essential');
    }


This can be simplified to something like:

var idToSearchMap = {
   'normalAvailability': 'Normal',
   'mcAvailability': 'Mission Critical',
   'eeAvailability': 'Entity Essential'
}
var search = idToSearchMap[$(this).attr('id')] || '';
handleKPI_Selection($(this), 0, search);


Keep your code DRY.


I would avoid non-standard javascript symbol name syntax in your code (i.e. not camelCase). For example, handleKPI_Selection could perhaps instead be handleKpiSelection.
If you are going to have multiple section-list elements, then the following line of code may be problematic


Your code:

$('.section-list tr').removeClass("kpi-selected");


This will remove class from all rows on all section-lists.  If you only want to target current section list, then you would need to do something like:

$(this).closest('.section-list').find('tr').removeClass('kpi-selected');