PageRenderTime 70ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/facete-client/src/main/webapp/resources/js/org/aksw/ssb/widgets/PaginatorWidgetAgility.js

https://github.com/GeoKnow/Facete
JavaScript | 437 lines | 164 code | 59 blank | 214 comment | 8 complexity | a324d96ab06d640f211c790e2a9ca778 MD5 | raw file
  1. (function($) {
  2. var ns = Namespace("org.aksw.ssb.widgets");
  3. ns.createItemFactory = function(agilityObject) {
  4. return function(parent) {
  5. return $$(agilityObject, {parent: parent});
  6. };
  7. };
  8. ns.calcPageCount = function(items, itemsPerPage) {
  9. return Math.floor(item / itemsPerPage);
  10. };
  11. /*
  12. ns.caleItemOffset = function(index, itemsPerPage) {
  13. };
  14. */
  15. ns.PaginatorItemRenderer = function() {
  16. };
  17. ns.PaginatorItemRenderer.prototype.create = function(parent, data) {
  18. var result = $$(ns.PaginatorItem, {parent: parent});
  19. result.setEnabled(data.isEnabled);
  20. result.setActive(data.isActive);
  21. result.setPage(data.page);
  22. result.setLabel(data.label);
  23. return result;
  24. };
  25. ns.PaginatorItem =
  26. $$({
  27. view: {
  28. format: '<li><a href="#" /></li>'
  29. },
  30. controller: {
  31. 'click a': function() {
  32. if(!this.isEnabled()) {
  33. return;
  34. }
  35. this.getParent().trigger("change-page", this.getPage());
  36. }
  37. },
  38. isEnabled: function() {
  39. return !this.view.$().hasClass("disabled");
  40. },
  41. setEnabled: function(value) {
  42. if(value) {
  43. this.view.$().removeClass("disabled");
  44. } else {
  45. this.view.$().addClass("disabled");
  46. }
  47. },
  48. isActive: function(value) {
  49. return this.view.$().hasClass("active");
  50. },
  51. setActive: function(value) {
  52. if(value) {
  53. this.view.$().addClass("active");
  54. } else {
  55. this.view.$().removeClass("active");
  56. }
  57. },
  58. setPage: function(index) {
  59. this.model.set({page: index});
  60. },
  61. getPage: function() {
  62. return this.model.get("page");
  63. },
  64. setLabel: function(label) {
  65. this.view.$("a").text(label);//html($.escapeHTML(label));
  66. //this.model.set({label: label});
  67. },
  68. getLabel: function() {
  69. return this.view.$("a").text();
  70. //return this.model.get("label");
  71. },
  72. getParent: function() {
  73. return this.model.get("parent");
  74. }
  75. });
  76. /*
  77. var PaginatorItemNext =
  78. */
  79. /* TODO Eventually it seems backbone is the better choice
  80. * - although agility seemed simple at first, I find myself
  81. * re-implenting features that backbone already offers in
  82. * order to increase reusability
  83. */
  84. /*
  85. ns.PaginatorModel = Backbone.Model.extend({
  86. defaults: {
  87. label: "not set",
  88. page: -1
  89. }
  90. });
  91. ns.PaginatorCollection = Backbone.Collection.extend({
  92. model: ns.PaginatorModel
  93. });
  94. */
  95. /**
  96. *
  97. */
  98. ns.PaginatorModel = function(options) {
  99. this.maxSlotCount = 6;
  100. this.currentPage = 1;
  101. this.pageCount = 1;
  102. this.maxContextCount = 5; // Number of boxes around the current location
  103. this.minStartCount = 1;
  104. this.minEndCount = 1;
  105. this.hasMorePages = false;
  106. _.extend(this, options);
  107. };
  108. ns.PaginatorModel.prototype.setCurrentPage = function(page) {
  109. this.currentPage = Math.min(this.pageCount, page);
  110. };
  111. ns.PaginatorModel.prototype.getCurrentPage = function() {
  112. return this.currentPage;
  113. };
  114. ns.PaginatorModel.prototype.setPageCount = function(pageCount) {
  115. this.pageCount = pageCount;
  116. };
  117. ns.PaginatorModel.prototype.getPageCount = function() {
  118. return this.getPageCount;
  119. };
  120. ns.PaginatorModel.prototype.getMaxSlotCount = function() {
  121. return this.maxSlotCount;
  122. };
  123. //ns.PageModel.prototype.
  124. ns.PaginatorModel.prototype.fetchData = function() {
  125. var currentPage = this.currentPage;
  126. // page indexes are zero based in here
  127. var numSlots = this.maxSlotCount - 2;
  128. var maxNumHeadSlots = currentPage - 1; // If we are on page 1, then there is 0 head pages
  129. var maxNumTailSlots = this.pageCount - currentPage; // If we are one page 10 of 10, there is 0 tail pages
  130. var numTailSlots = Math.min(maxNumTailSlots, Math.floor((numSlots - 1) / 2));
  131. var numHeadSlots = Math.min(maxNumHeadSlots, numSlots - numTailSlots - 1); // All slots that are neither tail nor current may be head
  132. var numRequiredSlots = Math.min(numSlots, this.pageCount);//numHeadSlots + numTailSlots + 1;
  133. //var activeSlotIndex = numHeadSlots + 1;
  134. var firstPage = currentPage - numHeadSlots;
  135. var pageSlots = [];
  136. // Prev button
  137. pageSlots.push({
  138. label: "<",
  139. isEnabled: currentPage > 1,
  140. page: currentPage -1
  141. });
  142. // First page button (only applies if there is more than two pages)
  143. for(var i = 0; i < numRequiredSlots; ++i) {
  144. var page = firstPage + i;
  145. pageSlots.push({
  146. label: "" + page,
  147. isEnabled: page != currentPage,
  148. isActive: page == currentPage,
  149. page: page
  150. });
  151. }
  152. pageSlots.push({
  153. label: ">",
  154. isEnabled: currentPage < this.pageCount,
  155. page: currentPage + 1
  156. });
  157. //return pageSlots;
  158. var result = $.Deferred();
  159. result.resolve(pageSlots);
  160. return result.promise();
  161. };
  162. ns.createPaginator = function(model) {
  163. //return $$(ns.Paginator, {itemFactory: ns.createItemFactory(ns.PaginatorItem)});
  164. //return ns.createListWidget(model, ns.createItemFactory(ns.PaginatorItem));
  165. var result = $$(ns.Paginator);
  166. result.getListWidget().setModel(model);
  167. //result.getListWidget().setItemFactory(ns.PaginatorItemRenderer);
  168. return result;
  169. };
  170. /**
  171. * A paginator widget (based on twitter bootstrap).
  172. *
  173. *
  174. * hasMorePages: Whether more pages than those are known exist
  175. *
  176. */
  177. ns.Paginator = $$({
  178. //model: {maxSlotCount: 5, currentPage: 0, pageCount: 0, hasMorePages: false, slots: []},
  179. view: {
  180. format: '<div class="pagination pagination-centered"></div>'
  181. },
  182. controller: {
  183. create: function() {
  184. var listWidget = ns.createListWidget(null, new ns.PaginatorItemRenderer());
  185. this.setListWidget(listWidget);
  186. this.append(listWidget);
  187. var self = this;
  188. listWidget.bind("change-page", function(ev, item) {
  189. self.trigger("change-page", item);
  190. });
  191. }
  192. },
  193. setModel: function(model) {
  194. this.getListWidget().setModel(model);
  195. },
  196. getModel: function() {
  197. return this.getListWidget().getModel();
  198. },
  199. getListWidget: function() {
  200. return this.model.get("listWidget");
  201. },
  202. setListWidget: function(listWidget) {
  203. this.model.set({listWidget: listWidget});
  204. },
  205. refresh: function() {
  206. this.getListWidget().refresh();
  207. }
  208. /*
  209. setCurrentPage: function(index) {
  210. this.model.set({currentPage: index});
  211. },
  212. getCurrentPage: function(index) {
  213. return this.model.get("currentPage");
  214. },
  215. getPageCount: function() {
  216. return this.model.get("pageCount");
  217. },
  218. setPageCount: function(pageCount) { //}, hasMorePages) {
  219. this.model.set({pageCount: pageCount});
  220. },
  221. /**
  222. * The number of pages shown in the list;
  223. * excluding buttons for forward and backward.
  224. *
  225. * @param size
  226. */
  227. /*
  228. setSlots: function(size) {
  229. var listWidget = this.getListWidget();
  230. var n = size + 2;
  231. // Remove superfluous items
  232. listWidget.trimToSize(n);
  233. var slots = this.getSlots();
  234. // Create new items as neccessary
  235. var m = n - slots.length;
  236. for(var i = 0; i < m; ++i) {
  237. var item = listWidget.getItemFactory()(this);
  238. //item.setLabel("" + (pages.length + i));
  239. listWidget.addItem(item);
  240. }
  241. //this.refresh();
  242. },
  243. */
  244. /**
  245. * [<<] [<] [10] [*11*] [12] [...] [>] [>>]
  246. *
  247. * At end
  248. * [<<] [<]... [49] [50] [>] [>>]
  249. *
  250. * At beginning
  251. * [<<] [<] [1] [2] [...] [>] [>>]
  252. *
  253. * In middle
  254. * [<<] [<] [...] [30] [31] [32] [...] [>] [>>]
  255. *
  256. */
  257. /*
  258. refresh: function() {
  259. var currentPage = this.getCurrentPage();
  260. var pageCount = this.getPageCount();
  261. // page indexes are zero based in here
  262. var numSlots = this.getMaxSlotCount() - 1; // We need one slot for the current page
  263. var maxNumHeadSlots = currentPage - 1;
  264. var maxNumTailSlots = pageCount - currentPage - 1;
  265. var numTailSlots = Math.min(maxNumTailSlots, Math.round(numSlots / 2));
  266. var numHeadSlots = Math.min(maxNumHeadSlots, numTailSlots - numTailSlots);
  267. var numRequiredSlots = numHeadSlots + numTailSlots + 1;
  268. var activeSlotIndex = numHeadSlots + 1;
  269. // Update the slots
  270. this.setSlots(numRequiredSlots);
  271. var slots = this.getSlots();
  272. console.log("Slots are", numRequiredSlots, slots);
  273. var firstPage = currentPage - numHeadSlots;
  274. for(var i = 0; i < numRequiredSlots; ++i) {
  275. var slot = slots[i];
  276. var page = firstPage + i;
  277. slot.setLabel("" + page);
  278. slot.setActive(false);
  279. slot.setTargetPage(page);
  280. }
  281. slots[activeSlotIndex].setActive(true);
  282. {
  283. var slot = this.getJumpToPrev();
  284. slot.setLabel("<");
  285. if(currentPage > 0) {
  286. slot.setTargetPage(currentPage - 1);
  287. slot.setEnabled(true);
  288. } else {
  289. slot.setEnabled(false);
  290. }
  291. }
  292. {
  293. var slot = this.getJumpToNext();
  294. slot.setLabel(">");
  295. if(currentPage < pageCount - 1) {
  296. slot.setTargetPage(currentPage + 1);
  297. slot.setEnabled(true);
  298. } else {
  299. slot.setEnabled(false);
  300. }
  301. }
  302. },
  303. getMaxSlotCount: function() {
  304. return this.model.get("maxSlotCount");
  305. },
  306. setMaxSlotCount: function(maxSlotCount) {
  307. this.model.set({maxSlotCount: maxSlotCount});
  308. },
  309. /**
  310. * Return the number of pages that are displayed
  311. * /
  312. getMaxSlotCount: function() {
  313. return this.model.get("maxSlotCount");
  314. },
  315. getAllSlots: function() {
  316. return this.getListWidget().getItems();
  317. },
  318. getSlots: function() {
  319. var slots = this.getAllSlots();
  320. return slots.slice(1, slots.length - 1);
  321. },
  322. getJumpToPrev: function() {
  323. return this.getAllSlots()[0];
  324. },
  325. getJumpToNext: function() {
  326. var slots = this.getAllSlots();
  327. return slots[slots.length - 1];
  328. },
  329. getJumpToCustom: function() {
  330. },
  331. getJumpToFirst: function() {
  332. var pages = this.getAllPages();
  333. return pages[0];
  334. },
  335. getJumpToLast: function() {
  336. var pages = this.getAllPages();
  337. return pages[pages.length - 1];
  338. },
  339. getPage: function() {
  340. },
  341. */
  342. });
  343. })(jQuery);