3

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.

2
  • Is second nested <ul> duplicate of first nested <ul>? Commented Sep 21, 2016 at 5:38
  • Not a duplicate (sorry, it's not clear in the description), the first nested list is the first 10 items in the xml, the second list is the next 10 items in the list, and so on. Commented Sep 21, 2016 at 6:32

4 Answers 4

1

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/

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks for the answer :) The code appears to stall at: if(i%10 == 0 ){ html+='<li><ul>'}
what do you mean by stall at?
Sorry, will clarify. If i run as-is noting will be appended to #ticket-test. If i remove the following, the script will run: ` if(i%10 == 0 ) { html+='<li><ul>'; } html+= '<li>'+varTicket+' '+varLocation+'</li>'; if(i%10 == 0 ) { html+='</ul></li>'; }`
Genius! Works like a charm!
Thanks also for the other responses, I unfortunately did not have time to review, however I do hope they help others with the same problem in the future. Thanks everyone!
|
0

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>

Comments

0
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>');
});

Comments

0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.