Add class based on JSON data

With dynamically generated HTML from JSON data, I am trying to add a class to each .status-card , in this case depending on the value of c.callStatus . This is the closest I got, but it just adds the active class to all status-card . I assume this is due to the way I use $(this) , or am I missing something else?

 $(function() { var agents = []; $.getJSON('js/agents.json', function(a) { $.each(a.agents, function(b, c) { var content = '<div class="status-card">' + '<div class="agent-details">' + '<span class="agent-name">' + c.name + '</span>' + '<span class="handling-state">' + c.callStatus + '</span>' + '<span class="handling-time">' + c.handlingTime + '</span>' + '</div>' + '<div class="status-indicator"></div>' + '</div>' $(content).appendTo('#left'); //Add class depending on callStatus $('.status-card').each(function() { if (c.callStatus == 'On Call') { $(this).removeClass('idle away').addClass('active'); } else if (c.callStatus == 'Idle') { $(this).removeClass('active away').addClass('idle'); } else { $(this).removeClass('active idle').addClass('away'); } console.log(c.callStatus); }); }); }); }); 

Thanks!

+5
source share
3 answers

You call $('.status-card').each() for each agent in the a.agents list. therefore, in the final iteration, all .status-card elements will have the last agent.callStatus class agent.callStatus .

I would write something like this.

 $(function() { function createStatusCard(name,callStatus,handlingTime) { var status_class_map = { "On Call" : "active", "Idle" : "idle" }; var $content = $("<div/>").addClass("status-card").addClass(function(){ return status_class_map[callStatus] || "away"; }); $content.html('<div class="agent-details">' + '<span class="agent-name">' + name + '</span>' + '<span class="handling-state">' + callStatus + '</span>' + '<span class="handling-time">' + handlingTime + '</span>' + '</div>' + '<div class="status-indicator"></div>'); return $content; } $.getJSON('agents.json', function(a) { $.each(a.agents, function(b, c) { $("#left").append(createStatusCard(c.name,c.callStatus,c.handlingTime)); }); }); }); 

it is more readable and easier to debug.

+1
source

This is the closest I got, but it adds an active class to all status-card .

This is because after adding each status-card you add other classes to all the status cards added so far:

 $.each(a.agents, function(b, c) { .... // here you are updating the class for all the cards added till now. $('.status-card').each(function() { .... }); .... }); 

So, active classes are added to all other cards, because it could be callStatus in the last outer loop.

You can calculate className based callStatus before creating HTML, and then use this className in HTML, like this:

 function getClassNameByStatus (callStatus) { switch(callStatus){ case "On Call": return "active"; case "Idle": return "idle"; default: return "away"; } } $.each(a.agents, function(b, c) { var className = getClassNameByStatus(c.callStatus); var content = '<div class="status-card' + className + '">' + ....; // rest of the HTML $(content).appendTo('#left'); }); 
+2
source

This is because your status-card each loop is nested in your JSON loop. Therefore, every time you punch an object from JSON data, you set the entire class of status-card elements that are already added to the DOM.

You can restructure to set the class as you assemble the elements before adding.

  $.each(a.agents, function(b, c) { var content = '<div class="agent-details">' + '<span class="agent-name">' + c.name + '</span>' + '<span class="handling-state">' + c.callStatus + '</span>' + '<span class="handling-time">' + c.handlingTime + '</span>' + '</div>' + '<div class="status-indicator"></div>'; var $statusCard = $("<div/>").addClass("status-card"); .append(content); $statusCard.addClass(function(){ switch(c.callStatus){ case "On Call": return "active"; case "Idle": return "idle"; default: return "away"; } }()); $statusCard.appendTo('#left'); }); 
0
source

Source: https://habr.com/ru/post/1261193/


All Articles