views:

305

answers:

4

I am interested in using jQuery to create automatic pagination for content based on the height of the content and the div, rather than by number of items. Most pagination examples I have been able to find are based on the number of items to be paginated, rather than the height of the containing div and the height of the contents. This solution does not work well with content of varying length.

Do anyone know of an existing solution that will paginate content based on height rather than item number? Ideally it would be a solution that would split content within a tag, such as a long paragraph across multiple pages.

I have included some dummy code below. Alternatively, the code can be accessed here: Example, Code


<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
<style type="text/css" media="screen">
body {background-color:white; font:16px Helvetica, Arial; color:black;}
.pagination {margin:auto; display:block; height:275px; width:300px; position:relative; overflow:hidden; border:1px solid black;}
</style>
</head>
<body>
<div class="pagination">
  <p>The House of Representatives shall be composed of Members chosen every second Year by the People of the several States, and the Electors in each State shall have the Qualifications requisite for Electors of the most numerous Branch of the State Legislature.</p>
  <p>No Person shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State in which he shall be chosen.</p>
  <p>(Representatives and direct Taxes shall be apportioned among the several States which may be included within this Union, according to their respective Numbers, which shall be determined by adding to the whole Number of free Persons, including those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of all other Persons.) (The previous sentence in parentheses was modified by the 14th Amendment, section 2.) The actual Enumeration shall be made within three Years after the first Meeting of the Congress of the United States, and within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode Island and Providence Plantations one, Connecticut five, New York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five and Georgia three.</p>
  <p>When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies.</p>
  <p>The House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of Impeachment.</p>
</div>
<ul>
    <li>Previous</li>
    <li>Next</li>
</body>
</html>
A: 

Sounds to me like you just need to implement $.scrollTo(): I just worked-up the following concept using a single "Advance Forward" button (Note: You must have jQuery and the scrollTo plugin referenced:

<button class="next">Next</button>
<div id="pagination">
  <p>The House of Representatives shall be composed of Members chosen every second Year by the People of the several States, and the Electors in each State shall have the Qualifications requisite for Electors of the most numerous Branch of the State Legislature.</p>
  <p>No Person shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State in which he shall be chosen.</p>
  <p>(Representatives and direct Taxes shall be apportioned among the several States which may be included within this Union, according to their respective Numbers, which shall be determined by adding to the whole Number of free Persons, including those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of all other Persons.) (The previous sentence in parentheses was modified by the 14th Amendment, section 2.) The actual Enumeration shall be made within three Years after the first Meeting of the Congress of the United States, and within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode Island and Providence Plantations one, Connecticut five, New York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five and Georgia three.</p>
  <p>When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies.</p>
  <p>The House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of Impeachment.</p>
</div>

--

var numElmnts = $("#pagination p").length;
var lastIndex = 0;
$(".next").click(function(){
  var nextIndex = (lastIndex >= (numElmnts-1)) ? 0 : (lastIndex+1) ;
  var nextParag = $("#pagination p:eq("+nextIndex+")");
  $("#pagination").animate({ height: $(nextParag).outerHeight() }, 800, "linear", function(){
    $("#pagination").scrollTo(nextParag, 800);
  });
  lastIndex = nextIndex;
});
Jonathan Sampson
A: 

I don't know of an existing solution. However with some JavaScript (using something like jQuery) you can compute the height of an element. $(element).height() for example. Using this method you could iterate through a loop of elements and add them to a div depending on the available room left (set as a constant I guess). So if I have 3 elements and my available height is 100 px and jQuery returns a height of 35 px for each element I'd show the first two and then add the last to a queue to be shown when the user clicks next.

It'd be a little harder to split the text in mid-element but I suppose you could use string parsing to cut the text of the element in half, measure height, cut in half again, measure height etc. It wouldn't be pretty, but it'd probably work.

Jeremy Bandini
+2  A: 

It sounds like you want to load all the content at once, but only show a little bit of it at a time to the user. Paginating HTML content server side isn't really feasible, and wouldn't have anything to do with jQuery in any case.

Good UX would be to just use a scroll bar instead of trying to reinvent page up/down. That said, if you absolutely must do this, then you want something like this:

$('.pagination').children().wrapAll('<div class="content"/>');
$('.next').click(function() {
    var current = ($('.content').css('margin-top') || '0px');
    $('.content').css('margin-top',current.substring(0,current.length-2) - $('.pagination').height() + 'px');
});

The basic idea is to keep the pagination div that you have with overflow: hidden and move the content inside of it up and down using negative margins.

One more time though, this is bad UX. Just use a scrollbar.

noah
I agree that scrolling this was is bad design, but the specification is outside of my control. Thank you for your help with this.
the3seashells
To get this to work with IE6, I needed to add a check for a margin value of "auto" I addressed it with this:if (current == 'auto') { current = '0px';}
the3seashells
A: 

Look at this jQuery plugin: http://rascarlito.free.fr/hoverscroll/

Dumitru