tags:

views:

380

answers:

6

Hello!

I'm a bit new to the jquery world and I was wondering: I have a JSON object that returns content from a database. How would I loop through those items to display only six per ul with each item being appended within that ul in a li, then construct a new ul every six items to display the remaining items in a li? Basically I'm trying to to this:

  • item 1
  • item 2
  • item 3
  • item 4
  • item 5
  • item 6
  • item 7
  • item 8
  • item 9
  • item 10
  • item 11
  • item 12

etc...

+1  A: 
function buildLists(data, element) {

    var count = parseInt((data.length / 6) + (data.length % 6 == 0 ? 0 : 1), 10),
        html = "";

    for (var i = 0; i < count; i++) {
        html += "<ul>";
        for (var j = i; j < (6 + (6 * i)); j++) {
            html += "<li>" + data[j] + "</li>";
        }
        html += "</ul>";
    }

    element.append(html);
}
ChaosPandion
A: 

My answer will be mostly core JavaScript.

    $(function() { //execute when DOM is ready
    var lists = '<ul>'; //start off list
    var nums = new Array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20'); //add a few items to an array for demo

    var i = 1; //1-based count for "every six"
    var j = 0; //0-based count for array keys
    while (i <= nums.length){
       if(i%6 == 0){ //check if number is a multiple of 6
        if(i != nums.length){ 
      lists += '<li>'+nums[j]+'</li></ul><ul>';  
        }else{ //if this is the last array value, don't start a new ul
         lists += '<li>'+nums[j]+'</li></ul>';  
        }
       }else {
        lists += '<li>'+nums[j]+'</li>';   
       }
       i++; //go to next number
       j++; //go to next number
   }


      $('body').append(lists); //ad uls to page
    });
Murrieta Web Design
A: 

This uses an array, but should get you pointed in the right direction.

var items = [1,2,3,4,5,6,7,8,9,10,11,12,13];
var ul = $("<ul></ul>");
for(var i = 0; i < items.length; i++) {
  if(i % 6 == 0 && i > 0) {    
    console.log(ul.html()); // change this line - insert into the DOM wherever you'd like
    ul = $("<ul></ul>");
  }
  ul.append("<li>" + i + "</li>");
}
Andy Gaskell
A: 

Came up with a solution using jQuery's ".each" function. The core code to do the loop and list creation is pretty small. Note: this is assuming the return JSON object has nested data.

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">
$(function(){
    var data = 
    [
     {value: 1},{value: 2},{value: 3},{value: 4},{value: 5},{value: 6},
     {value: 7},{value: 8},{value: 9},{value: 10},{value: 11},{value: 12},
     {value: 13},{value: 14},{value: 15},{value: 16},{value: 17},{value: 18}
    ];

    var $listReference;
    $.each(data, function(i, item) {
     if(i == 0 || (i) % 6 == 0){
      $listReference = $("<ul>");
      $("body").append($listReference);
     }
     $listReference.append($("<li>").text(item.value));
    });
});
</script>
</head>
<body>

</body>
</html>
WesleyJohnson
A: 

I would recommend practicing unobtrusive Javascript. One of the key principles is separating markup from design; you want to break the view into blocks of 6, but the data your representing is still a long, continuous, list. If you create multiple lists to represent this, it would be misleading to any scripts trying to make sense of the content on your page, or specialised clients like screenreaders.

Thus, I would create a single list, and use CSS to make it appear as multiple blocks.

CSS:

  .newBlock { margin-top: 1em; }

Javascript:

var records = 
[ {name: "a"},{name: "b"},{name: "c"},{name: "d"},{name: "e"},{name: "f"},
  {name: "g"},{name: "h"},{name: "i"},{name: "j"},{name: "k"},{name: "l"},
  {name: "m"},{name: "n"},{name: "o"},{name: "p"},{name: "q"},{name: "r"}
]; // sample data, adapted from WesleyJohnson's example
var $ul = $("<ul/>").appendTo("body");
$.each(records, function(count, record) {
  var $li = $("<li/>").html(record.name).appendTo($ul);
  if (count % 6 == 0) $li.addClass("newBlock");
});

online demo

mahemoff
Hello mahemoff! I tried out your solution and came REALLY close but for some reason, it only displays the first item of the six only which is strange. It's a bit modified from your original code but the same structure. Is there any way I can send you what I have?
loganlee
Should work - did you see the linked demo btw? I'd try getting rid of the CSS and you should just see the long list.You can send it to [email protected] or put it on a pastebin and link here, thanks.
mahemoff
A: 

Thank you everyone! I tried everyone's suggestion but I'm still coming up short for some reason. Below is what I currently have and I left out a part of what I'm trying to accomplish. I do need a new ul block for every 6th iteration but I also need a new div block (scroll_controls) with it. This is what I have so far:

$(function proName(){

$.getJSON("http://content.ftpokeracademy.net/searchwidget/pros", function(data) {

 /* Parse JSON objects */

 jJSON["pro_name"] = (function() {
  response = {
   values: [],
   count: 0
  };
  $.each(data,function(i,item){
   if (item.pro_name != "undefined") {
    response.count++;
    response.values[i] = item.pro_name;
    var proName = item.pro_name;
    var addProName = proName + ", ";
    /* append li to ul block */
    proNameLink = $('<li><a class="pro-name-link'+i+'" href="#">'+proName+'</a></li>');
    var $ul = $("<ul/>").appendTo('#scroll_controls');
    var $li = $("<li/>").html(pro_name).appendTo($ul);
    if (count % 6 == 0) 
     $li.addClass("newBlock");
     //alert("more than 6");
     //return false;
    $('#pro-name-results').append(proNameLink);
    /* disable link after click */
    proNameLink.bind("click", function() {
     $('.pro-name-link'+i+'').removeAttr('href');
     $('.pro-name-link'+i+'').css('color', '#ffffff');
     $('.added-search-terms').append(addProName);
     $('.pro-name-link'+i+'').unbind('click');
    });
   }
  });
  return response;
 })();

 /* Return a number of values for a given object */

 //alert( jJSON.getValues("pro_name",null) );
});

});

var jJSON = { getValues: function(obj,num) { return jJSON[obj]["values"].slice(0,((num == null) ? jJSON[obj]["values"].length : num)); }, getCount: function(obj) { return jJSON[obj]["count"]; } };

and the HTML:

<body>
<div id="wn">
  <div id="lyr" class="content"><span class="search-terms-title">Search Terms: <span class="added-search-terms"></span></span></div>
</div>
<div id="scroll_controls" class="hasImage">
    <ul id="pro-name-results">

    </ul>
</div>

What am I missing? What I want is a new "scroll_controls" div and a nested "pro-name-results" ul block for every 6th iteration with the li nested in the new ul.

Thank you all for the suggestions! It's much appreciated!

loganlee
A few comments/questions... 1) What's the structure of the JSON url? (it requires authentication)2) What's 'count' in '...if(count % 6...'? Did you mean response.count?3) 'function proName(){' should be 'function (){' (it's an anonymous function)4) jQuery searches the DOM every time you call $('.pro-name-link'+i+''). Store this in a variable and call that.5) $('.pro-name-link'+i+'') should be $('.pro-name-link'+i)
Bill Zeller
(sorry, the site removed the newlines in my comment)
Bill Zeller
Thanks Bill...I figured it out actually...I put the proNameLink inside of the if statement which is why I only got the first result of the six. Thanks for your suggestions, help out a lot!
loganlee