Reputation: 33
Source XML looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<area>
<ticket>
<ticketnumber>001</ticketnumber>
<location>Location</location>
</ticket>
<ticket>
<ticketnumber>001</ticketnumber>
<location>Location</location>
</ticket>
<ticket>
<ticketnumber>001</ticketnumber>
<location>Location</location>
</ticket>...
</area>
I can parse this into an existing un-ordered list using the following code:
$(document).ready(function(){
$.ajax({
type: "GET",
url: "feed.xml",
dataType: "xml",
success: function(xml) {
$(xml).find('ticket').each(function(){
var varTicket = $(this).find('ticketnumber').text();
var varLocation = $(this).find('location').text();
var varTheHTML = '<li>'+varTicket+' '+varLocation+'</li>';
$(varTheHTML).appendTo("#ticket-test");
});
},
error: function() {
alert("The XML File could not be processed correctly.");
}
});
});
This provides me with a populated list as expected.
<ul id="ticket-test">
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>...
</ul>
The problems begin to arise when I need to split this list into multiple lists, ideally nested in the master list. The new structure would now be:
<ul id="ticket-test">
<li>
<ul>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>...
</ul>
</li>
<li>
<ul>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>...
</ul>
</li>...
</ul>
The source XML is essentially a flat list, so I need to assign these list items into chunks of, say, 10 or so (used later with unslider).
I have tried running counters within the .each function and using a return false to jump back out again, but the code quickly becomes a spaghetti junction, I'm certain there is a more elegant way of achieving this.
I've also tried .split and for loops, but keep hitting a brick wall.
Upvotes: 3
Views: 651
Reputation: 32354
You can do something like this
$(document).ready(function() {
$.ajax({
type: "GET",
url: "feed.xml",
dataType: "xml",
success: function(xml) {
var html = '<li><ul>';
var counter = 10;
$(xml).find('ticket').each(function(i, v) {
var varTicket = $(v).find('ticketnumber').text();
var varLocation = $(v).find('location').text();
if (i > 0 && i % counter == 0) {
html += '</ul></li><li><ul>';
}
html += '<li>' + varTicket + ' ' + varLocation + '</li>';
});
$(html + '</ul></li>').appendTo("#ticket-test");
},
error: function() {
alert("The XML File could not be processed correctly.");
}
});
});
see demo:https://jsfiddle.net/y0d1or6h/
Upvotes: 1
Reputation: 1
You can use existing pattern at Question, then utilize .slice()
, .wrapAll()
, .parent()
, .wrap()
, recursion. Create two variables defined as 0
, 10
respectively, increment variables by 10
within recursive call to function, if greatest variable is less than or equal to total #ticket-test li
.length
var tickets = $("#ticket-test li");
function wrapListItems (el, num, i = 0, n = num) {
if (n <= tickets.length) {
el.slice(i, n).wrapAll("<ul>").parent().wrap("<li>");
i += num;
n += num;
wrapListItems(el, num, i, n);
}
};
wrapListItems(tickets, 10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<ul id="ticket-test">
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
<li>001 Location</li>
</ul>
Upvotes: 0
Reputation: 535
var counter = 2;//change to whatever u need
var mainHtmlElement = $('#ticket-test');
var htmlElement;
$('xml').find('ticket').each(function(index){
if(index % counter == 0) {
htmlElement = $('<ul class="level_2"></ul>');
var el_li = $('<li class="level_1"></li>');
htmlElement.appendTo(el_li);
el_li.appendTo(mainHtmlElement);
}
var varTicket = $(this).find('ticketnumber').text();
var varLocation = $(this).find('location').text();
htmlElement.append('<li class="level_2">'+varTicket+' '+varLocation+'</li>');
});
Upvotes: 0
Reputation: 11502
Please check this approach:
$(document).ready(function() {
var xmlString =
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
'<area>' +
'<ticket>' +
'<ticketnumber>001</ticketnumber>' +
'<location>Location</location>' +
'</ticket>' +
'<ticket>' +
'<ticketnumber>002</ticketnumber>' +
'<location>Location</location>' +
'</ticket>' +
'<ticket>' +
'<ticketnumber>003</ticketnumber>' +
'<location>Location</location>' +
'</ticket>' +
'<ticket>' +
'<ticketnumber>004</ticketnumber>' +
'<location>Location</location>' +
'</ticket>' +
'<ticket>' +
'<ticketnumber>005</ticketnumber>' +
'<location>Location</location>' +
'</ticket>' +
'<ticket>' +
'<ticketnumber>006</ticketnumber>' +
'<location>Location</location>' +
'</ticket>' +
'</area>';
var xmlDoc = jQuery.parseXML(xmlString);
var tempUL = $('<ul></ul>'); //creating a temp ul tag
$(xmlDoc).find('ticket').each(function() {
var varTicket = $(this).find('ticketnumber').text();
var varLocation = $(this).find('location').text();
var varTheHTML = '<li>' + varTicket + ' ' + varLocation + '</li>';
tempUL.append(varTheHTML)
});
//change below number as per your requirement
var numberOfLi = 3;
while (1) {
var liSet = tempUL.find("li:lt(" + numberOfLi + ")").detach(); //detaching the set of li to make new ul
var newUL = $("<ul></ul>").append(liSet);
var topLI = $("<li></li>").append(newUL);
topLI.appendTo("#ticket-test");
if (tempUL.find("li").length == 0)
break;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
my list
<ul id="ticket-test"></ul>
Upvotes: 0