# 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 <div class="block-wrap section" style="border-color: #01a982;"> <label class="section-title">Availability By Asset Criticality</label> <table class="section-list"> <tr id="normalAvailability"> <td class="td_title">Normal<input id="lblNormal" type="hidden" value="Normal"></td> <td class="kpi-info"><label class="big">2</label></td> <td class="td_title"><img class="index_icon" src="~/Images/Picture8.png" /></td> </tr> <tr id="small_tr"> <td></td> <td id="small_td"></td> </tr> <tr id="mcAvailability"> <td class="td_title">Mission Critical<input id="lblMC" type="hidden" value="Mission Critical"></td> <td class="kpi-info"><label class="big">0</label></td> <td class="td_title"><img class="index_icon" src="~/Images/Picture8.png" /></td> </tr> <tr id="eeAvailability"> <td class="td_title">Entity Essential<input id="lblEE" type="hidden" value="Entity Essentiall"></td> <td class="kpi-info"><label class="big">1</label></td> <td class="td_title"><img class="index_icon" src="~/Images/Picture8.png" /></td> </tr> </table> </div>  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") && index !== 0) { historyTable.search('').columns().search('').draw(); historyTable.columns(index).search(searchFilter); historyTable.draw(); } else { historyTable.search('').columns().search('').draw(); } }  ## 1 Answer • Should your <tr> elements be using normalAvailability, mcAvailabilty, etc. as ID's or as classes? • It looks like you are passing a <tr> element to handleKPI_Selection() not a <td>, 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');

• typo: missing closing quote in 'mcAvailability': 'Mission Critical, – wOxxOm Aug 19 '17 at 9:03
• Hi @mike I definitely see benefit in using the object mapping and renaming. I've just edited my example above as user can search any column bar 0 , so 1-n which is why I pass in index. Thanks for review! – Brian J Aug 19 '17 at 16:21
• @BrianJ You really shouldn't edit the code in your original question (except perhaps to fix cut/paste errors), as this may remove context for answer for the benefit of future readers. I often see question poster posting an answer showing their "after" code or opening a new question for iterative code review as a way to continue dialog around their code. – Mike Brant Aug 21 '17 at 14:49