Guest User

Untitled

a guest
Feb 25th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.70 KB | None | 0 0
  1. (function () {
  2. ko.littleGrid = {
  3. // Defines a view model class you can use to populate a grid
  4. viewModel: function (configuration) {
  5. var self = this;
  6. self.data = configuration.data;
  7. self.currentPageIndex = ko.observable(0);
  8. self.pager = configuration.pager || false;
  9. self.pageSize = configuration.pageSize || 5;
  10. self.columns = configuration.columns;
  11. self.detail = configuration.detail || false;
  12. self.detailNode = configuration.detailNode || "";
  13. self.detailMethod = configuration.detailMethod || "";
  14. self.detailColumns = configuration.detailColumns;
  15. self.detailReactive = configuration.detailReactive; // attribute that allows detail columns to be specified without detail being set to true or expand button showing
  16. self.noDefaultExpand = configuration.noDefaultExpand;
  17.  
  18. // ensure column configuration is correct
  19. columnsCheck(configuration, self.columns);
  20.  
  21. if (self.detail) {
  22. columnsCheck(configuration, self.detailColumns);
  23. // create the expand button item
  24. var expand = new Object({});
  25. expand.expandButton = true;
  26. expand.headerText = "";
  27. self.columns.splice(0, 0, expand);
  28. }
  29. else if (self.detailReactive) {
  30. columnsCheck(configuration, self.detailColumns);
  31. }
  32.  
  33. self.itemsOnCurrentPage = ko.computed(function () {
  34. if (self.pager) {
  35. var startIndex = self.pageSize * self.currentPageIndex();
  36. return reworkLookupsToObservables(ko.unwrap(self.columns), ko.unwrap(self.detailColumns), ko.unwrap(self.data).slice(startIndex, startIndex + self.pageSize));
  37. }
  38. else {
  39. return reworkLookupsToObservables(ko.unwrap(self.columns), ko.unwrap(self.detailColumns), ko.unwrap(self.data));
  40. }
  41. }, self);
  42.  
  43. self.maxPageIndex = ko.computed(function () {
  44. return Math.ceil(ko.unwrap(self.data).length / self.pageSize) - 1;
  45. }, self);
  46.  
  47. self.jumpToFirstPage = function () {
  48. self.currentPageIndex(0);
  49. };
  50.  
  51. self.jumpToLastPage = function () {
  52. self.currentPageIndex(Math.ceil(ko.unwrap(self.data).length / self.pageSize) - 1);
  53. };
  54.  
  55. self.methodNav = function (data, element, column) {
  56. var theMethod = window[column.method];
  57. if (typeof theMethod === 'function') {
  58. theMethod(data, element);
  59. }
  60. };
  61.  
  62. self.expandDetailedGrid = function (data, element) {
  63. // if the element is loading ignore it
  64. if (element.type === "readystatechange") {
  65. return;
  66. }
  67. var item = $(element.currentTarget),
  68. icon = $(item[0].children[0]);
  69. // collapse a detailed grid
  70. if (icon.hasClass("icon-minimizeMinusIcon")) {
  71. icon.removeClass("icon-minimizeMinusIcon");
  72. icon.addClass("icon-plusIcon");
  73. item.parent().next().hide();
  74. }
  75. // expand a detailed grid
  76. else {
  77. icon.addClass("icon-minimizeMinusIcon");
  78. icon.removeClass("icon-plusIcon");
  79. item.parent().next().show();
  80. }
  81.  
  82. if (self.detailMethod.length > 0) {
  83. var theMethod = window[self.detailMethod];
  84. if (typeof theMethod === 'function') {
  85. theMethod(data, element);
  86. }
  87. }
  88. };
  89.  
  90. self.expandMobileGrid = function (data, element) {
  91. // if the element is loading ignore it
  92. if (element.type === "readystatechange") {
  93. return;
  94. }
  95. var item = $(element.currentTarget);
  96.  
  97. var moreInfo = item.parent().find(".moreDetail");
  98.  
  99. if (moreInfo.length === 0) {
  100. moreInfo = $(item.parent().parent()[0].nextElementSibling);
  101.  
  102. if (moreInfo.is(":visible")) {
  103. moreInfo.hide();
  104. }
  105. // expand a detailed grid
  106. else {
  107. moreInfo.show();
  108. if (!moreInfo.is(":visible")) {
  109. moreInfo.attr("style", "display: block !important;");
  110. }
  111. }
  112. }
  113. else {
  114. moreInfo.attr("style", "display: block !important;");
  115. item.attr("style", "display: none !important;");
  116. }
  117. };
  118.  
  119. function toggleInfo(data, element) {
  120. var item = $(element.currentTarget),
  121. moreDetail = item.closest('tr').next();
  122. // collapse a detailed grid
  123. if (moreDetail.is(":visible")) {
  124. moreDetail.hide();
  125. }
  126. // expand a detailed grid
  127. else {
  128. moreDetail.show();
  129. }
  130. }
  131. }
  132. };
  133.  
  134. // Templates used to render the grid
  135. var templateEngine = new ko.nativeTemplateEngine();
  136.  
  137. templateEngine.addTemplate = function (templateName, templateMarkup) {
  138. $("head").append("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
  139. };
  140.  
  141. /*jshint multistr: true */
  142. var pagerTemplate =
  143. '<!-- ko if: $root.pager -->' +
  144. ' <tfoot>' +
  145. ' <tr>' +
  146. ' <td data-bind=\"attr: { colspan: $root.columns.length }\">' +
  147. ' <div class=\"ui small pagination menu\">' +
  148. ' <a class=\"icon item\" data-bind=\"click: $root.jumpToFirstPage\">' +
  149. ' <i class=\"left arrow icon\"></i>' +
  150. ' </a>' +
  151. ' <!-- ko foreach: ko.utils.range(0, maxPageIndex) -->' +
  152. ' <a href=\"#\" class=\"item\" data-bind=\"text: $data + 1, click: function() { $root.currentPageIndex($data) }, css: { active: $data == $root.currentPageIndex() }\"></a>' +
  153. ' <!-- /ko -->' +
  154. ' <a class=\"icon item\" data-bind=\"click: $root.jumpToLastPage\">' +
  155. ' <i class=\"right arrow icon\"></i>' +
  156. ' </a>' +
  157. ' </div>' +
  158. ' </td>' +
  159. ' </tr>' +
  160. ' </tfoot>' +
  161. '<!-- /ko -->';
  162.  
  163. /*jshint multistr: true */
  164. var rowTextTemplate =
  165. '<!-- ko if: $data.hasOwnProperty(\'customTemplate\') -->' +
  166. ' <!-- ko template: customTemplate --><!-- /ko -->' +
  167. '<!-- /ko -->' +
  168. '<!-- ko if: button && $data.hasOwnProperty(\'expand\') && !$data.hasOwnProperty(\'href\')-->' +
  169. ' <button data-bind=\"click: function(data,event) {$root.expandMobileGrid($parent, event)}\" class=\"fluid ui tiny lgBtnColour button\"><!-- ko text: typeof rowText == \'function\' ? rowText($parent) : rowText --><!-- /ko --></button>' +
  170. '<!-- /ko -->' +
  171. '<!-- ko if: button && $data.hasOwnProperty(\'href\') -->' +
  172. ' <a data-bind=\"attr: { \'href\': href + (hrefPlaceHolder === \'\' ? \'\' : $parent[hrefPlaceHolder]) }\" class=\"fluid ui tiny lgBtnColour button\"><!-- ko text: typeof rowText == \'function\' ? rowText($parent) : rowText --><!-- /ko --></a>' +
  173. '<!-- /ko -->' +
  174. '<!-- ko if: button && $data.hasOwnProperty(\'method\') && !$data.hasOwnProperty(\'permission\')-->' +
  175. ' <button data-bind=\"click: function(data,event) {$root.methodNav($parent, event, $data)}\" class=\"fluid ui tiny lgBtnColour button\"><!-- ko text: typeof rowText == \'function\' ? rowText($parent) : rowText --><!-- /ko --></button>' +
  176. '<!-- /ko -->' +
  177. '<!-- ko if: button && $data.hasOwnProperty(\'method\') && $data.hasOwnProperty(\'permission\') && !$data.hasOwnProperty(\'link\')-->' +
  178. ' <button data-bind=\"click: function(data,event) {$root.methodNav($parent, event, $data)}, permissions: permission\" class=\"fluid ui tiny lgBtnColour button\"><!-- ko text: typeof rowText == \'function\' ? rowText($parent) : rowText --><!-- /ko --></button>' +
  179. '<!-- /ko -->' +
  180. '<!-- ko if: !button && $data.hasOwnProperty(\'method\') && $data.hasOwnProperty(\'permission\') && $data.hasOwnProperty(\'link\')-->' +
  181. ' <!-- ko if: permission() -->' +
  182. ' <a data-bind=\"click: function(data,event) {$root.methodNav($parent, event, $data)}\"><!-- ko text: formatter($data, $parent[rowText]) --><!-- /ko --></a>' +
  183. ' <!-- /ko -->' +
  184. ' <!-- ko if: !permission() -->' +
  185. ' <label><!-- ko text: formatter($data, $parent[rowText]) --><!-- /ko --></label>' +
  186. ' <!-- /ko -->' +
  187. '<!-- /ko -->' +
  188. '<!-- ko if: !button && $data.hasOwnProperty(\'method\') && ($parent[rowText] === null) -->' +
  189. ' <!-- ko text: formatter($data, $parent[rowText]) --><!-- /ko -->' +
  190. '<!-- /ko -->' +
  191. '<!-- ko if: !button && $data.hasOwnProperty(\'method\') && ($parent[rowText] !== null) && !$data.hasOwnProperty(\'permission\') -->' +
  192. ' <a data-bind=\"click: function(data,event) {$root.methodNav($parent, event, $data)}\"><!-- ko text: formatter($data, $parent[rowText]) --><!-- /ko --></a>' +
  193. '<!-- /ko -->' +
  194. '<!-- ko if: !button && !$data.hasOwnProperty(\'method\') && !$data.hasOwnProperty(\'customTemplate\') && !$data.hasOwnProperty(\'lookup\') && !$data.hasOwnProperty(\'lookupCode\')-->' +
  195. ' <!-- ko text: typeof rowText == \'function\' ? rowText($parent) : formatter($data, $parent[rowText]) --><!-- /ko -->' +
  196. '<!-- /ko -->' +
  197. '<!-- ko if: $data.hasOwnProperty(\'lookup\') && $data.hasOwnProperty(\'lookupCode\')-->' +
  198. ' <!-- ko text: $parent[lookupCode].description --><!-- /ko -->' +
  199. '<!-- /ko -->';
  200.  
  201.  
  202. /*jshint multistr: true */
  203. var myTemplate =
  204. '<div class=\"computer tablet only row\">' +
  205. ' <div class=\"ui grid container\">' +
  206. ' <table class=\"ui littleGrid compact table\" data-bind=\"css: { detailed: $root.detail }\">' +
  207. ' <thead>' +
  208. ' <tr data-bind=\"foreach: $root.columns\">' +
  209. ' <td data-bind=\"text: headerText, css: $data.width\"></td>' +
  210. ' </tr>' +
  211. ' </thead>' +
  212. ' <tbody data-bind=\"foreach: $root.itemsOnCurrentPage\">' +
  213. ' <tr data-bind=\"foreach: $parent.columns\">' +
  214. ' <!-- ko if: $root.detail && expandButton -->' +
  215. ' <td data-bind=\"click: function(data,event) {$root.expandDetailedGrid($parent, event)}\" class=\"one wide\">' +
  216. ' <i class=\"icon icon-plusIcon\"></i>' +
  217. ' </td>' +
  218. ' <!-- /ko -->' +
  219. ' <!-- ko if: !$root.detail || ($root.detail && !expandButton) -->' +
  220. ' <td>' +
  221. rowTextTemplate +
  222. ' </td>' +
  223. ' <!-- /ko -->' +
  224. ' </tr>' +
  225. ' <!-- ko if: $root.detail -->' +
  226. ' <tr class=\"moreDetail\">' +
  227. ' <td data-bind=\"attr: { colspan: $root.columns.length }\" style=\" padding-top: 0; padding-bottom: 30px \">' +
  228. ' <div class=\"ui four column equal row grid\">' +
  229. ' <!-- ko foreach: $parent.detailColumns -->' +
  230. ' <!-- ko if: $root.detailNode.length > 0 -->' +
  231. ' <!-- ko foreach: $parent[$root.detailNode] -->' +
  232. ' <div class=\"column\" data-bind=\"attr: {id: $parent.rowText}\">' +
  233. ' <label data-bind=\"text: $parent.headerText\"></label>' +
  234. ' </div>' +
  235. ' <!-- ko if: $data.hasOwnProperty(\'lookup\') && $data.hasOwnProperty(\'lookupCode\')-->' +
  236. ' <div class=\"column\">' +
  237. ' <!-- ko text: $parent[lookupCode].description --><!-- /ko -->' +
  238. ' </div>' +
  239. ' <!-- /ko -->' +
  240. ' <!-- ko if: !$data.hasOwnProperty(\'lookup\') && !$data.hasOwnProperty(\'lookupCode\')-->' +
  241. ' <div class=\"column\">' +
  242. ' <label data-bind=\"text: typeof rowText == \'function\' ? rowText($parent) : formatter($parent, $data[$parent.rowText]) \"></label>' +
  243. ' </div>' +
  244. ' <!-- /ko -->' +
  245. ' <!-- /ko -->' +
  246. ' <!-- /ko -->' +
  247. ' <!-- ko if: $root.detailNode.length == 0 -->' +
  248. ' <!-- ko if: $data.hasOwnProperty(\'headerText\') -->' +
  249. ' <div class=\"column\" data-bind=\"attr: {id: $data.rowText}\">' +
  250. ' <label data-bind=\"text: headerText\"></label>' +
  251. ' </div>' +
  252. ' <!-- ko if: $data.hasOwnProperty(\'lookup\') && $data.hasOwnProperty(\'lookupCode\')-->' +
  253. ' <div class=\"column\">' +
  254. ' <!-- ko text: $parent[lookupCode].description --><!-- /ko -->' +
  255. ' </div>' +
  256. ' <!-- /ko -->' +
  257. ' <!-- ko if: !$data.hasOwnProperty(\'lookup\') && !$data.hasOwnProperty(\'lookupCode\')-->' +
  258. ' <div class=\"column\">' +
  259. ' <label data-bind=\"text: typeof rowText == \'function\' ? rowText($parent) : formatter($data, $parent[rowText]) \"></label>' +
  260. ' </div>' +
  261. ' <!-- /ko -->' +
  262. ' <!-- /ko -->' +
  263. ' <!-- ko if: $data.hasOwnProperty(\'rowTemplate\') -->' +
  264. ' <div class=\"column row\" data-bind=\"html: rowTemplate\"></div>' +
  265. ' <!-- /ko -->' +
  266. ' <!-- ko if: $data.hasOwnProperty(\'customTemplate\') -->' +
  267. ' <!-- ko template: customTemplate --><!-- /ko -->' +
  268. ' <!-- /ko -->' +
  269. ' <!-- /ko -->' +
  270. ' <!-- /ko -->' +
  271. ' </div>' +
  272. ' </td>' +
  273. ' </tr>' +
  274. ' <!-- /ko -->' +
  275. ' </tbody>' +
  276. pagerTemplate +
  277. ' </table>' +
  278. ' </div>' +
  279. '</div>';
  280.  
  281.  
  282. templateEngine.addTemplate("littleGrid", myTemplate);
  283.  
  284. // The "littleGrid" binding
  285. ko.bindingHandlers.littleGrid = {
  286. init: function () {
  287. return {'controlsDescendantBindings': true};
  288. },
  289. // This method is called to initialize the node, and will also be called again if you change what the grid is bound to
  290. update: function (element, viewModelAccessor, allBindings) {
  291. var viewModel = viewModelAccessor();
  292.  
  293. // Empty the element
  294. while (element.firstChild)
  295. ko.removeNode(element.firstChild);
  296.  
  297. // Allow the default templates to be overridden
  298. var gridTemplateName = allBindings.get('littleGridTemplate') || "littleGrid";
  299.  
  300. // Render the main grid
  301. var gridContainer = element.appendChild(document.createElement("DIV"));
  302. ko.renderTemplate(gridTemplateName, viewModel, {templateEngine: templateEngine}, gridContainer, "replaceNode");
  303. }
  304. };
  305. })();
  306.  
  307. //changes to values to lookups
  308. function reworkLookupsToObservables(columns, detailColumns, dataArray) {
  309. var lookupColumns = columns.filter(function (column) {
  310. return column.lookup && column.lookupCode;
  311. });
  312.  
  313. setLookupObservable(lookupColumns, dataArray);
  314.  
  315. if (detailColumns !== undefined) {
  316. var lookupDetailColumns = detailColumns.filter(function (column) {
  317. return column.lookup && column.lookupCode;
  318. });
  319.  
  320. setLookupObservable(lookupDetailColumns, dataArray);
  321. }
  322.  
  323. return dataArray;
  324. }
  325.  
  326. function setLookupObservable(columns, dataArray) {
  327.  
  328. if (columns.length) {
  329. if (dataArray && !jQuery.isEmptyObject(dataArray)) {
  330. dataArray.forEach(function (dataItem) {
  331. columns.forEach(function (column) {
  332. var lookupArray = column.lookup;//the lookup observableArray
  333. var codeProperty = column.lookupCode;//the property of the data item that is the code for the lookup
  334. var observ = ko.pureComputed(function () {
  335. var found = findArray(lookupArray(), dataItem[codeProperty]);
  336. if (found) {
  337. return found.description;
  338. } else {
  339. return '-';
  340. }
  341. });
  342. var value;
  343. var desc;
  344.  
  345. if (dataItem[codeProperty]) {
  346. if (dataItem[codeProperty].value) {
  347. value = dataItem[codeProperty].value;
  348. desc = dataItem[codeProperty].description;
  349. }
  350. else {
  351. value = dataItem[codeProperty];
  352. }
  353. }
  354. dataItem[codeProperty] = {
  355. value: value,
  356. description: desc ? desc : observ()
  357. };
  358. });
  359. });
  360. }
  361. }
  362. }
  363.  
  364. function findArray(arr, value) {
  365. return arr.filter(function (lookupItem) {
  366. return lookupItem.value === value;
  367. })[0];
  368. }
  369.  
  370. function columnsCheck(configuration, columns) {
  371. // ensure column configuration is correct
  372. for (var index in columns) {
  373. var column = columns[index];
  374. // only add the expand button if the detail setting is true
  375. if (configuration.detail) {
  376. column.expandButton = false;
  377. }
  378. // check to see that the button configuration is there
  379. if (column.button === undefined) {
  380. column.button = false;
  381. }
  382. // check to see that the width configuration is there
  383. if (column.width === undefined) {
  384. column.width = "";
  385. }
  386. // if there is a href on the column we need to see if there are placeholders that need replacing
  387. if (column.href !== undefined) {
  388. var href = column.href;
  389. column.hrefPlaceHolder = ""; // default placeholder will be an empty string
  390. // dynamically replace placeholder with value from items
  391. if (href.indexOf("{") > 0 && href.indexOf("}") > 0) {
  392. var placeholder = href.substring(href.indexOf("{") + 1, href.indexOf("}"));
  393. column.href = href.replace("{" + placeholder + "}", "");
  394. column.hrefPlaceHolder = placeholder;
  395. }
  396. }
  397. }
  398. }
  399.  
  400. /**
  401. * This method checks which columns data needs to be formatted on the grid while binding
  402. *
  403. * @param column
  404. * @param value
  405. * @returns {*}
  406. */
  407. function formatter(column, value) {
  408. if (!value || value === null || value.toString().toUpperCase() === "NULL" || value.toString().trim().length === 0) {
  409. return "-";
  410. }
  411.  
  412. if (column.money) {
  413. return currencyFormatter("$", value);
  414. }
  415. else if (column.dateFormat !== undefined && column.displayFormat !== undefined) {
  416. return moment(value, column.dateFormat).format(column.displayFormat);
  417. }
  418.  
  419. return value;
  420. }
  421.  
  422. function currencyFormatter(currencySymbol, value) {
  423.  
  424. if (currencySymbol) {
  425. if (value === ' ') {
  426. return "-";
  427. } else {
  428. var num = numberFormat(value);
  429.  
  430. if (num === "-") {
  431. return num;
  432. } else {
  433. return currencySymbol + " " + num;
  434. }
  435. }
  436.  
  437. } else {
  438.  
  439. return numberFormat(value);
  440.  
  441. }
  442.  
  443. }
  444.  
  445. function numberFormat(value) {
  446.  
  447. if (value) {
  448.  
  449. var strippedNumber = stripNumber(value);
  450.  
  451. if (isNumber(value)) {
  452.  
  453. var num = Number(strippedNumber);
  454. num = num.toFixed(2);
  455.  
  456. return num;
  457.  
  458. } else {
  459.  
  460. return "-";
  461.  
  462. }
  463.  
  464. } else {
  465.  
  466. return "-";
  467.  
  468. }
  469.  
  470. }
  471.  
  472. function stripNumber(n) {
  473.  
  474. if (n && !isNumber(n)) {
  475. var numberToStrip = n.trim();
  476.  
  477. var x = 0;
  478.  
  479. while (!isNumber(numberToStrip[x])) {
  480.  
  481. numberToStrip = numberToStrip.substring(x, numberToStrip.length);
  482. x++;
  483.  
  484. }
  485.  
  486. return numberToStrip.trim();
  487. } else {
  488. return n;
  489. }
  490.  
  491. }
  492.  
  493. function isNumber(n) {
  494. return !isNaN(parseFloat(n)) && isFinite(n);
  495. }
Add Comment
Please, Sign In to add comment