footable.paging.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. /*
  2. * FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
  3. * @version 3.1.6
  4. * @link http://fooplugins.com
  5. * @copyright Steven Usher & Brad Vincent 2015
  6. * @license Released under the GPLv3 license.
  7. */
  8. (function($, F){
  9. F.Pager = F.Class.extend(/** @lends FooTable.Pager */{
  10. /**
  11. * The pager object contains the page number and direction to page to.
  12. * @constructs
  13. * @extends FooTable.Class
  14. * @param {number} total - The total number of pages available.
  15. * @param {number} current - The current page number.
  16. * @param {number} size - The number of rows per page.
  17. * @param {number} page - The page number to goto.
  18. * @param {boolean} forward - A boolean indicating the direction of paging, TRUE = forward, FALSE = back.
  19. * @returns {FooTable.Pager}
  20. */
  21. construct: function(total, current, size, page, forward){
  22. /**
  23. * The total number of pages available.
  24. * @type {number}
  25. */
  26. this.total = total;
  27. /**
  28. * The current page number.
  29. * @type {number}
  30. */
  31. this.current = current;
  32. /**
  33. * The number of rows per page.
  34. * @type {number}
  35. */
  36. this.size = size;
  37. /**
  38. * The page number to goto.
  39. * @type {number}
  40. */
  41. this.page = page;
  42. /**
  43. * A boolean indicating the direction of paging, TRUE = forward, FALSE = back.
  44. * @type {boolean}
  45. */
  46. this.forward = forward;
  47. }
  48. });
  49. })(jQuery, FooTable);
  50. (function($, F){
  51. F.Paging = F.Component.extend(/** @lends FooTable.Paging */{
  52. /**
  53. * The paging component adds a pagination control to the table allowing users to navigate table rows via pages.
  54. * @constructs
  55. * @extends FooTable.Component
  56. * @param {FooTable.Table} table - The parent {@link FooTable.Table} object for the component.
  57. * @returns {FooTable.Filtering}
  58. */
  59. construct: function(table){
  60. // call the base constructor
  61. this._super(table, table.o.paging.enabled);
  62. /* PROTECTED */
  63. /**
  64. * An object containing the strings used by the paging buttons.
  65. * @type {{ first: string, prev: string, next: string, last: string }}
  66. */
  67. this.strings = table.o.paging.strings;
  68. /* PUBLIC */
  69. /**
  70. * The current page number to display.
  71. * @instance
  72. * @type {number}
  73. */
  74. this.current = table.o.paging.current;
  75. /**
  76. * The number of rows to display per page.
  77. * @instance
  78. * @type {number}
  79. */
  80. this.size = table.o.paging.size;
  81. /**
  82. * The maximum number of page links to display at once.
  83. * @instance
  84. * @type {number}
  85. */
  86. this.limit = table.o.paging.limit;
  87. /**
  88. * The position of the pagination control within the paging rows cell.
  89. * @instance
  90. * @type {string}
  91. */
  92. this.position = table.o.paging.position;
  93. /**
  94. * The format string used to generate the text displayed under the pagination control.
  95. * @instance
  96. * @type {string}
  97. */
  98. this.countFormat = table.o.paging.countFormat;
  99. /**
  100. * A selector specifying where to place the paging components UI, if null the UI is displayed within a row in the foot of the table.
  101. * @instance
  102. * @type {string}
  103. */
  104. this.container = table.o.paging.container;
  105. /**
  106. * The total number of pages.
  107. * @instance
  108. * @type {number}
  109. */
  110. this.total = -1;
  111. /**
  112. * The number of rows in the {@link FooTable.Rows#array} before paging is applied.
  113. * @instance
  114. * @type {number}
  115. */
  116. this.totalRows = 0;
  117. /**
  118. * A number indicating the previous page displayed.
  119. * @instance
  120. * @type {number}
  121. */
  122. this.previous = -1;
  123. /**
  124. * The count string generated using the {@link FooTable.Filtering#countFormat} option. This value is only set after the first call to the {@link FooTable.Filtering#predraw} method.
  125. * @instance
  126. * @type {string}
  127. */
  128. this.formattedCount = null;
  129. /**
  130. * The jQuery object of the element containing the entire paging UI.
  131. * @instance
  132. * @type {jQuery}
  133. */
  134. this.$container = null;
  135. /**
  136. * The jQuery object of the element wrapping all the paging UI elements.
  137. * @instance
  138. * @type {jQuery}
  139. */
  140. this.$wrapper = null;
  141. /** +
  142. * The jQuery row object that contains all the paging specific elements.
  143. * @instance
  144. * @type {jQuery}
  145. */
  146. this.$row = null;
  147. /**
  148. * The jQuery cell object that contains the pagination control and total count.
  149. * @instance
  150. * @type {jQuery}
  151. */
  152. this.$cell = null;
  153. /**
  154. * The jQuery object that contains the links for the pagination control.
  155. * @instance
  156. * @type {jQuery}
  157. */
  158. this.$pagination = null;
  159. /**
  160. * The jQuery object that contains the row count.
  161. * @instance
  162. * @type {jQuery}
  163. */
  164. this.$count = null;
  165. /**
  166. * Whether or not the pagination row is detached from the table.
  167. * @instance
  168. * @type {boolean}
  169. */
  170. this.detached = true;
  171. /* PRIVATE */
  172. /**
  173. * Used to hold the number of page links created.
  174. * @instance
  175. * @type {number}
  176. * @private
  177. */
  178. this._createdLinks = 0;
  179. },
  180. /* PROTECTED */
  181. /**
  182. * Checks the supplied data and options for the paging component.
  183. * @instance
  184. * @protected
  185. * @param {object} data - The jQuery data object from the parent table.
  186. * @fires FooTable.Paging#"preinit.ft.paging"
  187. */
  188. preinit: function(data){
  189. var self = this;
  190. /**
  191. * The preinit.ft.paging event is raised before the UI is created and provides the tables jQuery data object for additional options parsing.
  192. * Calling preventDefault on this event will disable the component.
  193. * @event FooTable.Paging#"preinit.ft.paging"
  194. * @param {jQuery.Event} e - The jQuery.Event object for the event.
  195. * @param {FooTable.Table} ft - The instance of the plugin raising the event.
  196. * @param {object} data - The jQuery data object of the table raising the event.
  197. */
  198. this.ft.raise('preinit.ft.paging', [data]).then(function(){
  199. if (self.ft.$el.hasClass('footable-paging'))
  200. self.enabled = true;
  201. self.enabled = F.is.boolean(data.paging)
  202. ? data.paging
  203. : self.enabled;
  204. if (!self.enabled) return;
  205. self.size = F.is.number(data.pagingSize)
  206. ? data.pagingSize
  207. : self.size;
  208. self.current = F.is.number(data.pagingCurrent)
  209. ? data.pagingCurrent
  210. : self.current;
  211. self.limit = F.is.number(data.pagingLimit)
  212. ? data.pagingLimit
  213. : self.limit;
  214. if (self.ft.$el.hasClass('footable-paging-left'))
  215. self.position = 'left';
  216. if (self.ft.$el.hasClass('footable-paging-center'))
  217. self.position = 'center';
  218. if (self.ft.$el.hasClass('footable-paging-right'))
  219. self.position = 'right';
  220. self.position = F.is.string(data.pagingPosition)
  221. ? data.pagingPosition
  222. : self.position;
  223. self.countFormat = F.is.string(data.pagingCountFormat)
  224. ? data.pagingCountFormat
  225. : self.countFormat;
  226. self.container = F.is.string(data.pagingContainer)
  227. ? data.pagingContainer
  228. : self.container;
  229. self.total = Math.ceil(self.ft.rows.all.length / self.size);
  230. }, function(){
  231. self.enabled = false;
  232. });
  233. },
  234. /**
  235. * Initializes the paging component for the plugin using the supplied table and options.
  236. * @instance
  237. * @protected
  238. * @fires FooTable.Paging#"init.ft.paging"
  239. */
  240. init: function(){
  241. /**
  242. * The init.ft.paging event is raised before its UI is generated.
  243. * Calling preventDefault on this event will disable the component.
  244. * @event FooTable.Paging#"init.ft.paging"
  245. * @param {jQuery.Event} e - The jQuery.Event object for the event.
  246. * @param {FooTable.Table} ft - The instance of the plugin raising the event.
  247. */
  248. var self = this;
  249. this.ft.raise('init.ft.paging').then(function(){
  250. self.$create();
  251. }, function(){
  252. self.enabled = false;
  253. });
  254. },
  255. /**
  256. * Destroys the paging component removing any UI generated from the table.
  257. * @instance
  258. * @protected
  259. * @fires FooTable.Paging#"destroy.ft.paging"
  260. */
  261. destroy: function () {
  262. /**
  263. * The destroy.ft.paging event is raised before its UI is removed.
  264. * Calling preventDefault on this event will prevent the component from being destroyed.
  265. * @event FooTable.Paging#"destroy.ft.paging"
  266. * @param {jQuery.Event} e - The jQuery.Event object for the event.
  267. * @param {FooTable.Table} ft - The instance of the plugin raising the event.
  268. */
  269. var self = this;
  270. this.ft.raise('destroy.ft.paging').then(function(){
  271. self.ft.$el.removeClass('footable-paging')
  272. .find('tfoot > tr.footable-paging').remove();
  273. self.detached = true;
  274. self._createdLinks = 0;
  275. });
  276. },
  277. /**
  278. * Performs the actual paging against the {@link FooTable.Rows#current} array removing all rows that are not on the current visible page.
  279. * @instance
  280. * @protected
  281. */
  282. predraw: function(){
  283. this.total = Math.ceil(this.ft.rows.array.length / this.size);
  284. this.current = this.current > this.total ? this.total : (this.current < 1 ? 1 : this.current);
  285. this.totalRows = this.ft.rows.array.length;
  286. if (this.totalRows > this.size){
  287. this.ft.rows.array = this.ft.rows.array.splice((this.current - 1) * this.size, this.size);
  288. }
  289. this.formattedCount = this.format(this.countFormat);
  290. },
  291. /**
  292. * Updates the paging UI setting the state of the pagination control.
  293. * @instance
  294. * @protected
  295. */
  296. draw: function(){
  297. if (this.total <= 1){
  298. if (!this.detached){
  299. if (this.$row){
  300. this.$row.detach();
  301. } else {
  302. this.$wrapper.detach();
  303. }
  304. this.detached = true;
  305. }
  306. } else {
  307. if (this.detached){
  308. if (this.$row){
  309. var $tfoot = this.ft.$el.children('tfoot');
  310. if ($tfoot.length == 0){
  311. $tfoot = $('<tfoot/>');
  312. this.ft.$el.append($tfoot);
  313. }
  314. this.$row.appendTo($tfoot);
  315. } else {
  316. this.$wrapper.appendTo(this.$container);
  317. }
  318. this.detached = false;
  319. }
  320. if (F.is.jq(this.$cell)){
  321. this.$cell.attr('colspan', this.ft.columns.visibleColspan);
  322. }
  323. this._createLinks();
  324. this._setVisible(this.current, this.current > this.previous);
  325. this._setNavigation(true);
  326. this.$count.text(this.formattedCount);
  327. }
  328. },
  329. /**
  330. * Creates the paging UI from the current options setting the various jQuery properties of this component.
  331. * @instance
  332. * @protected
  333. */
  334. $create: function(){
  335. this._createdLinks = 0;
  336. var position = 'footable-paging-center';
  337. switch (this.position){
  338. case 'left': position = 'footable-paging-left'; break;
  339. case 'right': position = 'footable-paging-right'; break;
  340. }
  341. this.ft.$el.addClass('footable-paging').addClass(position);
  342. this.$container = this.container === null ? null : $(this.container).first();
  343. if (!F.is.jq(this.$container)){
  344. var $tfoot = this.ft.$el.children('tfoot');
  345. if ($tfoot.length == 0){
  346. $tfoot = $('<tfoot/>');
  347. this.ft.$el.append($tfoot);
  348. }
  349. // add it to a row and then populate it with the search input and column selector dropdown.
  350. this.$row = $('<tr/>', {'class': 'footable-paging'}).prependTo($tfoot);
  351. this.$container = this.$cell = $('<td/>').attr('colspan', this.ft.columns.visibleColspan).appendTo(this.$row);
  352. } else {
  353. this.$container.addClass('footable-paging-external').addClass(position);
  354. }
  355. this.$wrapper = $('<div/>', {'class': 'footable-pagination-wrapper'}).appendTo(this.$container);
  356. this.$pagination = $('<ul/>', { 'class': 'pagination' }).on('click.footable', 'a.footable-page-link', { self: this }, this._onPageClicked);
  357. this.$count = $('<span/>', { 'class': 'label label-default' });
  358. this.$wrapper.append(this.$pagination, $('<div/>', {'class': 'divider'}), this.$count);
  359. this.detached = false;
  360. },
  361. /* PUBLIC */
  362. /**
  363. * @summary Uses the supplied format string and replaces the placeholder strings with the current values.
  364. * @description This method is used to generate the short description label for the pagination control. i.e. Showing X of Y records. The placeholders for this string are the following:
  365. * * {CP} - The current page number.
  366. * * {TP} - The total number of pages.
  367. * * {PF} - The first row of the current page.
  368. * * {PL} - The last row of the current page.
  369. * * {TR} - The total rows available.
  370. * These placeholders can be supplied in a string like; "Showing {PF} to {PL} of {TR} rows."
  371. * @param {string} formatString - The string to be formatted with the paging specific variables.
  372. * @returns {string}
  373. */
  374. format: function(formatString){
  375. var firstRow = (this.size * (this.current - 1)) + 1,
  376. lastRow = this.size * this.current;
  377. if (this.ft.rows.array.length == 0){
  378. firstRow = 0;
  379. lastRow = 0;
  380. } else {
  381. lastRow = lastRow > this.totalRows ? this.totalRows : lastRow;
  382. }
  383. return formatString.replace(/\{CP}/g, this.current)
  384. .replace(/\{TP}/g, this.total)
  385. .replace(/\{PF}/g, firstRow)
  386. .replace(/\{PL}/g, lastRow)
  387. .replace(/\{TR}/g, this.totalRows);
  388. },
  389. /**
  390. * Pages to the first page.
  391. * @instance
  392. * @returns {jQuery.Promise}
  393. * @fires FooTable.Paging#"before.ft.paging"
  394. * @fires FooTable.Paging#"after.ft.paging"
  395. */
  396. first: function(){
  397. return this._set(1);
  398. },
  399. /**
  400. * Pages to the previous page.
  401. * @instance
  402. * @returns {jQuery.Promise}
  403. * @fires FooTable.Paging#"before.ft.paging"
  404. * @fires FooTable.Paging#"after.ft.paging"
  405. */
  406. prev: function(){
  407. return this._set(this.current - 1 > 0 ? this.current - 1 : 1);
  408. },
  409. /**
  410. * Pages to the next page.
  411. * @instance
  412. * @returns {jQuery.Promise}
  413. * @fires FooTable.Paging#"before.ft.paging"
  414. * @fires FooTable.Paging#"after.ft.paging"
  415. */
  416. next: function(){
  417. return this._set(this.current + 1 < this.total ? this.current + 1 : this.total);
  418. },
  419. /**
  420. * Pages to the last page.
  421. * @instance
  422. * @returns {jQuery.Promise}
  423. * @fires FooTable.Paging#"before.ft.paging"
  424. * @fires FooTable.Paging#"after.ft.paging"
  425. */
  426. last: function(){
  427. return this._set(this.total);
  428. },
  429. /**
  430. * Pages to the specified page.
  431. * @instance
  432. * @param {number} page - The page number to go to.
  433. * @returns {jQuery.Promise}
  434. * @fires FooTable.Paging#"before.ft.paging"
  435. * @fires FooTable.Paging#"after.ft.paging"
  436. */
  437. goto: function(page){
  438. return this._set(page > this.total ? this.total : (page < 1 ? 1 : page));
  439. },
  440. /**
  441. * Shows the previous X number of pages in the pagination control where X is the value set by the {@link FooTable.Defaults#paging} - limit option value.
  442. * @instance
  443. */
  444. prevPages: function(){
  445. var page = this.$pagination.children('li.footable-page.visible:first').data('page') - 1;
  446. this._setVisible(page, true);
  447. this._setNavigation(false);
  448. },
  449. /**
  450. * Shows the next X number of pages in the pagination control where X is the value set by the {@link FooTable.Defaults#paging} - limit option value.
  451. * @instance
  452. */
  453. nextPages: function(){
  454. var page = this.$pagination.children('li.footable-page.visible:last').data('page') + 1;
  455. this._setVisible(page, false);
  456. this._setNavigation(false);
  457. },
  458. /**
  459. * Gets or sets the current page size.
  460. * @instance
  461. * @param {(number|string)} [value] - The new page size to use, this value is supplied to `parseInt` so strings can be used. If not supplied or an invalid valid the current page size is returned.
  462. * @returns {(number|undefined)}
  463. */
  464. pageSize: function(value){
  465. value = parseInt(value);
  466. if (isNaN(value)){
  467. return this.size;
  468. }
  469. this.size = value;
  470. this.total = Math.ceil(this.ft.rows.all.length / this.size);
  471. if (F.is.jq(this.$wrapper)){
  472. if (this.$container.is("td")){
  473. this.$row.remove();
  474. } else {
  475. this.$wrapper.remove();
  476. }
  477. }
  478. this.$create();
  479. this.ft.draw();
  480. },
  481. /* PRIVATE */
  482. /**
  483. * Performs the required steps to handle paging including the raising of the {@link FooTable.Paging#"before.ft.paging"} and {@link FooTable.Paging#"after.ft.paging"} events.
  484. * @instance
  485. * @private
  486. * @param {number} page - The page to set.
  487. * @returns {jQuery.Promise}
  488. * @fires FooTable.Paging#"before.ft.paging"
  489. * @fires FooTable.Paging#"after.ft.paging"
  490. */
  491. _set: function(page){
  492. var self = this,
  493. pager = new F.Pager(self.total, self.current, self.size, page, page > self.current);
  494. /**
  495. * The before.ft.paging event is raised before a sort is applied and allows listeners to modify the pager or cancel it completely by calling preventDefault on the jQuery.Event object.
  496. * @event FooTable.Paging#"before.ft.paging"
  497. * @param {jQuery.Event} e - The jQuery.Event object for the event.
  498. * @param {FooTable.Table} ft - The instance of the plugin raising the event.
  499. * @param {FooTable.Pager} pager - The pager that is about to be applied.
  500. */
  501. return self.ft.raise('before.ft.paging', [pager]).then(function(){
  502. pager.page = pager.page > pager.total ? pager.total : pager.page;
  503. pager.page = pager.page < 1 ? 1 : pager.page;
  504. if (self.current == page) return $.when();
  505. self.previous = self.current;
  506. self.current = pager.page;
  507. return self.ft.draw().then(function(){
  508. /**
  509. * The after.ft.paging event is raised after a pager has been applied.
  510. * @event FooTable.Paging#"after.ft.paging"
  511. * @param {jQuery.Event} e - The jQuery.Event object for the event.
  512. * @param {FooTable.Table} ft - The instance of the plugin raising the event.
  513. * @param {FooTable.Pager} pager - The pager that has been applied.
  514. */
  515. self.ft.raise('after.ft.paging', [pager]);
  516. });
  517. });
  518. },
  519. /**
  520. * Creates the pagination links using the current state of the plugin. If the total number of pages is the same as
  521. * the last time this function was executed it does nothing.
  522. * @instance
  523. * @private
  524. */
  525. _createLinks: function(){
  526. if (this._createdLinks === this.total) return;
  527. var self = this,
  528. multiple = self.total > 1,
  529. link = function(attr, html, klass){
  530. return $('<li/>', {
  531. 'class': klass
  532. }).attr('data-page', attr)
  533. .append($('<a/>', {
  534. 'class': 'footable-page-link',
  535. href: '#'
  536. }).data('page', attr).html(html));
  537. };
  538. self.$pagination.empty();
  539. if (multiple) {
  540. self.$pagination.append(link('first', self.strings.first, 'footable-page-nav'));
  541. self.$pagination.append(link('prev', self.strings.prev, 'footable-page-nav'));
  542. if (self.limit > 0 && self.limit < self.total){
  543. self.$pagination.append(link('prev-limit', self.strings.prevPages, 'footable-page-nav'));
  544. }
  545. }
  546. for (var i = 0, $li; i < self.total; i++){
  547. $li = link(i + 1, i + 1, 'footable-page');
  548. self.$pagination.append($li);
  549. }
  550. if (multiple){
  551. if (self.limit > 0 && self.limit < self.total){
  552. self.$pagination.append(link('next-limit', self.strings.nextPages, 'footable-page-nav'));
  553. }
  554. self.$pagination.append(link('next', self.strings.next, 'footable-page-nav'));
  555. self.$pagination.append(link('last', self.strings.last, 'footable-page-nav'));
  556. }
  557. self._createdLinks = self.total;
  558. },
  559. /**
  560. * Sets the state for the navigation links of the pagination control and optionally sets the active class state on the current page link.
  561. * @instance
  562. * @private
  563. * @param {boolean} active - Whether or not to set the active class state on the individual page links.
  564. */
  565. _setNavigation: function(active){
  566. if (this.current == 1) {
  567. this.$pagination.children('li[data-page="first"],li[data-page="prev"]').addClass('disabled');
  568. } else {
  569. this.$pagination.children('li[data-page="first"],li[data-page="prev"]').removeClass('disabled');
  570. }
  571. if (this.current == this.total) {
  572. this.$pagination.children('li[data-page="next"],li[data-page="last"]').addClass('disabled');
  573. } else {
  574. this.$pagination.children('li[data-page="next"],li[data-page="last"]').removeClass('disabled');
  575. }
  576. if ((this.$pagination.children('li.footable-page.visible:first').data('page') || 1) == 1) {
  577. this.$pagination.children('li[data-page="prev-limit"]').addClass('disabled');
  578. } else {
  579. this.$pagination.children('li[data-page="prev-limit"]').removeClass('disabled');
  580. }
  581. if ((this.$pagination.children('li.footable-page.visible:last').data('page') || this.limit) == this.total) {
  582. this.$pagination.children('li[data-page="next-limit"]').addClass('disabled');
  583. } else {
  584. this.$pagination.children('li[data-page="next-limit"]').removeClass('disabled');
  585. }
  586. if (this.limit > 0 && this.total < this.limit){
  587. this.$pagination.children('li[data-page="prev-limit"],li[data-page="next-limit"]').css('display', 'none');
  588. } else {
  589. this.$pagination.children('li[data-page="prev-limit"],li[data-page="next-limit"]').css('display', '');
  590. }
  591. if (active){
  592. this.$pagination.children('li.footable-page').removeClass('active').filter('li[data-page="' + this.current + '"]').addClass('active');
  593. }
  594. },
  595. /**
  596. * Sets the visible page using the supplied parameters.
  597. * @instance
  598. * @private
  599. * @param {number} page - The page to make visible.
  600. * @param {boolean} right - If set to true the supplied page will be the right most visible pagination link.
  601. */
  602. _setVisible: function(page, right){
  603. if (this.limit > 0 && this.total > this.limit){
  604. if (!this.$pagination.children('li.footable-page[data-page="'+page+'"]').hasClass('visible')){
  605. var start = 0, end = 0;
  606. if (right == true){
  607. end = page > this.total ? this.total : page;
  608. start = end - this.limit;
  609. } else {
  610. start = page < 1 ? 0 : page - 1;
  611. end = start + this.limit;
  612. }
  613. if (start < 0){
  614. start = 0;
  615. end = this.limit > this.total ? this.total : this.limit;
  616. }
  617. if (end > this.total){
  618. end = this.total;
  619. start = this.total - this.limit < 0 ? 0 : this.total - this.limit;
  620. }
  621. this.$pagination.children('li.footable-page').removeClass('visible').slice(start, end).addClass('visible');
  622. }
  623. } else {
  624. this.$pagination.children('li.footable-page').removeClass('visible').slice(0, this.total).addClass('visible');
  625. }
  626. },
  627. /**
  628. * Handles the click event for all links in the pagination control.
  629. * @instance
  630. * @private
  631. * @param {jQuery.Event} e - The event object for the event.
  632. */
  633. _onPageClicked: function(e){
  634. e.preventDefault();
  635. if ($(e.target).closest('li').is('.active,.disabled')) return;
  636. var self = e.data.self, page = $(this).data('page');
  637. switch(page){
  638. case 'first': self.first();
  639. return;
  640. case 'prev': self.prev();
  641. return;
  642. case 'next': self.next();
  643. return;
  644. case 'last': self.last();
  645. return;
  646. case 'prev-limit': self.prevPages();
  647. return;
  648. case 'next-limit': self.nextPages();
  649. return;
  650. default: self._set(page);
  651. return;
  652. }
  653. }
  654. });
  655. F.components.register('paging', F.Paging, 400);
  656. })(jQuery, FooTable);
  657. (function(F){
  658. /**
  659. * An object containing the paging options for the plugin. Added by the {@link FooTable.Paging} component.
  660. * @type {object}
  661. * @prop {boolean} enabled=false - Whether or not to allow paging on the table.
  662. * @prop {string} countFormat="{CP} of {TP}" - A string format used to generate the page count text.
  663. * @prop {number} current=1 - The page number to display.
  664. * @prop {number} limit=5 - The maximum number of page links to display at once.
  665. * @prop {string} position="center" - The string used to specify the alignment of the pagination control.
  666. * @prop {number} size=10 - The number of rows displayed per page.
  667. * @prop {string} container=null - A selector specifying where to place the paging components UI, if null the UI is displayed within a row in the foot of the table.
  668. * @prop {object} strings - An object containing the strings used by the paging buttons.
  669. * @prop {string} strings.first="&laquo;" - The string used for the 'first' button.
  670. * @prop {string} strings.prev="&lsaquo;" - The string used for the 'previous' button.
  671. * @prop {string} strings.next="&rsaquo;" - The string used for the 'next' button.
  672. * @prop {string} strings.last="&raquo;" - The string used for the 'last' button.
  673. * @prop {string} strings.prevPages="..." - The string used for the 'previous X pages' button.
  674. * @prop {string} strings.nextPages="..." - The string used for the 'next X pages' button.
  675. */
  676. F.Defaults.prototype.paging = {
  677. enabled: false,
  678. countFormat: '{CP} of {TP}',
  679. current: 1,
  680. limit: 5,
  681. position: 'center',
  682. size: 10,
  683. container: null,
  684. strings: {
  685. first: '&laquo;',
  686. prev: '&lsaquo;',
  687. next: '&rsaquo;',
  688. last: '&raquo;',
  689. prevPages: '...',
  690. nextPages: '...'
  691. }
  692. };
  693. })(FooTable);
  694. (function(F){
  695. /**
  696. * Navigates to the specified page number. Added by the {@link FooTable.Paging} component.
  697. * @instance
  698. * @param {number} num - The page number to go to.
  699. * @returns {jQuery.Promise}
  700. * @fires FooTable.Paging#paging_changing
  701. * @fires FooTable.Paging#paging_changed
  702. * @see FooTable.Paging#goto
  703. */
  704. F.Table.prototype.gotoPage = function(num){
  705. return this.use(F.Paging).goto(num);
  706. };
  707. /**
  708. * Navigates to the next page. Added by the {@link FooTable.Paging} component.
  709. * @instance
  710. * @returns {jQuery.Promise}
  711. * @fires FooTable.Paging#paging_changing
  712. * @fires FooTable.Paging#paging_changed
  713. * @see FooTable.Paging#next
  714. */
  715. F.Table.prototype.nextPage = function(){
  716. return this.use(F.Paging).next();
  717. };
  718. /**
  719. * Navigates to the previous page. Added by the {@link FooTable.Paging} component.
  720. * @instance
  721. * @returns {jQuery.Promise}
  722. * @fires FooTable.Paging#paging_changing
  723. * @fires FooTable.Paging#paging_changed
  724. * @see FooTable.Paging#prev
  725. */
  726. F.Table.prototype.prevPage = function(){
  727. return this.use(F.Paging).prev();
  728. };
  729. /**
  730. * Navigates to the first page. Added by the {@link FooTable.Paging} component.
  731. * @instance
  732. * @returns {jQuery.Promise}
  733. * @fires FooTable.Paging#paging_changing
  734. * @fires FooTable.Paging#paging_changed
  735. * @see FooTable.Paging#first
  736. */
  737. F.Table.prototype.firstPage = function(){
  738. return this.use(F.Paging).first();
  739. };
  740. /**
  741. * Navigates to the last page. Added by the {@link FooTable.Paging} component.
  742. * @instance
  743. * @returns {jQuery.Promise}
  744. * @fires FooTable.Paging#paging_changing
  745. * @fires FooTable.Paging#paging_changed
  746. * @see FooTable.Paging#last
  747. */
  748. F.Table.prototype.lastPage = function(){
  749. return this.use(F.Paging).last();
  750. };
  751. /**
  752. * Shows the next X number of pages in the pagination control where X is the value set by the {@link FooTable.Defaults#paging} - limit.size option value. Added by the {@link FooTable.Paging} component.
  753. * @instance
  754. * @see FooTable.Paging#nextPages
  755. */
  756. F.Table.prototype.nextPages = function(){
  757. return this.use(F.Paging).nextPages();
  758. };
  759. /**
  760. * Shows the previous X number of pages in the pagination control where X is the value set by the {@link FooTable.Defaults#paging} - limit.size option value. Added by the {@link FooTable.Paging} component.
  761. * @instance
  762. * @see FooTable.Paging#prevPages
  763. */
  764. F.Table.prototype.prevPages = function(){
  765. return this.use(F.Paging).prevPages();
  766. };
  767. /**
  768. * Gets or sets the current page size
  769. * @instance
  770. * @param {number} [value] - The new page size to use.
  771. * @returns {(number|undefined)}
  772. * @see FooTable.Paging#pageSize
  773. */
  774. F.Table.prototype.pageSize = function(value){
  775. return this.use(F.Paging).pageSize(value);
  776. };
  777. })(FooTable);