views:

43

answers:

2

Hello everyone! I am having a spot of trouble trying to paginate some results from an XML file via jQuery, basically I need to display 10 Magazine covers and when the user either click previous or next another 10 are shown, respective of what has been clicked. Here is my code:

 $(document).ready(function() {

 $.ajax({
    type: "GET",
    url: "issues.xml",
    dataType: "xml",
    success: function(xml) {

                var startIndex = 0; // gets edited via ui
                var howMany = 10; // constant of how many per page, but you could make this a ui changeable thing too
                var $issues = $(xml).find('issue'); //the resulting issues from the xml
                var totalIssues = $issues.length;
    var numPages = Math.ceil(totalIssues / howMany)

    $('span.issuecount').html(+totalIssues+' Issues - '+numPages+' Pages');

                var displayIssues = function() { // display the issues
                      var $issuesPaginated = $issues.slice( startIndex , ($issues.length - startIndex) + howMany );
                      $('#shelf-items li').fadeOut(500); // clear old issues
                      $issuesPaginated.each(function(){
                          var id = $(this).attr('id');
                          var date = $(this).find('date').text();
                          var cover = $(this).find('cover').text();
                          var issue = $(this).find('issuenumber').text();
                          var url = $(this).find('url').text();
                          $('<li id="'+id+'"></li>').html('<a href="'+url+'"><img src="images/covers/'+cover+'" alt="" /></a><br />'+date+' - #'+issue+'').fadeIn(500).appendTo('#shelf-items');
                      });
                }

                $('#prevIssueButton').click(function() {
                    if( startIndex < howMany) {
                        startIndex -= howMany;
                        displayIssues().fadeIn(500);
                    }else {
                        alert('No more previous issues'); // probably want to do something more elegant here, like start over at 0, etc..
                    }
                });
                $('#nextIssueButton').click(function() {
      if( startIndex + howMany >= totalIssues) {
                        startIndex += howMany;
                        displayIssues();
                    }else {
                        alert('No more next issues'); // probably want to do something more elegant here, like start over at 0, etc..
                    }
                });
                displayIssues().fadeIn(500); // display for the first time (ajax call);
            }
   }); // end ajax call

}); // end document-ready

edit: there is now also a Javascript error on displayIssues().fadeIn(500);

+1  A: 
  $(xml).find('issue').each(function(){

can become: (using .slice() )

  var startIndex = 0; //edit this via your ui
  var howMany = 10; 
  var $issues = $(xml).find('issue');
  var $issuesPaginated = $issues.slice( startIndex , ($issues.length - startIndex) + howMany );
  $issuesPaginated.each(function(){

Are you using anything server-side? Could you facilitate pagination that way so you aren't loading all that data into the DOM?

for the requested help regarding click handlers:

$(document).ready(function() {

 $.ajax({
    type: "GET",
    url: "issues.xml",
    dataType: "xml",
    success: function(xml) {

                var startIndex = 0; // gets edited via ui
                var howMany = 10; // constant of how many per page, but you could make this a ui changeable thing too
                var $issues = $(xml).find('issue'); //the resulting issues from the xml
                var totalIssues = $issues.length;

                var displayIssues = function() { // display the issues
                      var $issuesPaginated = $issues.slice( startIndex , ($issues.length - startIndex) + howMany );
                      $('#shelf-items').html(''); // clear old issues
                      $issuesPaginated.each(function(){
                          var id = $(this).attr('id');
                          var date = $(this).find('date').text();
                          var cover = $(this).find('cover').text();
                          var issue = $(this).find('issuenumber').text();
                          var url = $(this).find('url').text();
                          $('<li id="'+id+'"></li>').html('<a href="'+url+'"><img src="images/covers/'+cover+'" alt="" /></a><br />'+date+' - #'+issue+'').appendTo('#shelf-items');
                      });
                }

                $('#prevIssueButton').click(function() {
                    if( startIndex < howMany) {
                        startIndex -= howMany;
                        displayIssues();
                    }else {
                        alert('No more previous issues'); // probably want to do something more elegant here, like start over at 0, etc..
                    }
                });
                $('#nextIssueButton').click(function() {
                    if( startIndex + howMany >= totalIssues) {
                        startIndex += howMany;
                        displayIssues();
                    }else {
                        alert('No more next issues'); // probably want to do something more elegant here, like start over at 0, etc..
                    }
                });
                displayIssues(); // display for the first time (ajax call);
            }
   }); // end ajax call

}); // end document-ready
Dan Heberden
Hi Dan, unfortunatly that hasnt worked. It now shows up blank, also how can I control the pages with the next / previous links?
Nathan Fitzgerald
yeah, made a quick edit - it the splice method needed to become a jquery object again. But better yet, I used the `.slice()` method and put the math in for you
Dan Heberden
There is only going to be a small amount of data contained in the XML file, this is not for public viewing, strictly for private clients - so the DOM load is irrelevant.That works brilliantly Dan, your help is much appreciated! I just need to know how I can attatch Prev+Next page actions to those buttons I have setup?
Nathan Fitzgerald
I would make your startIndex, resulting $issues and the total $issues in a variable inside of `$(document).ready()` but outside of the ajax call. Then still inside `$(document).ready()`, you can bind your click events to the prev/next buttons and change your startIndex, redisplay the elements, limit based off of the total elements (e.g. disabled the next button when at the end)..
Dan Heberden
Sorry Dan, bit of jQuery noob as you can probably tell, I have no idea to write out those variables, I will be able to do the click functions, could you help me out? Please? :)
Nathan Fitzgerald
a bit of a crude example, but hopefully this gets you going in the right direction (see answer)
Dan Heberden
See updated example, the previous button goes to the back of the results from page 1, but the next button does not work? This has baffled me also when i change the conditonal for next to startIndex + howMany <= totalIssues - it loads page 2 but not 3 :/
Nathan Fitzgerald
http://www.ipixelmedia.net/template.html - for live working example
Nathan Fitzgerald
A: 

I usually deal with large datasets spanning multiple pages, so I include index parameters to my AJAX call. (Which also requires something smart on the server side...) In you case it looks like you're calling a static xml file, in which case I'd ditch the AJAX or have the AJAX dump the results into a variable which you can iterate over at your leisure and under your control.

Quotidian