6

Sorry for being long and thank you very much for your usual time and guidance.

I have a div of unknown dimensions; in fact, its width and height are set using percentages so the final values in pixels depend on the window innerWidth an innerHeight properties.

I need to create an ajax pagination inside that div. In other words, I have two child div s (figure below). The second one is for pagination links. The first one is responsible of holding items (aligned horizontally and vertically). It will be (automatically) of unknown width . As a result, the number of items inside depend on its final width and height because all items have a fixed known width and hieght (Let's say 80 pixels width and 50 pixels height).

I hope the following figure is illustrating my issue in the best manner: enter image description here

The goal is to find a good approach to find the values of X and Y.

  • X= number of items per row
  • Y= the number of items per column

These two values will help finding the number of items per page (to be used server side for pagination). Pagination links will be created by dividing the total number of pages by this value. Note: Everything is done with ajax.

What I am planning to do:

  • create a javascript function calculate_viewport() to be the first thing to execute before any other thing parsed/exectued.
  • create a javascript function that calculates X and Y values based on values returned by calculate_viewport().
  • use the X and Y for an ajax call that request a certain page.

    <script type="text/javascript">
    
    function calculate_viewport() {
        var width_and_height_object;
        // calcluate width and height using of current window.innerWidth  and window.innerHeight
        // put values in an object width_and_height_object
        return width_and_height_object; }
    
    function calculate_XandY(width_and_height_object) {
        var XandY_object;
        // calcluate X and Y values by perfoming necessary division operations
        return XandY_object; }
    
    var XandY = calculate_XandY(viewport()); </script>
    
    <!DOCTYPE html> <html>
        <head>
        </head>
        <body>
            <div id="parent" style="height: 70%; width: 50%">
                <div id="items_container" style="height: calc(100% - 30px); width: 100%"></div>
                <div id="pagination" style="height: 30px; width: 100%">></div>
            </div>
        </body>
        <script src="jquery.js"></script>
        <script type="text/javascript">
                $('a.next a.previous').click(function(e){
                     e.preventDefault();         
                     $.ajax({
                        type: "GET",
                        url: url_to_page_of_items,
                        data: { number_of_items_per_page : X_times_Y },
                        cache: false, 
                        success: callback // append result to items container div 
                     });        
               return false;
            });
        </script> </html>
    

What do you think about this approach? Are there any other better ways to achieve this goal? Is it acceptable to create a <script> tag before the <html> tag just to make early window size calculation?

N.B: For the server side part, I manage to paginate results via some functions offered by the ORM library I am using. I use a server-side template engine that renders a page of items as HTML. I am ready to provide any code upon request for this part. Thanks

Adib Aroui
  • 4,981
  • 5
  • 42
  • 94

1 Answers1

2

You'll never get the layout math right on your own. My recommendation is to lay out all of the items before hand (flex box is ideal here!), get the count, and then fill them in using ajax.

Here's a quick demo I whipped up. The actual JS is pretty simple, using jQuery.

var MARGIN = 10; //This should match your CSS

var itemContainerHeight = $(".foo").height();
var count = 0;

$(".item").each(function () {
  if ($(this).position().top + $(this).height() + MARGIN > itemContainerHeight) {
    $(this).hide();
  } else {
    count++;
  }
});

$('.pagination').text("I can display "+count+" items!");

The important line is the one containing .position(). That'll get the location of each of the items top edge, add the height to find their bottom edge, and check if it's past the bounds of the item container.

After this you can just use the count to query the necessary items from the server. I'd also recommend using visbility: hidden; on all of the items so the user doesn't see them before they're ready.

Jack Guy
  • 8,346
  • 8
  • 55
  • 86
  • Thank you for your time. If I understand you well, you are suggesting a maximum intial number of items and setting visibility to hidden using the js you provided then using the count for the next pages to request only the necessary number of items in each page. right? A note about flexbox, it is not supported in IE8 and 9, and has only partial support for 10 and 11 which is a hurdle for me. `display:table`+ `table-layout:fixed` has better browser support (for info) – Adib Aroui Feb 23 '16 at 00:31
  • @whitelettersinblankpapers Yep! That would be my approach anyway. The problem is interesting to me though, because if a user resized their window the layout would break pretty quickly- I'd usually chose a fixed-item layout in your situation. You can use flebox in ie8 and 9, you'll just have to make use of a [polyfill](https://github.com/10up/flexibility) – Jack Guy Feb 23 '16 at 01:24
  • 1
    I will be using your answer (with flexbox thanks to my fascination after reading a guide about it, of course I will be using the polyfill). About resizing, I am not taking it into account in my project for the moment, but when I will reach this step in the future I will be sending a comment here to share my thoughts. Thanks a lot for this and have a nice day – Adib Aroui Feb 24 '16 at 00:24