Monday 7 April 2014

Simple pagination plugin for Twitter Bootstrap

Let's say you have content in a Twitter Bootstrap web page and you want to paginate through it. If you've ever tried looking for examples on doing this, you would know that very few of them contain content. Or in other words the examples contain all the numbers at the bottom but none of the content at the top and how to paginate through it.
I then found plugins which looked very clever, but didn't actually work.
So I have created a jQuery plugin (which works) and an example of how it could be used.
First the HTML page which I took form getbootstrap.com, then added the necessary code for the pagination which I highlight below.
Actually, it works for any site which uses jQuery. Another strength to this simplified method is that you can name the content IDs whatever you like and the plugin with still pick them up as labels.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap 101 Template</title>

    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <style>
    body
    {
      padding-top:2em;
    }
    #mickspagination #navigation a
    {
      background:#e5e5e5;
      margin:0.1em;
      padding:0.5em;
    }
    </style>
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="row">
      <div class="container">
        <div class="col-md-12">
          <div id="mickspagination">
            <div id="content">
              <div id="1" class="active">
                <p>Content for 1</p>
              </div>
              <div id="2">
                <p>Content for 2</p>
              </div>
              <div id="3">
                <p>Content for 3</p>
              </div>
              <div id="4">
                <p>Content for 4</p>
              </div>
            </div>
            <div id="navigation"></div>
          </div>
        </div>
      </div>
    </div>  
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>
    <script src="pagination.plugin.js"></script>
    <script>
    (function()
    {
      $('#mickspagination').pagination();
    })();
    </script>
  </body>
</html>

Now the jQuery plugin contained in pagination.plugin.js

(function($)
{
    $.fn.extend(
    {
        pagination:function(options)
        {
            var defaults = 
            {
                showarrows:false,                
                classesext:null,
                alignment:'center',
                navigationtag:'#navigation'
            }

            var options = $.extend(defaults, options);

            return this.each(function() 
            {
                var o = options;                

                var content = $(this).find('#content');
                var contentDivs = content.find(' > div');
                var firstDiv = content.children().first();
                var lastDiv = content.children().last();    
                var leftDiv = content.children().first();    
                var rightDiv = content.children().eq(1);
                var leftArrow, rightArrow;
                var activeDiv  = content.find('.active');
                var navigation = null;
                var contentArr = Array();

                contentDivs.not('.active').hide();

                /* Provide option for navigation outside the pagination */
                if(o.navigationtag == '#navigation')
                {
                  navigation = $(this).find('#navigation');
                }
                else
                {

                  navigation = $(document).find(o.navigationtag);
                }

                /* Show the first arrows */
                if(o.showarrows == true)
                {
                  link = $(this).arrowlink(firstDiv.attr('id').replace(/ /g,''),'«', o.classesext);
                  navigation.append(link);
                  link = $(this).arrowlink(leftDiv.attr('id'),'<', o.classesext);
                  navigation.append(link);                  
                  leftArrow = navigation.find("a:contains('<')"); 
                }    

                /* Show all the pagination navigation */
                contentDivs.each(function()
                {
                  encodedID = $(this).attr('id').replace(/ /g,'');
                  $(this).attr('title', $(this).attr('id'));                  
                  $(this).attr('id', encodedID);                  
                  contentArr.push($(this).attr('id'));
                  link = $(this).buildlink(o.classesext);
                  navigation.append(link);
                });

                /* Show the last arrows */
                if(o.showarrows == true)
                {
                  link = $(this).arrowlink(rightDiv.attr('id'),'>', o.classesext);
                  navigation.append(link);
                  link = $(this).arrowlink(lastDiv.attr('id'),'»', o.classesext);
                  navigation.append(link);                  
                  rightArrow = navigation.find("a:contains('>')");                  
                }

                /* Centre the pagination navigation. May wish to set this as an option */
                navigation.css('text-align',o.alignment);

                /* Handle what happens when someone clicks on a navigation link */
                $(navigation).on('click', 'a', function()
                {
                  /* Make the currently clicked ID the active one */
                  activeDiv  = content.find('.active');
                  activeDiv.removeClass('active');
                  currentID = $(this).attr('href');
                  newActiveDiv = content.find(' > div'+currentID);
                  newActiveDiv.addClass('active');

                  /* Change what the arrows now point at */
                  if(o.showarrows == true)
                  {
                    leftArrow.updateleftlink(newActiveDiv, contentArr);
                    rightArrow.updaterightlink(newActiveDiv, contentArr);
                  }

                  /* Show the newly selected content */
                  contentDivs.not('.active').hide();
                  newActiveDiv.show();      
                });
            });
        }
    }); /* End of pagination plugin. Other function may go below this */

    /* Create the pagination navigation links */    
    $.fn.buildlink = function(classesext)
    {
        var ct = $.trim(classesext);
        link = '<a href="#';
        link += $(this).attr('id')+'"';        
        if(classesext !== null)
        {
            link += ' class="'+ct+'"';
        }
        link += '>';        
        link += $(this).attr('title');
        link += '</a>';
        return link;
    };

    $.fn.arrowlink = function(dynamicloc, linkchar, classesext)
    {
        var ct = $.trim(classesext);
        link = '<a href="#';        
        link += dynamicloc+'"';        
        link += ' class="pagarrow';
        if(classesext !== null)
        {
            link += ' '+ct;
        }        
        link += '">';
        link += linkchar;
        link += '</a>';
        return link;
    };

    /* Update the first arrow link */
    $.fn.updateleftlink = function(ad,cr)
    {
        var ov = 0;
        var hrefstring = '#';
        var ap = cr.indexOf(ad.attr('id'));
        if((ap-1) <= 0)
        {
            ov = 0;
        }
        else
        {
            ov = (ap-1);
        }
        hrefstring += cr[ov];
        $(this).attr('href',hrefstring);    
    };

    $.fn.updaterightlink = function(ad,cr)
    {
        var ov = 0;
        var hrefstring = '#';
        var ap = cr.indexOf(ad.attr('id'));    
        if((ap+1) >= cr.length)
        {
            ov = cr.length-1;      
        }
        else
        {
            ov = (ap+1);
        }
        hrefstring += cr[ov];    
        $(this).attr('href',hrefstring);    
    };

})(jQuery);

No comments:

Post a Comment