How to create break a loop on every third object? - javascript

I want to add a class to the first three database objects, then another class for the 4 to 6 objects and so on...
I found ways to break the loop but I hope there are better ways to accomplish bunches of three than to have to hardcode a lot of loops?
I'm thankful for all help!
http://jsfiddle.net/r61bce3z/
this is the basics of the loop i have:
var tableContent = '';
$.getJSON( '/users/insights', function( data ) {
userListData = data;
$.each(data, function(){
tableContent += '<ul>';
tableContent += '<li class="sub">' + this.date + '</li>';
tableContent += '</ul>';
});

The $.each() method calls your function with an index for the element it is up to. So use that with a little arithmetic as an index into an array of class names:
var classes = ['class1', 'class2', 'class3', 'class4'];
$.getJSON( '/users/insights', function( data ) {
userListData = data;
$.each(data, function(i){
tableContent += '<ul>';
tableContent += '<li class="' + classes[Math.floor(i/3) % classes.length]
+ '">' + this.date + '</li>';
tableContent += '</ul>';
});
});
Using Math.floor(i/3) gives you your groups of 3. Adding in % classes.length allows for if you have more groups of 3 than classes (so that you don't go past the end of the array of classes, it'll just start reusing the classes from the beginning of the array).

You can make it with some helper variables.
var tableContent = '';
var classIndex=-1;
$.getJSON( '/users/insights', function( data ) {
userListData = data;
$.each(data, function(index){
if(index % 3 == 0) classIndex++;
var css = classes[classIndex];
tableContent += '<ul>';
tableContent += '<li class="myClass' + classIndex + '">' + this.date + '</li>';
tableContent += '</ul>';
});
}

Related

Display JSON data in tablular format of predefined format

I am working on a small project's interface. Basically, an API sends the following JSON data:
{
"wallet_transactions": [
{
"total_cost": "80.000",
"expense_type__name": "Gas",
"total_quantity": "5.000",
"trans_type": "Purchased"
},
{
"total_cost": "250.000",
"expense_type__name": "Gas",
"total_quantity": "35.000",
"trans_type": "Rent"
}
]}
The data basically shows how much of GAS was given, its cost and its means (on credit or it was bought).
I tried to build a table out of it directly, but it was dimmed unfriendly since GAS was written twice.
What I tried was:
$.each(response.wallet_transactions, function(index) {
var exp_name=response.wallet_transactions[index].expense_type__name;
var quantity=response.wallet_transactions[index].total_quantity;
var price=response.wallet_transactions[index].total_cost;
var trans_type=response.wallet_transactions[index].trans_type;
rows=rows+'<tr><td>' + exp_name + '</td>';
rows=rows + '<td>' + price + '</td>';
rows=rows + '<td>' + quantity + '</td>';
rows=rows + '</tr>';
});
The output that is needed now looks like the image below:
Group the data for each name together in another object, then build the table from that.
var table_data = {};
$.each(response.wallet_transactions, function(i, trans) {
var exp_name = trans.expense_type__name;
var quantity = trans.total_quantity;
var price = trans.total_cost;
var trans_type = trans.trans_type;
if (!table_data[exp_name]) {
table_data[exp_name] = {}
}
table_data[exp_name][trans_type] = {
quantity: quantity,
cost: price
};
}
$.each(table_data, function(name, data) {
rows += "<tr><td>" + name + "</td>";
rows += "<td>" + data.Rent.cost + "</td>";
rows += "<td>" + data.Rent.quantity + "</td>";
rows += "<td>" + data.Purchased.cost + "</td>";
rows += "<td>" + data.Purchased.quantity + "</td>";
rows += "</tr>";
}
Notice that $.each passes the array element as the second argument to the callback function, so you don't have to repeat response.wallet_transactions[index] on every line.

How to have jquery loop over json data results to create a two column table

I'm having a bit of trouble trying to get my json data response shown in a two column table. I've found lots of posts that show how to show it as a single row, but nothing as a two column table.
This is what I have so far and it is still only showing a single column with multiple rows:
var trHTML = '';
$.each(data.Titles, function (i, item) {
var v = 0;
trHTML += '<tr>';
if(v <= 2){
trHTML += '<td>' + data.Titles[i] + '<br><img src="' + data.Images[i] + '"></td>';
}
else{
var v = 0;
trHTML += '</tr>';
trHTML += '<tr>';
}
trHTML += '</tr>';
v++
});
$('#location').append(trHTML);
},
Try this:
var trHTML = '';
var v = 0;
$.each(data.Titles, function (i, item) {
// it keeps v always 0 or 1 regarding if it's first or second column
if(v >= 2){
v = 0;
}
if(v == 0){
trHTML += '<tr>';
}
trHTML += '<td>' + data.Titles[i] + '<br><img src="' + data.Images[i] + '"></td>';
if(v == 1){
trHTML += '</tr>';
}
v++
});
if(v == 1){
trHTML += '</tr>';
}
$('#location').append(trHTML);
},

How to optimize the DOM inserting loop

For example : I want to insert many tr in a table like this
var tbody = $('#tbody')
// Suppose the articlelist is the data from ajax
while (articlelist.length > 0) {
var article = articlelist.shift(),
var tr = $(' <tr>'
+' <td>'+article.id+'</td>'
+'<td>' + article.channelid +'</td>'
+ '<td>'+article.comment+'</td>'
+'<td>'+article.last_edit_time+'</td><td>'
)
tbody.append(tr)
}
To avoid create the <tr>...</tr> in loop .Is it possible to use a class to generate the tr content ?
An optimized version:
var tbody = $('#tbody'),
htmlStr = "";
for (var i = 0, len = articlelist.length; i < len; i++) { // avoid accessing 'length' property on each iteration
htmlStr += '<tr><td>' + articlelist[i].id + '</td>'
+ '<td>' + articlelist[i].channelid + '</td>'
+ '<td>' + articlelist[i].comment + '</td>'
+ '<td>' + articlelist[i].last_edit_time + '</td><td><tr>';
}
tbody.append(htmlStr); // parses the specified text as HTML or XML and inserts the resulting nodes
You could use a loop to concatenate all the strings, then append this lengthy string all at once. This would help with performance for many trs
var tbody = $('#tbody')
var rows = ''
while (articlelist.length > 0) {
var article = articlelist.shift(),
rows += '<tr><td>'+article.id+'</td>'
+'<td>' + article.channelid +'</td>'
+ '<td>'+article.comment+'</td>'
+'<td>'+article.last_edit_time+'</td><tr>';
}
tbody.append(rows)
add a function like this to do this for you.
while (articlelist.length > 0) {
make_content(article);
}
function make_content(article) {
var tbody = $('#tbody');
var tr = $(' <tr>'
+' <td>'+article.id+'</td>'
+'<td>' + article.channelid +'</td>'
+ '<td>'+article.comment+'</td>'
+'<td>'+article.last_edit_time+'</td><td>'
)
tbody.append(tr)
}

Need help using a 'for loop' extracting data from a Table

Just wondering if anyone can help me.
I have created a table, and using Javascript I am extracting all the data and placing it into divs.
$(function () {
$('table').each(function () {
var output = "",
table = $(this),
rowHead = table.find('tbody tr th'),
rowSubject = table.find('thead tr th:not(:first-child)'),
rowContent = table.find('tbody tr td'),
copy = table.clone();
output += '<div class="mobiled-table">';
for (i = 0; i < rowHead.length; i++) {
output += '<div class="head">' + $(rowHead[i]).html() + '</div>';
for (j = 0; j < rowSubject.length; j++) {
output += '<div class="subject">' + $(rowSubject[j]).html() + '</div>';
output += '<div class="content">' + $(rowContent[i]).html() + '</div>';
}
}
output += '</div>';
$('table').append(output);
});
});
It all works great except the .content class isnt working correctly. I believe I am using the wrong 'for loop' or I need to create another 'for loop'. Please take a look at my codepen and you will see my problem
http://codepen.io/anon/pen/JrKBf
I hope someone can help.
Because rowContent contains the matrix of cells but as a one dimension array, you have to translate (i, j) to a valid index for rowContent which is (i * 4) + j:
rowContent[i]
should be replaced by:
rowContent[(i*4) + j]
In a simpler way, you can do like this,
var container=$("#container");
$("table tr:not(:first)").each(function() {
var heading = $(this).find("th").html();
container.append('<div class="subject">' + heading + '</div>');
$(this).find("td").each(function(i) {
container.append('<div class="subject">' + $("table th").eq($(this).index()).html() + '</div>');
container.append('<div class="content">' + $(this).html() + '</div>');
});
});
Fiddle

how to add multiple values in javascript?

i have this situation:
...
for (var i = 0; i < json.length; i++)
{
output += '<tr>';
for ( var objects in json[i])
{
if (objects == 'amt_1')
{
output += '<td id="amt">' + json[i][objects] + '</td>';
}
}
output += '</tr>';
}
output += '<tr">';
var amt = 0;
$('#amt').each(function() {
amt += $(this).text();
});
output += '<td>' + amt + '</td>';
output += '</tr>';
$('#details').append(output);
}
this is a part of a table that give's me something like this:
<td id="amt">4.58</td>
<td id="amt">55.74</td>
<td id="amt">193.5</td>
<td></td>
and in the last td i would like the sum of the rest of them with the id = amt
what i have seems not to work
any ideas?
Thnaks
The problem is that you are using id's instead of classes, id's are supposed to be unique, so javascript only returns 1 td. Multiple elements however, can share the same class.
Also, the jQuery won't work because the elements haven't been added to the document yet.
for (var i = 0; i < json.length; i++)
{
output += '<tr>';
for ( var objects in json[i])
{
if (objects == 'amt_1')
{
output += '<td class="amt">' + json[i][objects] + '</td>';
}
}
output += '</tr>';
}
output += '<tr">';
$('#details').append(output); //Copied here, this will add the above elements
//to the document subtree, which allows jquery
//to search for them
output = ""; //Reset output
var amt = 0;
$('.amt').each(function() { //Changed to class selector
amt += parseInt($(this).text());
});
output += '<td>' + amt + '</td>';
output += '</tr>';
$('#details').append(output); //Append result
Like they said you should use a class instead of id
output += '<td class="amt">' + json[i][objects] + '</td>';
Then you must add the output to the DOM before your jQuery selector, $('.amt'), can find the elements
$('#details').append(output); //<--append BEFORE you select the .amt elements
var amt = 0;
$('.amt').each(function() {
amt += parseFloat($(this).html()); //parseFloat on the html
});
output = '<tr">'; //<-- reset output here
output += '<td>' + amt + '</td>';
output += '</tr>';
$('#details').append(output);
Still it would be better to just sum the amount in your for loop
var total = 0;
...
if (objects == 'amt_1')
{
var curAmt = json[i][objects];
output += '<td class="amt">' + curAmt + '</td>';
total += parseFloat(curAmt);
}
...
output += '<td>' + total + '</td>';
You can't have more than one element with the same id on a page. $("#someId") will always select at most 1 element. So, your first problem is you don't even have a list of elements. You can solve that by using class instead.
Once you resolve the id issue, the trouble you'll have is you are trying to add text as though it were a number. First, you convert text to a number in one loop, then you loop through your entire collection again and try to add the textual numbers. Just get the total during the first loop. You'll be adding numbers instead of text, and you'll only have to iterate your collection once.
Also, you don't need to iterate the keys of an object just get a property. You can just reference the property directly: json[i].amt_1
While we're at it, let's not build up the html string, but instead just create the DOM elements directly. And take advantage of $.each() to do our looping.
var total = 0;
$.each(json, function (i, item) {
var row = $('<tr>').appendTo("#details");
$("<td>").appendTo(row).addClass("amt").text(item.amt_1);
total += item.amt_1;
});
var row = $("<tr>").appendTo("#details");
$("<td>").appendTo(row).text(total);

Categories