PageRenderTime 46ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/dist/backbone.paginator.js

https://github.com/dgs700/backbone.paginator
JavaScript | 302 lines | 206 code | 61 blank | 35 comment | 27 complexity | 2a2f71a732848d3536dcfe0e22a43926 MD5 | raw file
Possible License(s): MIT
  1. /*! backbone.paginator - v0.1.5 - 3/28/2012
  2. * http://github.com/addyosmani/backbone.paginator
  3. * Copyright (c) 2012 Addy Osmani; Licensed MIT */
  4. Backbone.Paginator = (function (Backbone, _, $) {
  5. "use strict";
  6. var Paginator = {};
  7. Paginator.version = "0.15";
  8. // @name: clientPager
  9. //
  10. // @tagline: Paginator for client-side data
  11. //
  12. // @description:
  13. // This paginator is responsible for providing pagination
  14. // and sort capabilities for a single payload of data
  15. // we wish to paginate by the UI for easier browsering.
  16. //
  17. Paginator.clientPager = Backbone.Collection.extend({
  18. sync: function (method, model, options) {
  19. var queryMap = {};
  20. queryMap[this.perPageAttribute] = this.perPage;
  21. queryMap[this.skipAttribute] = this.page * this.perPage;
  22. queryMap[this.orderAttribute] = this.sortField;
  23. queryMap[this.customAttribute1] = this.customParam1;
  24. queryMap[this.formatAttribute] = this.format;
  25. queryMap[this.customAttribute2] = this.customParam2;
  26. queryMap[this.queryAttribute] = this.query;
  27. var params = _.extend({
  28. type: 'GET',
  29. dataType: 'jsonp',
  30. jsonpCallback: 'callback',
  31. data: decodeURIComponent($.param(queryMap)),
  32. url: this.url,
  33. processData: false
  34. }, options);
  35. return $.ajax(params);
  36. },
  37. nextPage: function () {
  38. this.page = this.page++;
  39. this.pager();
  40. },
  41. previousPage: function () {
  42. this.page = --this.page || 1;
  43. this.pager();
  44. },
  45. goTo: function (page) {
  46. this.page = parseInt(page, 10);
  47. this.pager();
  48. },
  49. howManyPer: function (perPage) {
  50. this.displayPerPage = perPage;
  51. this.pager();
  52. },
  53. // where column is the key to sort on
  54. setSort: function (column, direction) {
  55. this.pager(column, direction);
  56. },
  57. pager: function (sort, direction) {
  58. var self = this,
  59. start = (self.page - 1) * this.displayPerPage,
  60. stop = start + this.displayPerPage;
  61. if (self.origModels === undefined) {
  62. self.origModels = self.models;
  63. }
  64. self.models = self.origModels;
  65. if (sort) {
  66. self.models = self._sort(self.models, sort, direction);
  67. }
  68. self.reset(
  69. self.models.slice(start, stop));
  70. },
  71. _sort: function (models, sort, direction) {
  72. models = models.sort(function (a, b) {
  73. var ac = a.get(sort),
  74. bc = b.get(sort);
  75. if (direction === 'desc') {
  76. if (ac > bc) {
  77. return -1;
  78. }
  79. if (ac < bc) {
  80. return 1;
  81. }
  82. } else {
  83. if (ac < bc) {
  84. return -1;
  85. }
  86. if (ac > bc) {
  87. return 1;
  88. }
  89. }
  90. return 0;
  91. });
  92. return models;
  93. },
  94. info: function () {
  95. var self = this,
  96. info = {},
  97. totalRecords = (self.origModels) ? self.origModels.length : self.length,
  98. totalPages = Math.ceil(totalRecords / self.perPage);
  99. info = {
  100. totalRecords: totalRecords,
  101. page: self.page,
  102. perPage: this.displayPerPage,
  103. totalPages: totalPages,
  104. lastPage: totalPages,
  105. lastPagem1: totalPages - 1,
  106. previous: false,
  107. next: false,
  108. page_set: [],
  109. startRecord: (self.page - 1) * this.displayPerPage + 1,
  110. endRecord: Math.min(totalRecords, self.page * this.displayPerPage)
  111. };
  112. if (self.page > 1) {
  113. info.prev = self.page - 1;
  114. }
  115. if (self.page < info.totalPages) {
  116. info.next = self.page + 1;
  117. }
  118. info.pageSet = self.setPagination(info);
  119. self.information = info;
  120. return info;
  121. },
  122. setPagination: function (info) {
  123. var pages = [], i = 0, l = 0;
  124. // How many adjacent pages should be shown on each side?
  125. var ADJACENT = 3;
  126. var ADJACENTx2 = ADJACENT * 2;
  127. var LASTPAGE = Math.ceil(info.totalRecords / info.perPage);
  128. var LPM1 = -1;
  129. if (LASTPAGE > 1) {
  130. // not enough pages to bother breaking it up
  131. if (LASTPAGE < (7 + ADJACENTx2)) {
  132. for (i = 1, l = LASTPAGE; i <= l; i++) {
  133. pages.push(i);
  134. }
  135. }
  136. // enough pages to hide some
  137. else if (LASTPAGE > (5 + ADJACENTx2)) {
  138. //close to beginning; only hide later pages
  139. if (info.page < (1 + ADJACENTx2)) {
  140. for (i = 1, l = 4 + ADJACENTx2; i < l; i++) {
  141. pages.push(i);
  142. }
  143. }
  144. // in middle; hide some front and some back
  145. else if (LASTPAGE - ADJACENTx2 > info.page && info.page > ADJACENTx2) {
  146. for (i = info.page - ADJACENT; i <= info.page + ADJACENT; i++) {
  147. pages.push(i);
  148. }
  149. }
  150. // close to end; only hide early pages
  151. else {
  152. for (i = LASTPAGE - (2 + ADJACENTx2); i <= LASTPAGE; i++) {
  153. pages.push(i);
  154. }
  155. }
  156. }
  157. }
  158. return pages;
  159. }
  160. });
  161. // @name: requestPager
  162. //
  163. // Paginator for server-side data being requested from a backend/API
  164. //
  165. // @description:
  166. // This paginator is responsible for providing pagination
  167. // and sort capabilities for requests to a server-side
  168. // data service (e.g an API)
  169. //
  170. Paginator.requestPager = Backbone.Collection.extend({
  171. sync: function (method, model, options) {
  172. var queryMap = {}, params;
  173. queryMap[this.perPageAttribute] = this.perPage;
  174. queryMap[this.skipAttribute] = this.page * this.perPage;
  175. queryMap[this.orderAttribute] = this.sortField;
  176. queryMap[this.customAttribute1] = this.customParam1;
  177. queryMap[this.formatAttribute] = this.format;
  178. queryMap[this.customAttribute2] = this.customParam2;
  179. queryMap[this.queryAttribute] = this.query;
  180. params = _.extend({
  181. type: 'GET',
  182. dataType: 'jsonp',
  183. jsonpCallback: 'callback',
  184. data: decodeURIComponent($.param(queryMap)),
  185. url: this.url,
  186. processData: false
  187. }, options);
  188. return $.ajax(params);
  189. },
  190. requestNextPage: function () {
  191. if (typeof this.page === "number") {
  192. this.page += 1;
  193. // customize as needed. For the Netflix API, skipping ahead based on
  194. // page * number of results per page was necessary. You may have a
  195. // simpler server-side pagination API where just updating
  196. // the 'page' value is all you need to do.
  197. // This applies similarly to requestPreviousPage()
  198. this.pager();
  199. }
  200. },
  201. requestPreviousPage: function () {
  202. if (typeof this.page === "number") {
  203. this.page -= 1;
  204. // customize as needed.
  205. this.pager();
  206. }
  207. },
  208. updateOrder: function (column) {
  209. if (column) {
  210. this.sortField = column;
  211. this.pager();
  212. }
  213. },
  214. goTo: function (page) {
  215. this.page = parseInt(page, 10);
  216. this.pager();
  217. },
  218. howManyPer: function (count) {
  219. this.page = this.firstPage;
  220. this.perPage = count;
  221. this.pager();
  222. },
  223. sort: function () {
  224. },
  225. info: function () {
  226. var info = {
  227. page: this.page,
  228. firstPage: this.firstPage,
  229. totalPages: this.totalPages,
  230. lastPage: this.totalPages
  231. };
  232. this.information = info;
  233. return info;
  234. },
  235. // fetches the latest results from the server
  236. pager: function () {
  237. this.fetch({});
  238. }
  239. });
  240. return Paginator;
  241. }(Backbone, _, $));