JSFiddle here: http://jsfiddle.net/xgTt2/3/
I have a $.each nested inside of a $.each, and I'm not sure why the second $.each is running twice. Any ideas?
var serverResponse = [{"Id":"aaa","OrderItems":[{"Id":1,"Description":"Salad"},{"Id":2,"Description":"Pizza"}]},{"Id":"bbb","OrderItems":[{"Id":3,"Description":"Salad"},{"Id":4,"Description":"Pizza"}]}];
$.each(serverResponse, function (index) {
var pos = serverResponse[index];
$('#placeholder').append('<p>' + pos.Id + '</p>')
$.each(pos.OrderItems, function (index) {
$('.orderitem').append('<p>' + this.Id +
' ' + this.Description + '</p>')
});
});
The above javascript is producing the following output:
aaa
1 Salad
2 Pizza
3 Salad
4 Pizza
bbb
3 Salad
4 Pizza
I want this:
aaa
1 Salad
2 Pizza
bbb
3 Salad
4 Pizza
Any idea what I'm doing wrong? Here's a working example of the problem: http://jsfiddle.net/xgTt2/3/
Near the end, you have two elements with the class orderitem. Using $('.orderitem').append() will append to both of them.
Instead, you want to append to the last element you created.
var $order_item = $('<p class="orderitem">' + pos.Id + '</p>');
$('#placeholder').append($order_item);
$.each(pos.OrderItems, function (index) {
$order_item.append('<p>' + this.Id +
' ' + this.Description + '</p>');
});
http://jsfiddle.net/xgTt2/4/
Here's the answer:
http://jsfiddle.net/7EmsX/
var serverResponse = [{
"Id": "aaa",
"OrderItems": [{
"Id": 1,
"Description": "Salad"
}, {
"Id": 2,
"Description": "Pizza"
}]
},
{
"Id": "bbb",
"OrderItems": [{
"Id": 3,
"Description": "Salad"
}, {
"Id": 4,
"Description": "Pizza"
}]
}];
$.each(serverResponse, function (index) {
var pos = serverResponse[index];
var $orderItem = $('<p class="orderitem">' + pos.Id + '</p>');
$orderItem.appendTo('#placeholder');
$.each(pos.OrderItems, function (index) {
$orderItem.append('<p>' + this.Id + ' ' + this.Description + '</p>')
});
});
When you select the .orderitem class, it is selected every pos item and inserting the sub items into it. You want to insert your sub-items only to the current pos item instead.
In second loop run, $('.orderitem') select all of your <p class="orderitem"></p>
Try below:
var serverResponse = [{"Id":"aaa","OrderItems":[{"Id":1,"Description":"Salad"},{"Id":2,"Description":"Pizza"}]},{"Id":"bbb","OrderItems":[{"Id":3,"Description":"Salad"},{"Id":4,"Description":"Pizza"}]}];
$.each(serverResponse, function (index) {
var pos = serverResponse[index];
var orderitemHTML = '';
orderitemHTML += '<p class="orderitem">' + pos.Id + '</p>';
$.each(pos.OrderItems, function (index) {
orderitemHTML += '<p>' + this.Id + ' ' + this.Description + '</p>';
});
$('#placeholder').append(orderitemHTML);
});
Related
I'm picking up a JSON object using a promise:
var x = get();
x.done(function(data) {
for(var i in data) {
}
});
which is returning this data when i do console.log(data);
[{…}]
0:
customer: "9028"
data:
active: "1"
customer: "9028"
description: ""
id: "13717"
inherited: "0"
name: "Out of Hours"
priority: "1"
shared: "0"
sound: ""
__proto__: Object
voip_seq: "4"
__proto__: Object
length: 1
__proto__: Array(0)
so that is working fine, but within my for loop, I want to add 2 items to data
I tried adding this into my .done
var obj = { name: "Light" };
data.push(obj);
But that didn't add to data
My for loop looks like this:
for(var i in data) {
var m = '<option value="' + data[i].data.id + '"'
if(data[i].data.id == selected_val) {
m += ' selected="selected"';
}
m += '>' + data[i].data.name + '</option>';
$('#' + value_element_id).append(m);
}
If you want to add two more items to your select, you simply need to push new objects into your data array before your loop starts. The objects must contain the structure and properties ("name" and "id" within a "data" sub-property) matching the JSON coming from the Promise, so that your loop code can process them.
In the simplest case, it could be as straightforward as
x.done(function(data) {
data.push({ "data": { "name": "light", "id": 1234 } });
data.push({ "data": { "name": "dark", "id": 5678 } });
for(var i in data) {
var m = '<option value="' + data[i].data.id + '"'
if (data[i].data.id == selected_val) {
m += ' selected="selected"';
}
m += '>' + data[i].data.name + '</option>';
$('#' + value_element_id).append(m);
}
});
Demo: https://jsfiddle.net/a286b7fw/1/
In this case I think data is not an array so it hasn't .push() method. You can add property to object like this:
for(var i in data) {
var m = '<option value="' + data[i].data.id + '"'
if(data[i].data.id == selected_val) {
m += ' selected="selected"';
}
m += '>' + data[i].data.name + '</option>';
$('#' + value_element_id).append(m);
// here it will add obj to data
var obj = {name: "Light"};
data = {
...data,
obj
}
}
I am creating a website to practice my coding on and I came across a problem while doing so. I am trying to import data from a json file with a forloop and the variables came back as undefined. I think it has to do with the i variable in the foreach, but I could be wrong. Any help is much appreciated. Thanks!
<script>
$.getJSON('package.json', function(data){
for(var i in data)
{
var username = i.username;
var value = i.value;
var tokens= i.tokens;
$(".list-group").append('<li>' + username + ' has deposited $' + value + ' in ' + tokens + ' tokens</li>');
}
});
</script>
And here is a copy of the json file
{
"u1":
{
"username": "Username1",
"tokens": 2,
"value": 26
},
"u2":
{
"username": "Username2",
"tokens": 4,
"value": 292
},
"u3":
{
"username": "Username3",
"tokens": 10,
"value": 127
},
"u4":
{
"username": "Username4",
"tokens": 3,
"value": 12
}
}
if data is an array, i will be an Integer-value string of the index.
You'll want data[i].username, data[i].value, data[i].tokens instead
if data is an object, you don't need to iterate through it
You'll want data.username, data.value, data.tokens instead
if the data from json is array of object use it;
<script>
$.getJSON('package.json', function(data){
for(var i in data)
{
var username = data[i].username;
var value = data[i].value;
var tokens= data[i].tokens;
$(".list-group").append('<li>' + username + ' has deposited $' + value + ' in ' + tokens + ' tokens</li>');
}
});
</script>
else use it
<script>
$.getJSON('package.json', function(data){
var username = data.username;
var value = data.value;
var tokens= data.tokens;
$(".list-group").append('<li>' + username + ' has deposited $' + value + ' in ' + tokens + ' tokens</li>');
});
</script>
I declare an array with json data, then when I init the array should be read and display on the div.
But now show nothing, can anyone help me check my code, what mistake I have made. Thanks.
JS Fiddle
HTML
<script>
$(function() {
var array = [];
array[0] = {
"no": "1",
"name": "fruit",
"value": "mango",
"totalvote": "75"
};
array[1] = {
"no": "2",
"name": "fruit",
"value": "apple",
"totalvote": "10"
};
array[2] = {
"no": "3",
"name": "fruit",
"value": "orange",
"totalvote": "5"
};
array[3] = {
"no": "4",
"name": "fruit",
"value": "banana",
"totalvote": "45"
};
PG.init("popup_survey_whitebox_selection", "1", array);
PG.callpopup();
PG.render_1();
});
</script>
JS
var PG = {
divid: "",
multiselection: "",
optionitem: [],
/* type:"", */
init: function (divid, multiselection, optionitem) {
/* PG.type = type;*/
PG.divid = divid;
PG.multiselect = multiselection;
PG.optionitem = optionitem;
},
test: function () {
for (var i = 0; PG.optionitem.length > i; i++) {
alert(PG.optionitem[i].name);
}
},
callpopup: function () {
$("#popup_survey_whitebox_content").hide();
var orig = '', // create var to cache the original text
newText = ''; // create var to cache the new Text with "..."
$("label#popup_survey_label_title").text(function (index, currentText) {
orig = currentText;
newText = currentText.substr(0, 30);
if (currentText.length > 30) newText += "...";
return newText;
});
$("#popup_survey_whitebox").hover(function () {
$('#popup_survey_whitebox_content').stop().animate({
opacity: 1,
height: "toggle"
}, 500, function () {
$("label#popup_survey_label_title").text(orig); // Here put the original text.
}).css('position', 'relative');
}, function () {
$('#popup_survey_whitebox_content').stop().animate({
opacity: 1,
height: "toggle"
}, 500, function () {
$("label#popup_survey_label_title").text(newText); // Here put the new text with "..."
}).css('position', 'relative');
});
$("#popup_survey_end_whitebox").click(function () {
$("#popup_survey_whitebox").remove();
});
},
render_1: function () {
$.each(array, function (i, obj) {
if (PG.multiselect == 1) {
var selection = "<li class='popup_survey_whitebox_li'></li><input class='the_checkbox' type='radio' id=" + obj.value + " name=" + obj.name + " value=" + obj.value + ">" +
"<label class='popup_survey_whitebox_label' for=" + obj.value + ">" + obj.no + ". " + obj.value + "</label>" +
"<div class='popup_survey_whitebox_progressbar'><div class='popup_survey_whitebox_progressbar_inner' for=" + obj.value + " style='width:" + obj.totalvote + "%;'>" +
"</div></div>" +
"<div id='popup_survey_whitebox_percent' class='popup_survey_whitebox_percent'>" + obj.totalvote + "%</div>";
} else {
var selection = "<li class='popup_survey_whitebox_li'></li><input class='the_checkbox' type='checkbox' id=" + obj.value + " name=" + obj.name + " value=" + obj.value + ">" +
"<label class='popup_survey_whitebox_label' for=" + obj.value + ">" + obj.no + ". " + obj.value + "</label>" +
"<div class='popup_survey_whitebox_progressbar'><div class='popup_survey_whitebox_progressbar_inner' for=" + obj.value + " style='width:" + obj.totalvote + "%;'>" +
"</div></div>" +
"<div id='popup_survey_whitebox_percent' class='popup_survey_whitebox_percent'>" + obj.totalvote + "%</div>";
}
$("#" + PG.divid).append(selection);
});
var survey_button = "<br><input id='submit_btn' type='button' class='whiteboxbutton whiteboxbutton-small' value='Finish' style='width:100%;'>";
$("#popup_survey_label_title").append("What is your favorite fruit??What is your favorite fruit??");
/*$("#popup_survey_whitebox_title").append();*/
$("#popup_survey_whitebox_inner_title").append("Please select 1 fruit only:");
$('#popup_survey_whitebox_button').append(survey_button);
$('.the_checkbox').on('change', function (evt) {
$('.popup_survey_whitebox_percent').css('display', 'block');
$('.popup_survey_whitebox_progressbar').css('display', 'block');
$(".popup_survey_whitebox_button").show();
if ($(this).siblings(':checked').length >= PG.multiselect) {
this.checked = false;
}
});
},
save: function () {}
}
I console and get this error Uncaught ReferenceError: array is not defined but I must declare on html.
There is other way around as well to solve this error besides closure. Since, you already have optionitem present in PG and you already passed the optionitem to it, you can use it as well inside render_1 method.
Change
$.each(array, function (i, obj) {
to
$.each(PG.optionitem, function (i, obj) {
With that, you need not to define array as a global variable which might conflict with others.
http://jsfiddle.net/5qnhcudp/2/
Your array is in a closure. There is a couple of different things you could do but simply, you can just move your array declaration outside of the closure.
JSFiddle
<script>
var array = [];
$(function() {
...
});
</script>
Found another solution to your problem, your PG object is actually trying to reference the global scope where it doesn't need to. See, your inline script where you declare the array, you are passing that into the PG object.
You have this:
render_1: function () {
$.each(array, function (i, obj) {
...
});
}
Replace with this:
render_1: function () {
$.each(PG.optionitem, function (i, obj) {
...
});
}
This solution is actually independant from my first one. If you don't want the array in global scope, this solution will work.
Ok, I am new to JQuery and I have requirement to do some manipulation on table based on rows.
The table consists of rows which belong to 3 different style classes Brand have category and category have products.
var table = $("table tbody");
table.find(".brand").each(function(i) {
var $tdsBrand = $(this).find("td"),
brand = $tdsBrand.eq(0).text(),
atyBrand = $tdsBrand.eq(1).text(),
alyBrand = $tdsBrand.eq(2).text();
console.log('Brand Row ' + (i + 1) + ':\nBrand Name: ' + brand + '\nActual TY: ' + atyBrand + '\nActual LY: ' + alyBrand);
var brandClass = $(this).attr("class");
console.log('brand class : ' + brandClass);
if (this row has next row as category) {
//if(brand.next($( "tr[class='category']" ))) {
//if ("(.band):has(.category)") {
//if ($(this).parents(".category").length == 1) {
table.find(".category").each(function(i) {
var catClass = $(this).attr("class");
console.log('category class : ' + catClass);
var $tdsCategory = $(this).find("td"),
category = $tdsCategory.eq(0).text(),
atyCategory = $tdsCategory.eq(1).text(),
alyCategory = $tdsCategory.eq(2).text();
console.log('Category Row ' + (i + 1) + ':\nCategory Name: ' + category + '\nActual TY: ' + atyCategory + '\nActual LY: ' + alyCategory);
if (This row has next row as product) {
//if(next($( "tr[class='product']" ))) {
//if ("(.category):has(.product)") {
//if ($(this).parents("product").length == 1) {
table.find(".product").each(function(i) {
var proClass = $(this).attr("class");
console.log('product class : ' + proClass);
var $tds = $(this).find("td"),
product = $tds.eq(0).text(),
aty = $tds.eq(1).text(),
aly = $tds.eq(2).text();
console.log('Product Row ' + (i + 1) + ':\nProduct Name: ' + product + '\nActual TY: ' + aty + '\nActual LY: ' + aly);
});
}
});
}
});
What I want to do is, I have to sum up Actual TY values of products and display them on their category. Then sum up Actual TY of categories (which has been calculated from products for different categories) to their brand.
Please refer http://jsfiddle.net/cfhhz0zr/46/ for clear understanding of my requirement and code which I've tried till now.
Thank you.
Just modified a bit your code and it seems that is doing what you are looking for. See also the http://jsfiddle.net/88prg1dt/
I refactored a bit and renamed some variables to make a bit more sense so should be fairly clear now. If you want to calculate the total for a product / category now should be really super simple.
Here is the JS code:
var $table = $("table tbody");
$table.find(".brand").each(function (brandIndex) {
var $brandRow = $(this);
var $tdsBrand = $(this).find("td");
var brandName = $tdsBrand.eq(0).text();
var atyBrand = $tdsBrand.eq(1).text();
var alyBrand = $tdsBrand.eq(2).text();
console.log('Brand Row ' + (brandIndex + 1) + ':\nBrand Name: ' + brandName + '\nActual TY: ' + atyBrand + '\nActual LY: ' + alyBrand);
var $categoryRows = $brandRow.nextUntil('.brand').filter('.category');
$categoryRows.each(function (categoryIndex) {
var $categoryRow = $(this);
var $tdsCategory = $categoryRow.find("td");
var categoryName = $tdsCategory.eq(0).text();
var atyCategory = $tdsCategory.eq(1).text();
var alyCategory = $tdsCategory.eq(2).text();
console.log('Category Row: ' + (categoryIndex + 1) + ':\nCategory Name: ' + categoryName + '\nActual TY: ' + atyCategory + '\nActual LY: ' + alyCategory);
var $productRows = $categoryRow.nextUntil('.brand, .category').filter('.product');
$productRows.each(function (productIndex) {
var $productRow = $(this);
var $tdProducts = $productRow.find("td");
var productName = $tdProducts.eq(0).text();
var atyProduct = $tdProducts.eq(1).text();
var aly = $tdProducts.eq(2).text();
console.log('Product Row ' + (productIndex + 1) + ':\nProduct Name: ' + productName + '\nActual TY: ' + atyProduct + '\nActual LY: ' + aly);
});
});
});
I played a bit with jQuery nextUntil() method as the documentation:
Description: Get all following siblings of each element up to but not
including the element matched by the selector, DOM node, or jQuery
object passed.
Is this answering your question ?
Okay, so I'm a JSON noob with only basic jQuery knowledge and I've looked all over for a solution and can't find one. Any help is greatly appreciated.
I need to:
1) loop through a JSON array (working)
2) display the first two results for "mbrname"
3) then display a count for the rest of the results.
I am successfully looping through and displaying ALL mbrname results. But somehow I need to only display the first two and if there are more display "+ # others"
Here's a screenshot of what the final product should look like:
Here's what my code produces now:
Here's my JSON:
{
"messages":{
"message":[
{
"date-time":"June 2, 2013 12:22 pm",
"subject":"This is the message subject",
"msg-string":"001",
"newmsg":"true",
"attach":"shop-cart",
"recipient":[
{
"mbrname":"D. Craig",
"mbr-href":"#craig"
},
{
"mbrname":"N. McCoy",
"mbr-href":"#mccoy"
},
{
"mbrname":"J. Smith",
"mbr-href":"#smith"
},
{
"mbrname":"B. Wardlaw",
"mbr-href":"#wardlaw"
}
]
},
{
"date-time":"May 23, 2013 12:22 pm",
"subject":"This is a great subject",
"attach":"none",
"msg-string":"002",
"newmsg":"true",
"recipient":[
{
"mbrname":"D. Craig",
"mbr-href":"#craig"
},
{
"mbrname":"N. McCoy",
"mbr-href":"#mccoy"
}
]
},
{
"date-time":"May 11, 2013 12:22 pm",
"subject":"Interested in your tomatoes",
"attach":"shop-cart",
"msg-string":"003",
"newmsg":"false",
"recipient":[
{
"mbrname":"J. Smith",
"mbr-href":"#smith"
}
]
}
]
}
}
Here's my jquery just for the "mbrname" section which successfully pulls in the names and appends them to my HTML:
$.each (message.recipient, function (message, recipient) {
var mbrPart = recipient.mbrname + ', ';
var currentUser = $('#' + newID + ' .name');
$(currentUser).append(mbrPart);
});
Thanks in advance for any help!
I'd keep it simple, no need to do any looping:
var recipientString = message.recipient[0].mbrname;
var count = message.recipient.length;
if (count > 1)
recipientString += ', ' + message.recipient[1].mbrname;
if (count > 2)
recipientString += ' + ' + (count - 2) + ' others';
$('#' + newID + ' .name').append(recipientString);
Something like this should work.
var count = 0;
$.each (message.recipient, function (message, recipient) {
if(count<2){
var mbrPart = recipient.mbrname + ', ';
var currentUser = $('#' + newID + ' .name');
$(currentUser).append(mbrPart);
}
count++;
});
$(currentUser).append(" + " + count-2 + " Others");