Reputation: 379
I am using jquery and the each function but I am having trouble finding the last item in a ul list.
DATA:
<ul id="1">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<ul id="2">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<ul id="3">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
I have tried multiple things but nothing is doing what I want. Here is I have tried.
var test = '{';
for (i = 1; i <= 3; i++) {
test += i+':{';
$('#'+i+' li').each(function(index,e){
test += $(this).attr('id');
// THIS IS THE PROBLEM AREA START
if(index != $('#'+i).last()){
test += ',';
}
// PROBLEM AREA END
});
test += '}';
if(i != 3){
test += ',';
}
}
test += '}';
alert(test);
I have also tried using the "$('#'+i+':last')" but that did not do it ether.
The output I am trying to get is:
{1:{1,2,3},2:{1,2,3},3:{1,2,3}}
Upvotes: 2
Views: 2815
Reputation: 52518
After re-reading your question, what you really want is a clever way to make the output, not detecting what is the last element.
You should do something like:
var rootArr = new Array();
for (i = 1; i <= 3; i++) {
var liArr = new Array();
$("#" + i + " li").each(function() {
// add code to
liArr.push($(this).text());
}
rootArr.push(i + ":{" + liArr.join(",") + "}");
}
var result = "{" + rootArr.join(",") + "}";
(Based on SkillDrick's advice)
Upvotes: 1
Reputation: 16302
One of the problems is you are trying to use numbers for member names in Objects. I will eleminate this by prefixing these in the base object with "id-", and using arrays within the object.
var out = {};
$("ul").each(function() {
var ul = [];
$(this).find("li").each(function() {
ul.push($(this).text()); // maybe .html() ?
});
out."id-" + $(this).attr("id") = ul;
});
console.log(JSON.parse(out));
I haven't tested this, but you get the idea. Sort through each UL, and sort through each LI of each UL.
Should output:
{"id-1": [1,2,3], "id-2":, [1,2,3], "id-3":[1,2,3]}
Upvotes: 0
Reputation: 168715
Firstly, you're output looks like JSON code. Since you're using jQuery already, there are much easier ways to generate JSON code than building the string from scratch.
Secondly, a suggestion: If you use a classname for your <ul>
tags, you won't need to mess around with a for()
loop for those numeric IDs (do you really need numeric IDs? They'll bite you eventually! -- Bear in mind that IDs should be unique across the page. Plus JSON expects arrays with numeric indices to be denoted with square brackets rather than the curly braces you're using).
<ul class='mylist'>
<li>1</li>
...
Then you can write code like this:
myarray=[];
$('.mylist').each(function(ulindex) {
myarray[ulindex]=[];
$(this).children().each(function(liindex) {
myarray[ulindex][liindex]=$(this).text();
})
});
$output=$.toJSON(myarray);
Code above not tested, but should be close enough to give you an idea. (note: you may need a jquery plug-in to get the toJSON()
method; I can't remember)
Upvotes: 1
Reputation: 3052
jQuery actually utilizes the .length
property (http://api.jquery.com/length/) of each object. So, when you are using a selector, and you have a list of matched elements, .length - 1
will be the index of the last element.
i.e.:
var test = '{';
for (i = 1; i <= 3; i++) {
test += i+':{';
$('#'+i+' li').each(function(index,e){
test += $(this).attr('id'); //This is erroneous; this (ie e)'s
//id is nonexistent. Do you mean .html()?
// THIS IS THE PROBLEM AREA START
if(index != $('#'+i+' li').length - 1){
test += ',';
}
// PROBLEM AREA END
});
test += '}';
if(i != 3){
test += ',';
}
}
test += '}';
alert(test);
Although there are more than a few problems here. If you added the class='include'
to each <ul>
...
var str;
$('.include').each(function (index, e) {
str += e.attr('id') + ": {";
e.children().each(function (cIndex, child) {
str += child.html() + ( cIndex != e.children().length - 1 ) ? ', ' : '';
});
str += '}' + ( index != e.parent().children().length - 1);
});
May provide some helpful insights. Basically what you are are trying to write is a JSON serializer. You might want to check out http://flexjson.sourceforge.net/
Upvotes: 0
Reputation: 30996
You are trying to select the last element out of the matched set (which only consists out of your ul
rather than its children (which are li
elements)). You need to do this on the children of the current selection:
$('#'+i).children('li').last()
or (as selector):
$('#'+i+' > li:last')
Upvotes: 5
Reputation: 8117
2 Changes
Use
test += $(this).text();
instead of
test += $(this).attr('id');
Change if condition to
if($(this).next().length){
Modified code
var test = '{';
for (i = 1; i <= 3; i++) {
test += i+':{';
$('#'+i+' li').each(function(index,e){
// Change #1
test += $(this).text();
// Change #2
if($(this).next().length){
test += ',';
}
});
test += '}';
if(i != 3){
test += ',';
}
}
test += '}';
alert(test);
Upvotes: 1
Reputation: 70859
I would recommend you create an array with your strings, then join them with a comma.
So something like this:
var arr = ["1:{1,2,3}", "2:{1,2,3}", "3:{1,2,3}"];
var str = "{" + myArray.join(",") + "}";
So, in each iteration of the each
loop you'd construct a string like "1:{1,2,3}"
and push
it to your array.
Upvotes: 0