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.
Related
I am looking to change the following code that I have found and to add questions with textbook or box that the user can fill in the answer in stead of only multiple choice.
How ever, every time I am trying to add if or if else the code goes corrupt. I have copied the code and removed all but 3 questions. how can I modify this?
var quizzes = [
{
name: "test",
questions: [
{
text: "Test1?",
choices: [
{ text: "1", correct: false },
{ text: "2", correct: true },
{ text: "3", correct: false },
],
},
{
text: "test2",
choices: [
{ text: "4", correct: false },
{ text: "5", correct: false },
{ text: "6", correct: true },
],
},
{
text: "Test3",
choices: [
{ text: "7", correct: true },
{ text: "8", correct: false },
{ text: "9", correct: false },
],
},
{
]
// When the document is ready
window.addEventListener('DOMContentLoaded', function() {
var $container = document.getElementById('container');
// Initialize each quiz into the container
quizzes.forEach(function(quiz) { initQuiz(quiz, $container); });
});
function initQuiz(quiz, $container) {
// DOM elements
var $dom = initDOM(quiz, $container),
// Current question index (starts at 0)
num = 0,
score = 0;
nextScreen();
function nextScreen() {
if (num < quiz.questions.length) {
displayQuestion();
} else {
displayEndResult();
}
}
function displayQuestion() {
clearDisplayArea();
var question = quiz.questions[num];
// Display the image if there is one
if (question.image) {
$dom.display.innerHTML = '<img src="' + question.image + '" class="question-img"/>';
}
// Display the question
$dom.display.innerHTML +=
'<p>Q' + (num+1) + ': ' + question.text + '</p>'
+ question.choices.map(function(choice, i) {
return '<label>'
+ '<input type="radio" name="' + quiz.name + '" value="' + i + '"/>'
+ choice.text
+ '</label>';
return '<form>'
+ '<input type = "text" id="textbook" name="' + quiz.name + '" value="' + i + '"/>'
+ textbox.text
+ '</form>' ;
}).join('')
+ '<br>';
// Create Submit button
$submit = document.createElement('button');
$submit.addEventListener('click', onAnswerSubmit);
$submit.innerHTML = 'Submit';
// Add the submit button
$dom.display.appendChild($submit);
}
function onAnswerSubmit() {
// Get the checked radio button
var selectedChoice = $dom.display.querySelector('input:checked');
if (!selectedChoice) {
alert("You need to select an answer");
} else {
// If it's correct
if (quiz.questions[num].choices[selectedChoice.value].correct) {
score++; // Add 1 point to the score
}
num++;
nextScreen();
}
}
function displayEndResult() {
clearDisplayArea();
$dom.display.innerHTML = '<p>End of Quiz</p>'
+ '<p>Congratulations! Your score is: ' + score + '</p>'
+ '<p>If you scored lower than 2, please keep practicing</p>';
}
function clearDisplayArea() {
$dom.display.innerHTML = '';
}
// The "DOM" (Document Object Model) represents HTML elements
function initDOM(quiz, $container) {
// Create frame
So this is one solution, first make sure you have a input box in your html file.
Now with the input box you could give it a class of whatever you want as below
<input class="personAnswer"></input>
Now you could go back to your JS code and add the following
document.getElementById("personAnswer").(WHATEVER YOU WANT TO CHECK FOR)
And that's it!
I am trying to get the value from the select element with jquery, but the console.log is showing that the value is NaN. I think it may have to do with the way I am selecting the ID's, but I am not sure.
//Here I am creating the select element with the options in a loop and giving them an incremental ID.
var div = $('<div class="containter">');
$('.rForm').append(div);
for(var x = 0; x < 10; x++)
{
var h3 = $('<h3 style="margin-bottom: 5px;">' + "Question" + " " + (x + 1) + '</h3>');
var label = $('<label>').attr('id', 'q'+ (x + 1)).text(questions[x]);
var br = $('<br>');
div.append(label);
div.append(br);
var select = $('<select>').attr('id', 'q'+ (x + 1));
for(var i = 0; i < 10; i++)
{
if(i === 0){
select.append($('<option>').text(options[i]));
}
else{
select.append($('<option>').attr('value', options[i].val).text(options[i].text));
}
console.log('hi')
}
$('.containter').append(select);
}
$('#submit').on('click', function(){
// var answers = [];
var newProfile = {
name: $('#name').val().trim(),
photo: $('#link').val().trim(),
scores: []
}
for(var x = 0; x < 10; x++){
var num = $('#q' + (x+1)).val(); //Showing the value as NaN
console.log("num", num)
newProfile.scores.push(parseInt(num));
}
console.log('new', newProfile);
console.log('scores' + newProfile.scores);
});
Rather do this :
var questions = [{
title: "Do you like jQuery ?",
expected: [0],
answers: [
"yes",
"no"
]
}, {
title: "jQuery is :",
expected: [1],
answers: [
"a language",
"a library",
"a framework"
]
}, {
title: "What is the type of jQuery.map() ?",
expected: [2],
answers: [
"[a] -> b",
"[a] -> [b]",
"[a] -> (a -> Int -> b) -> [b]"
]
}];
$("form").html($.map(questions, function (q, i) {
return ""
+ "<div>"
+ "<h3>" + q.title + "</h3>"
+ "<select "
+ "multiple "
+ "name=\"q" + i + "\""
+ "size=\"" + q.answers.length + "\""
+ ">"
+ $.map(q.answers, function (a, j) {
return "<option value=\"" + j + "\">" + a + "</option>";
}).join("")
+ "</select>"
+ "</div>";
}).join("") + (
"<button type=\"button\">Submit</button>"
));
$("button").click(function () {
var score = 0;
var $sel = $("select");
$sel.each(function (i) {
var answers = $(this).val() || [];
var expected = questions[i].expected;
if (answers.join() == expected.join()) score++;
});
alert(score + "/" + questions.length);
});
body, h3, select, input {font: normal 12px Arial;}
select {overflow: hidden;}
div {margin-bottom: 1em;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form></form>
EDITED:
I'm (still) having a little trouble getting values from a nested array in JSON and appending them to generated html.
I'm currently using the following JSON (updated):
{
"OuterArray": [
{
"memberId": "01",
"key01": "",
"included": "true",
"nestedArray": [
{ "keyA": "", "keyB": "" },
{ "keyA": "", "keyB": "" }
]
},
{
"memberId": "02",
"key01": "",
"included": "true",
"nestedArray": [
{ "keyA": "", "keyB": "" },
{ "keyA": "", "keyB": "" }
]
},
{
"memberId": "03",
"key01": "",
"included": "false",
"nestedArray": [
{ "keyA": "", "keyB": "" },
{ "keyA": "", "keyB": "" }
]
},
{
"memberId": "04",
"key01": "",
"included": "true",
"nestedArray": [
{ "keyA": "", "keyB": "" },
{ "keyA": "", "keyB": "" }
]
}
]
}
And this js:
for (var i = 0; i < outerArray.length; i++) {
if (outerArray[i].included !== "false") {
var key01 = outerArray[i].key01;
var key02 = outerArray[i].key02;
// etc.
var nestedArray = outerArray[i]["nestedArray"];
myDiv.innerHTML +=
"<div class=\"outer-array-stuff\">"
+ "<p class=\"key01\">" + key01 + "</p>"
+ "<p class=\"key02\">" + key02 + "</p>"
+ "<div class=\"nested-array-stuff\">" // help?
+ "</div>"
+ "</div>"
var nestedArrayStuff = document.getElementsByClassName("nested-array-stuff")[i];
for (var j=0; j<outerArray.length; j++) {
nestedArrayStuff.innerHTML += "<p class=\"keyA\">" + nestedArray[j].keyA + "</p>";
}
}
Note that one of the keys in the outer array has a boolean value which determines whether or not it (the outer array member) is - and its nested array stuff are - included in the page.
So just to reiterate, the goal is:
<div class="outer-array-stuff">
<!-- <snip: some outer array key/values here /> -->
<div class="nested-array-stuff">
<div class="nested-array-stuff">
<p>[e.g., nested array key 1 value]</p>
<p>[e.g., nested array key 2 value]</p>
<p>[etc.]</p>
</div>
</div>
If all the outer array members 'included' are 'true', everything outer & nested loads, but this is not exactly what I want; I need to filter so that only those 'included' !== "false". So now my problem is that despite being inside the if 'included'/else loop, the outer array members stop loading at the first excluded outer array member (actually, the next 'true' outer array member does load, but its nested array stuff doesn't, and then nothing further loads, the entire outer array loop dies.
Any insight as to why this is happening?
Many thanks to dreyescat for the help to this point.
P.S. generally I'm trying to minimize my reliance on jQuery.
Many thanks, svs
You are almost there. Here is your code revised with some comments.
// Generally is not a good practice iterate arrays using for..in
//for (var i in outerArray) {
for (var i = 0; i < outerArray.length; i++) {
var key01 = outerArray[i].key01;
var key02 = outerArray[i].key02;
// This should by outerArray array and not jsonData object.
var nestedArray = outerArray[i]["nestedArray"];
myDiv.innerHTML +=
"<div class=\"outer-array-stuff\">"
+ "<p class=\"key01\">" + key01 + "</p>"
+ "<p class=\"key02\">" + key02 + "</p>"
+ "<div class=\"nested-array-stuff\">" // help?
+ "</div>"
+ "</div>"
// getElementsByClassName gets a list of elements that have that class.
// I suppose you want to add the elements to the corresponding outer array.
// Let's use the loop index i to get the proper parent element. You could also
// just get the last one.
var nestedArrayStuff = document.getElementsByClassName("nested-array-stuff")[i]; // help?
// Again I recommend you not to use for..in for arrays.
for (var obj in nestedArray) {
nestedArrayStuff.innerHTML += "<p class=\"keyA\">" + nestedArray[obj].keyA + "</p>"; // NOPE
}
}
See demo.
You could also build the entire nested array stuff before adding it to the div element. Then you don't need to query the document to get the nested array stuff element.
for (var i in outerArray) {
var key01 = outerArray[i].key01;
var key02 = outerArray[i].key02;
var nestedArray = outerArray[i]["nestedArray"];
var nestedArrayStuff = '<div class=\"nested-array-stuff\">';
for (var obj in nestedArray) {
nestedArrayStuff += "<p class=\"keyA\">" + nestedArray[obj].keyA + "</p>"; // NOPE
}
nestedArrayStuff += '</div>';
myDiv.innerHTML += "<div class=\"outer-array-stuff\">"
+ "<p class=\"key01\">" + key01 + "</p>"
+ "<p class=\"key02\">" + key02 + "</p>"
+ nestedArrayStuff
+ "</div>"
+ "</div>";
}
See demo
nestedArray is not a string. your nestedArray array loop should be as follows.
var nestedArray = outerArray[i].nestedArray;
for (var j in nestedArray) {
console.log(nestedArray[j].keyA);
console.log(nestedArray[j].keyB);
}
Here is your complete solution, I used lists to output content. It assumes we have one container:
<div id="mydiv"></div>
Than JS would be:
var myDiv = document.getElementById('mydiv');
var outerArray = [
{
"memberId":"01",
"key01":"",
"key02":"key02 exists, ...",
"included":"true",
"nestedArray":[
{
"keyA":"1",
"keyB":"2"
},
{
"keyA":"3",
"keyB":"4"
}
]
},
{
"memberId":"02",
"key01":"key01 value..",
"included":"true",
"nestedArray":[
{
"keyA":"5",
"keyB":""
},
{
"keyA":"",
"keyB":"8"
}
]
},
{
"memberId":"03",
"key02":"",
"included":"false",
"nestedArray":[
{
"keyA":"",
"keyB":"9"
},
{
"keyA":"",
"keyB":""
}
]
},
{
"memberId":"04",
"key01":"value of key01",
"key02":"key02 value ...",
"included":"true",
"nestedArray":[
{
"keyA":"",
"keyB":"10"
},
{
"keyA":"11",
"keyB":"12"
}
]
}
];
var insertHtml = '';
for (var i = 0; i < outerArray.length; i++) {
if (outerArray[i].included !== "false") {
insertHtml += "<ul class=\"outer-array-stuff\">";
insertHtml += " <li>";
insertHtml += " <p class=\"memberId\">memberId(" + i + "): " + outerArray[i].memberId + "</p>"
insertHtml += " <p class=\"key01\">key01: " + ( ( typeof outerArray[i].key01!='undefined' && outerArray[i].key01 ) ? outerArray[i].key01 : '') + "</p>"
insertHtml += " <p class=\"key02\">key02: " + ( ( typeof outerArray[i].key02!='undefined' && outerArray[i].key02 ) ? outerArray[i].key02 : '') + "</p>"
var nestedArray = outerArray[i]["nestedArray"];
if ( nestedArray.length>0 ) {
insertHtml += " <ul class=\"nested-array-stuff\">"
for (var j=0; j<nestedArray.length; j++) {
insertHtml += "<li class=\"keyA\">keyA(" + j + "): " + nestedArray[j].keyA + "</li>";
insertHtml += "<li class=\"keyB\">keyB(" + j + "): " + nestedArray[j].keyB + "</li>";
};
insertHtml += " </ul>"
};
insertHtml += " </li>";
insertHtml += "</ul>"
}
}
myDiv.innerHTML = insertHtml;
I'm trying to pull out data from my json using match() in my search function. Here's what I want to do using the string inputted in the textbox. It would then pull out data from my json array as long as there is a match. Here's what I have so far:
var data = [{
"RM_Name": "Russ Martin",
"Division": "East",
"RM_Phone": "(603) 491-1259",
"RC_Name": "Jacob Sucoff",
"RC_Phone": "(800) 247-4154 x3403",
"States_Covered": "MT,VT, NH, ME (all firms)",
"Latitude": 46.6797995,
"Longitude": -110.044783,
"Coordinates": "46.6797995,-110.044783"
}, {
"RM_Name": "Carey Fortnam",
"Division": "East",
"RM_Phone": "(585)-259-7394",
"RC_Name": "Matt Wrzesniewsky",
"RC_Phone": "(800) 247-4154 x3088",
"States_Covered": "NY- Upstate ex Rockland County (BD, FP)",
"Latitude": 40.7056308,
"Longitude": -73.9780035,
"Coordinates": "40.7056308,-73.9780035"
}];
$.each(data, function(i, item) {
var rm_name = item.RM_Name,division = item.Division,rm_phone = item.RM_Phone,rc_name = item.RC_Name,rc_phone = item.RC_Phone,states = item.States_Covered;
var dataset='<tr class="'+rm_name+' '+rc_name+'"><td>'+rm_name+'</td><td>'+division+'</td><td>'+rm_phone+'</td><td>'+rc_name+'</td><td>'+rc_phone+'</td><td>'+states+'</td></tr>';
$('.rm-data').append(dataset);
});
$('#search').on('keypress', function (e) {
if(e.which == 13) {
search();
}
}).on('change', function (e) {
search();
});
function search() {
var query = $('#search').val();
// empty?
if(query === "")
{
$('.rm-data tr').show();
return;
}
$('.rm-data tr').hide();
$('.error-msg').hide();
if ($('.rm-data tr').hasClass(query)) {
$('.rm-data tr:contains(' + query + ')').fadeIn('slow', function () {
$('.rm-data tr:contains(' + query + ')').slideDown().show();
});
}
else {
//JSON Match Finder
$.getJSON(data, function (data) {
$.each(data, function (i, item) {
var test= item.RM_Name+' '+item.RC_Name;
var regex = new RegExp(query);
var test2 = test.match(regex);
console.dir(test2);
});
});
var error = '<div class="error-msg">Contact Not Found</div>';
$('.rm-table-search').append(error);
if ($('.error-msg').length == 0) {
$('.rm-table').append(error);
}
else {
$('.rm-table').append('');
}
}
}
I am able to find matches using this code but I cannot pull the data out. Is there anyway I can do this? Fiddle here.
Just sharing my output so far via console.log()
["Ru", index: 0, input: "Russ MartinJacob Sucoff", $family: function, $constructor: function, pop: function…]
ab-rm.js:80
6
null ab-rm.js:80
["Ru", index: 18, input: "Kevin GangMichael Rus", $family: function, $constructor: function, pop: function…]
ab-rm.js:80
12
null ab-rm.js:80
["Ru", index: 0, input: "Russ CorbyNatasha Fomenko", $family: function, $constructor: function, pop: function…]
ab-rm.js:80
8
null ab-rm.js:80
["Ru", index: 6, input: "Laura RupsisKenny Meyer", $family: function, $constructor: function, pop: function…]
I figured it out based on balexandre's idea:
$.each(data, function (i, item) {
var rm_name = item.RM_Name,
division = item.Division,
rm_phone = item.RM_Phone,
rc_name = item.RC_Name,
rc_phone = item.RC_Phone,
states = item.States_Covered;
var dataset = '<tr class="' + rm_name + ' ' + rc_name + '"><td>' + rm_name + '</td><td>' + division + '</td><td>' + rm_phone + '</td><td>' + rc_name + '</td><td>' + rc_phone + '</td><td>' + states + '</td></tr>';
$('.rm-data').append(dataset);
});
function search() {
var query = $('#search').val();
$('.rm-data tr').hide();
$('.error-msg').hide();
if ($('.rm-data tr').hasClass(query)) {
$('.rm-data tr:contains(' + query + ')').fadeIn('slow', function () {
$('.rm-data tr:contains(' + query + ')').slideDown().show();
});
} else {
var combined_array = [];
$.each(data, function (i, item) {
combined_array.push(item.RM_Name);
combined_array.push(item.RC_Name);
});
$.each(combined_array, function (i, item) {
var contents = item;
var array_check = item.indexOf(query) >= 0;
var matches = ''+contents+'';
$('#search-helper-container').append(matches);
$('.false').remove();
$('#search-helper-container').css('display', 'block');
});
var error = '<div class="error-msg">Contact Not Found</div>';
$('.rm-table-search').append(error);
if ($('.error-msg').length == 0) {
$('.rm-table').append(error);
} else {
$('.rm-table').append('');
}
}
}
$('#search-button').on('click', function () {
search();
});
$('#search').on('focus', function () {
$('#search').val('');
$('.true').remove();
$('#search-helper-container').css('display', 'none');
});
$('#search-helper-container').on('click', 'a.search-match', function (e) {
e.preventDefault();
var inputVal = $(this).text();
$('#search').val(inputVal);
});
And a working Fiddle here.
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);
});