| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566 |  /** * jQuery jPages v0.7 * Client side pagination with jQuery * http://luis-almeida.github.com/jPages * * Licensed under the MIT license. * Copyright 2012 Luís Almeida * https://github.com/luis-almeida */;(function($, window, document, undefined) {  var name = "jPages",      instance = null,      defaults = {        containerID: "",        first: false,        previous: "← previous",        next: "next →",        last: false,        links: "numeric", // blank || title        startPage: 1,        perPage: 10,        midRange: 5,        startRange: 1,        endRange: 1,        keyBrowse: false,        scrollBrowse: false,        pause: 0,        clickStop: false,        delay: 50,        direction: "forward", // backwards || auto || random ||        animation: "", // http://daneden.me/animate/ - any entrance animations        fallback: 400,        minHeight: true,        callback: undefined // function( pages, items ) { }      };  function Plugin(element, options) {    this.options = $.extend({}, defaults, options);    this._container = $("#" + this.options.containerID);    if (!this._container.length) return;    this.jQwindow = $(window);    this.jQdocument = $(document);    this._holder = $(element);    this._nav = {};    this._first = $(this.options.first);    this._previous = $(this.options.previous);    this._next = $(this.options.next);    this._last = $(this.options.last);    /* only visible items! */    this._items = this._container.children(":visible");    this._itemsShowing = $([]);    this._itemsHiding = $([]);    this._numPages = Math.ceil(this._items.length / this.options.perPage);    this._currentPageNum = this.options.startPage;    this._clicked = false;    this._cssAnimSupport = this.getCSSAnimationSupport();    this.init();  }  Plugin.prototype = {    constructor : Plugin,    getCSSAnimationSupport : function() {      var animation = false,          animationstring = 'animation',          keyframeprefix = '',          domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),          pfx = '',          elm = this._container.get(0);      if (elm.style.animationName) animation = true;      if (animation === false) {        for (var i = 0; i < domPrefixes.length; i++) {          if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) {            pfx = domPrefixes[i];            animationstring = pfx + 'Animation';            keyframeprefix = '-' + pfx.toLowerCase() + '-';            animation = true;            break;          }        }      }      return animation;    },    init : function() {      this.setStyles();      this.setNav();      this.paginate(this._currentPageNum);      this.setMinHeight();    },    setStyles : function() {      var requiredStyles = "<style>" +      ".jp-invisible { visibility: hidden !important; } " +      ".jp-hidden { display: none !important; }" +      "</style>";      $(requiredStyles).appendTo("head");      if (this._cssAnimSupport && this.options.animation.length)        this._items.addClass("animated jp-hidden");      else this._items.hide();    },    setNav : function() {      var navhtml = this.writeNav();      this._holder.each(this.bind(function(index, element) {        var holder = $(element);        holder.html(navhtml);        this.cacheNavElements(holder, index);        this.bindNavHandlers(index);        this.disableNavSelection(element);      }, this));      if (this.options.keyBrowse) this.bindNavKeyBrowse();      if (this.options.scrollBrowse) this.bindNavScrollBrowse();    },    writeNav : function() {      var i = 1, navhtml;      navhtml = this.writeBtn("first") + this.writeBtn("previous");      for (; i <= this._numPages; i++) {        if (i === 1 && this.options.startRange === 0) navhtml += "<span>...</span>";        if (i > this.options.startRange && i <= this._numPages - this.options.endRange)          navhtml += "<a href='#' class='jp-hidden'>";        else          navhtml += "<a>";        switch (this.options.links) {          case "numeric":            navhtml += i;            break;          case "blank":            break;          case "title":            var title = this._items.eq(i - 1).attr("data-title");            navhtml += title !== undefined ? title : "";            break;        }        navhtml += "</a>";        if (i === this.options.startRange || i === this._numPages - this.options.endRange)          navhtml += "<span>...</span>";      }      navhtml += this.writeBtn("next") + this.writeBtn("last") + "</div>";      return navhtml;    },    writeBtn : function(which) {      return this.options[which] !== false && !$(this["_" + which]).length ?      "<a class='jp-" + which + "'>" + this.options[which] + "</a>" : "";    },    cacheNavElements : function(holder, index) {      this._nav[index] = {};      this._nav[index].holder = holder;      this._nav[index].first = this._first.length ? this._first : this._nav[index].holder.find("a.jp-first");      this._nav[index].previous = this._previous.length ? this._previous : this._nav[index].holder.find("a.jp-previous");      this._nav[index].next = this._next.length ? this._next : this._nav[index].holder.find("a.jp-next");      this._nav[index].last = this._last.length ? this._last : this._nav[index].holder.find("a.jp-last");      this._nav[index].fstBreak = this._nav[index].holder.find("span:first");      this._nav[index].lstBreak = this._nav[index].holder.find("span:last");      this._nav[index].pages = this._nav[index].holder.find("a").not(".jp-first, .jp-previous, .jp-next, .jp-last");      this._nav[index].permPages =        this._nav[index].pages.slice(0, this.options.startRange)          .add(this._nav[index].pages.slice(this._numPages - this.options.endRange, this._numPages));      this._nav[index].pagesShowing = $([]);      this._nav[index].currentPage = $([]);    },    bindNavHandlers : function(index) {      var nav = this._nav[index];      // default nav      nav.holder.bind("click.jPages", this.bind(function(evt) {        var newPage = this.getNewPage(nav, $(evt.target));        if (this.validNewPage(newPage)) {          this._clicked = true;          this.paginate(newPage);        }        evt.preventDefault();      }, this));      // custom first      if (this._first.length) {        this._first.bind("click.jPages", this.bind(function() {          if (this.validNewPage(1)) {            this._clicked = true;            this.paginate(1);          }        }, this));      }      // custom previous      if (this._previous.length) {        this._previous.bind("click.jPages", this.bind(function() {          var newPage = this._currentPageNum - 1;          if (this.validNewPage(newPage)) {            this._clicked = true;            this.paginate(newPage);          }        }, this));      }      // custom next      if (this._next.length) {        this._next.bind("click.jPages", this.bind(function() {          var newPage = this._currentPageNum + 1;          if (this.validNewPage(newPage)) {            this._clicked = true;            this.paginate(newPage);          }        }, this));      }      // custom last      if (this._last.length) {        this._last.bind("click.jPages", this.bind(function() {          if (this.validNewPage(this._numPages)) {            this._clicked = true;            this.paginate(this._numPages);          }        }, this));      }    },    disableNavSelection : function(element) {      if (typeof element.onselectstart != "undefined")        element.onselectstart = function() {          return false;        };      else if (typeof element.style.MozUserSelect != "undefined")        element.style.MozUserSelect = "none";      else        element.onmousedown = function() {          return false;        };    },    bindNavKeyBrowse : function() {      this.jQdocument.bind("keydown.jPages", this.bind(function(evt) {        var target = evt.target.nodeName.toLowerCase();        if (this.elemScrolledIntoView() && target !== "input" && target != "textarea") {          var newPage = this._currentPageNum;          if (evt.which == 37) newPage = this._currentPageNum - 1;          if (evt.which == 39) newPage = this._currentPageNum + 1;          if (this.validNewPage(newPage)) {            this._clicked = true;            this.paginate(newPage);          }        }      }, this));    },    elemScrolledIntoView : function() {      var docViewTop, docViewBottom, elemTop, elemBottom;      docViewTop = this.jQwindow.scrollTop();      docViewBottom = docViewTop + this.jQwindow.height();      elemTop = this._container.offset().top;      elemBottom = elemTop + this._container.height();      return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom));      // comment above and uncomment below if you want keyBrowse to happen      // only when container is completely visible in the page      /*return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom) &&                (elemBottom <= docViewBottom) &&  (elemTop >= docViewTop) );*/    },    bindNavScrollBrowse : function() {      this._container.bind("mousewheel.jPages DOMMouseScroll.jPages", this.bind(function(evt) {        var newPage = (evt.originalEvent.wheelDelta || -evt.originalEvent.detail) > 0 ?        (this._currentPageNum - 1) : (this._currentPageNum + 1);        if (this.validNewPage(newPage)) {          this._clicked = true;          this.paginate(newPage);        }        evt.preventDefault();        return false;      }, this));    },    getNewPage : function(nav, target) {      if (target.is(nav.currentPage)) return this._currentPageNum;      if (target.is(nav.pages)) return nav.pages.index(target) + 1;      if (target.is(nav.first)) return 1;      if (target.is(nav.last)) return this._numPages;      if (target.is(nav.previous)) return nav.pages.index(nav.currentPage);      if (target.is(nav.next)) return nav.pages.index(nav.currentPage) + 2;    },    validNewPage : function(newPage) {      return newPage !== this._currentPageNum && newPage > 0 && newPage <= this._numPages;    },    paginate : function(page) {      var itemRange, pageInterval;      itemRange = this.updateItems(page);      pageInterval = this.updatePages(page);      this._currentPageNum = page;      if ($.isFunction(this.options.callback))        this.callback(page, itemRange, pageInterval);      this.updatePause();    },    updateItems : function(page) {      var range = this.getItemRange(page);      this._itemsHiding = this._itemsShowing;      this._itemsShowing = this._items.slice(range.start, range.end);      if (this._cssAnimSupport && this.options.animation.length) this.cssAnimations(page);      else this.jQAnimations(page);      return range;    },    getItemRange : function(page) {      var range = {};      range.start = (page - 1) * this.options.perPage;      range.end = range.start + this.options.perPage;      if (range.end > this._items.length) range.end = this._items.length;      return range;    },    cssAnimations : function(page) {      clearInterval(this._delay);      this._itemsHiding        .removeClass(this.options.animation + " jp-invisible")        .addClass("jp-hidden");      this._itemsShowing        .removeClass("jp-hidden")        .addClass("jp-invisible");      this._itemsOriented = this.getDirectedItems(page);      this._index = 0;      this._delay = setInterval(this.bind(function() {        if (this._index === this._itemsOriented.length) clearInterval(this._delay);        else {          this._itemsOriented          .eq(this._index)          .removeClass("jp-invisible")          .addClass(this.options.animation);        }        this._index = this._index + 1;      }, this), this.options.delay);    },    jQAnimations : function(page) {      clearInterval(this._delay);      this._itemsHiding.addClass("jp-hidden");      this._itemsShowing.fadeTo(0, 0).removeClass("jp-hidden");      this._itemsOriented = this.getDirectedItems(page);      this._index = 0;      this._delay = setInterval(this.bind(function() {        if (this._index === this._itemsOriented.length) clearInterval(this._delay);        else {          this._itemsOriented          .eq(this._index)          .fadeTo(this.options.fallback, 1);        }        this._index = this._index + 1;      }, this), this.options.delay);    },    getDirectedItems : function(page) {      var itemsToShow;      switch (this.options.direction) {        case "backwards":          itemsToShow = $(this._itemsShowing.get().reverse());          break;        case "random":          itemsToShow = $(this._itemsShowing.get().sort(function() {            return (Math.round(Math.random()) - 0.5);          }));          break;        case "auto":          itemsToShow = page >= this._currentPageNum ?          this._itemsShowing : $(this._itemsShowing.get().reverse());          break;        default:          itemsToShow = this._itemsShowing;      }      return itemsToShow;    },    updatePages : function(page) {      var interval, index, nav;      interval = this.getInterval(page);      for (index in this._nav) {        if (this._nav.hasOwnProperty(index)) {          nav = this._nav[index];          this.updateBtns(nav, page);          this.updateCurrentPage(nav, page);          this.updatePagesShowing(nav, interval);          this.updateBreaks(nav, interval);        }      }      return interval;    },    getInterval : function(page) {      var neHalf, upperLimit, start, end;      neHalf = Math.ceil(this.options.midRange / 2);      upperLimit = this._numPages - this.options.midRange;      start = page > neHalf ? Math.max(Math.min(page - neHalf, upperLimit), 0) : 0;      end = page > neHalf ?        Math.min(page + neHalf - (this.options.midRange % 2 > 0 ? 1 : 0), this._numPages) :        Math.min(this.options.midRange, this._numPages);      return {start: start,end: end};    },    updateBtns : function(nav, page) {      if (page === 1) {        nav.first.addClass("jp-disabled");        nav.previous.addClass("jp-disabled");      }      if (page === this._numPages) {        nav.next.addClass("jp-disabled");        nav.last.addClass("jp-disabled");      }      if (this._currentPageNum === 1 && page > 1) {        nav.first.removeClass("jp-disabled");        nav.previous.removeClass("jp-disabled");      }      if (this._currentPageNum === this._numPages && page < this._numPages) {        nav.next.removeClass("jp-disabled");        nav.last.removeClass("jp-disabled");      }    },    updateCurrentPage : function(nav, page) {      nav.currentPage.removeClass("jp-current");      nav.currentPage = nav.pages.eq(page - 1).addClass("jp-current");    },    updatePagesShowing : function(nav, interval) {      var newRange = nav.pages.slice(interval.start, interval.end).not(nav.permPages);      nav.pagesShowing.not(newRange).addClass("jp-hidden");      newRange.not(nav.pagesShowing).removeClass("jp-hidden");      nav.pagesShowing = newRange;    },    updateBreaks : function(nav, interval) {      if (        interval.start > this.options.startRange ||        (this.options.startRange === 0 && interval.start > 0)      ) nav.fstBreak.removeClass("jp-hidden");      else nav.fstBreak.addClass("jp-hidden");      if (interval.end < this._numPages - this.options.endRange) nav.lstBreak.removeClass("jp-hidden");      else nav.lstBreak.addClass("jp-hidden");    },    callback : function(page, itemRange, pageInterval) {      var pages = {            current: page,            interval: pageInterval,            count: this._numPages          },          items = {            showing: this._itemsShowing,            oncoming: this._items.slice(itemRange.start + this.options.perPage, itemRange.end + this.options.perPage),            range: itemRange,            count: this._items.length          };      pages.interval.start = pages.interval.start + 1;      items.range.start = items.range.start + 1;      this.options.callback(pages, items);    },    updatePause : function() {      if (this.options.pause && this._numPages > 1) {        clearTimeout(this._pause);        if (this.options.clickStop && this._clicked) return;        else {          this._pause = setTimeout(this.bind(function() {            this.paginate(this._currentPageNum !== this._numPages ? this._currentPageNum + 1 : 1);          }, this), this.options.pause);        }      }    },    setMinHeight : function() {      if (this.options.minHeight && !this._container.is("table, tbody")) {        setTimeout(this.bind(function() {          this._container.css({ "min-height": this._container.css("height") });        }, this), 1000);      }    },    bind : function(fn, me) {      return function() {        return fn.apply(me, arguments);      };    },    destroy : function() {      this.jQdocument.unbind("keydown.jPages");      this._container.unbind("mousewheel.jPages DOMMouseScroll.jPages");      if (this.options.minHeight) this._container.css("min-height", "");      if (this._cssAnimSupport && this.options.animation.length)        this._items.removeClass("animated jp-hidden jp-invisible " + this.options.animation);      else this._items.removeClass("jp-hidden").fadeTo(0, 1);      this._holder.unbind("click.jPages").empty();    }  };  $.fn[name] = function(arg) {    var type = $.type(arg);    if (type === "object") {      if (this.length && !$.data(this, name)) {        instance = new Plugin(this, arg);        this.each(function() {          $.data(this, name, instance);        });      }      return this;    }    if (type === "string" && arg === "destroy") {      instance.destroy();      this.each(function() {        $.removeData(this, name);      });      return this;    }    if (type === 'number' && arg % 1 === 0) {      if (instance.validNewPage(arg)) instance.paginate(arg);      return this;    }    return this;  };})(jQuery, window, document);
 |