Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (function () {
- ko.littleGrid = {
- // Defines a view model class you can use to populate a grid
- viewModel: function (configuration) {
- var self = this;
- self.data = configuration.data;
- self.currentPageIndex = ko.observable(0);
- self.pager = configuration.pager || false;
- self.pageSize = configuration.pageSize || 5;
- self.columns = configuration.columns;
- self.detail = configuration.detail || false;
- self.detailNode = configuration.detailNode || "";
- self.detailMethod = configuration.detailMethod || "";
- self.detailColumns = configuration.detailColumns;
- self.detailReactive = configuration.detailReactive; // attribute that allows detail columns to be specified without detail being set to true or expand button showing
- self.noDefaultExpand = configuration.noDefaultExpand;
- // ensure column configuration is correct
- columnsCheck(configuration, self.columns);
- if (self.detail) {
- columnsCheck(configuration, self.detailColumns);
- // create the expand button item
- var expand = new Object({});
- expand.expandButton = true;
- expand.headerText = "";
- self.columns.splice(0, 0, expand);
- }
- else if (self.detailReactive) {
- columnsCheck(configuration, self.detailColumns);
- }
- self.itemsOnCurrentPage = ko.computed(function () {
- if (self.pager) {
- var startIndex = self.pageSize * self.currentPageIndex();
- return reworkLookupsToObservables(ko.unwrap(self.columns), ko.unwrap(self.detailColumns), ko.unwrap(self.data).slice(startIndex, startIndex + self.pageSize));
- }
- else {
- return reworkLookupsToObservables(ko.unwrap(self.columns), ko.unwrap(self.detailColumns), ko.unwrap(self.data));
- }
- }, self);
- self.maxPageIndex = ko.computed(function () {
- return Math.ceil(ko.unwrap(self.data).length / self.pageSize) - 1;
- }, self);
- self.jumpToFirstPage = function () {
- self.currentPageIndex(0);
- };
- self.jumpToLastPage = function () {
- self.currentPageIndex(Math.ceil(ko.unwrap(self.data).length / self.pageSize) - 1);
- };
- self.methodNav = function (data, element, column) {
- var theMethod = window[column.method];
- if (typeof theMethod === 'function') {
- theMethod(data, element);
- }
- };
- self.expandDetailedGrid = function (data, element) {
- // if the element is loading ignore it
- if (element.type === "readystatechange") {
- return;
- }
- var item = $(element.currentTarget),
- icon = $(item[0].children[0]);
- // collapse a detailed grid
- if (icon.hasClass("icon-minimizeMinusIcon")) {
- icon.removeClass("icon-minimizeMinusIcon");
- icon.addClass("icon-plusIcon");
- item.parent().next().hide();
- }
- // expand a detailed grid
- else {
- icon.addClass("icon-minimizeMinusIcon");
- icon.removeClass("icon-plusIcon");
- item.parent().next().show();
- }
- if (self.detailMethod.length > 0) {
- var theMethod = window[self.detailMethod];
- if (typeof theMethod === 'function') {
- theMethod(data, element);
- }
- }
- };
- self.expandMobileGrid = function (data, element) {
- // if the element is loading ignore it
- if (element.type === "readystatechange") {
- return;
- }
- var item = $(element.currentTarget);
- var moreInfo = item.parent().find(".moreDetail");
- if (moreInfo.length === 0) {
- moreInfo = $(item.parent().parent()[0].nextElementSibling);
- if (moreInfo.is(":visible")) {
- moreInfo.hide();
- }
- // expand a detailed grid
- else {
- moreInfo.show();
- if (!moreInfo.is(":visible")) {
- moreInfo.attr("style", "display: block !important;");
- }
- }
- }
- else {
- moreInfo.attr("style", "display: block !important;");
- item.attr("style", "display: none !important;");
- }
- };
- function toggleInfo(data, element) {
- var item = $(element.currentTarget),
- moreDetail = item.closest('tr').next();
- // collapse a detailed grid
- if (moreDetail.is(":visible")) {
- moreDetail.hide();
- }
- // expand a detailed grid
- else {
- moreDetail.show();
- }
- }
- }
- };
- // Templates used to render the grid
- var templateEngine = new ko.nativeTemplateEngine();
- templateEngine.addTemplate = function (templateName, templateMarkup) {
- $("head").append("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
- };
- /*jshint multistr: true */
- var pagerTemplate =
- '<!-- ko if: $root.pager -->' +
- ' <tfoot>' +
- ' <tr>' +
- ' <td data-bind=\"attr: { colspan: $root.columns.length }\">' +
- ' <div class=\"ui small pagination menu\">' +
- ' <a class=\"icon item\" data-bind=\"click: $root.jumpToFirstPage\">' +
- ' <i class=\"left arrow icon\"></i>' +
- ' </a>' +
- ' <!-- ko foreach: ko.utils.range(0, maxPageIndex) -->' +
- ' <a href=\"#\" class=\"item\" data-bind=\"text: $data + 1, click: function() { $root.currentPageIndex($data) }, css: { active: $data == $root.currentPageIndex() }\"></a>' +
- ' <!-- /ko -->' +
- ' <a class=\"icon item\" data-bind=\"click: $root.jumpToLastPage\">' +
- ' <i class=\"right arrow icon\"></i>' +
- ' </a>' +
- ' </div>' +
- ' </td>' +
- ' </tr>' +
- ' </tfoot>' +
- '<!-- /ko -->';
- /*jshint multistr: true */
- var rowTextTemplate =
- '<!-- ko if: $data.hasOwnProperty(\'customTemplate\') -->' +
- ' <!-- ko template: customTemplate --><!-- /ko -->' +
- '<!-- /ko -->' +
- '<!-- ko if: button && $data.hasOwnProperty(\'expand\') && !$data.hasOwnProperty(\'href\')-->' +
- ' <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>' +
- '<!-- /ko -->' +
- '<!-- ko if: button && $data.hasOwnProperty(\'href\') -->' +
- ' <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>' +
- '<!-- /ko -->' +
- '<!-- ko if: button && $data.hasOwnProperty(\'method\') && !$data.hasOwnProperty(\'permission\')-->' +
- ' <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>' +
- '<!-- /ko -->' +
- '<!-- ko if: button && $data.hasOwnProperty(\'method\') && $data.hasOwnProperty(\'permission\') && !$data.hasOwnProperty(\'link\')-->' +
- ' <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>' +
- '<!-- /ko -->' +
- '<!-- ko if: !button && $data.hasOwnProperty(\'method\') && $data.hasOwnProperty(\'permission\') && $data.hasOwnProperty(\'link\')-->' +
- ' <!-- ko if: permission() -->' +
- ' <a data-bind=\"click: function(data,event) {$root.methodNav($parent, event, $data)}\"><!-- ko text: formatter($data, $parent[rowText]) --><!-- /ko --></a>' +
- ' <!-- /ko -->' +
- ' <!-- ko if: !permission() -->' +
- ' <label><!-- ko text: formatter($data, $parent[rowText]) --><!-- /ko --></label>' +
- ' <!-- /ko -->' +
- '<!-- /ko -->' +
- '<!-- ko if: !button && $data.hasOwnProperty(\'method\') && ($parent[rowText] === null) -->' +
- ' <!-- ko text: formatter($data, $parent[rowText]) --><!-- /ko -->' +
- '<!-- /ko -->' +
- '<!-- ko if: !button && $data.hasOwnProperty(\'method\') && ($parent[rowText] !== null) && !$data.hasOwnProperty(\'permission\') -->' +
- ' <a data-bind=\"click: function(data,event) {$root.methodNav($parent, event, $data)}\"><!-- ko text: formatter($data, $parent[rowText]) --><!-- /ko --></a>' +
- '<!-- /ko -->' +
- '<!-- ko if: !button && !$data.hasOwnProperty(\'method\') && !$data.hasOwnProperty(\'customTemplate\') && !$data.hasOwnProperty(\'lookup\') && !$data.hasOwnProperty(\'lookupCode\')-->' +
- ' <!-- ko text: typeof rowText == \'function\' ? rowText($parent) : formatter($data, $parent[rowText]) --><!-- /ko -->' +
- '<!-- /ko -->' +
- '<!-- ko if: $data.hasOwnProperty(\'lookup\') && $data.hasOwnProperty(\'lookupCode\')-->' +
- ' <!-- ko text: $parent[lookupCode].description --><!-- /ko -->' +
- '<!-- /ko -->';
- /*jshint multistr: true */
- var myTemplate =
- '<div class=\"computer tablet only row\">' +
- ' <div class=\"ui grid container\">' +
- ' <table class=\"ui littleGrid compact table\" data-bind=\"css: { detailed: $root.detail }\">' +
- ' <thead>' +
- ' <tr data-bind=\"foreach: $root.columns\">' +
- ' <td data-bind=\"text: headerText, css: $data.width\"></td>' +
- ' </tr>' +
- ' </thead>' +
- ' <tbody data-bind=\"foreach: $root.itemsOnCurrentPage\">' +
- ' <tr data-bind=\"foreach: $parent.columns\">' +
- ' <!-- ko if: $root.detail && expandButton -->' +
- ' <td data-bind=\"click: function(data,event) {$root.expandDetailedGrid($parent, event)}\" class=\"one wide\">' +
- ' <i class=\"icon icon-plusIcon\"></i>' +
- ' </td>' +
- ' <!-- /ko -->' +
- ' <!-- ko if: !$root.detail || ($root.detail && !expandButton) -->' +
- ' <td>' +
- rowTextTemplate +
- ' </td>' +
- ' <!-- /ko -->' +
- ' </tr>' +
- ' <!-- ko if: $root.detail -->' +
- ' <tr class=\"moreDetail\">' +
- ' <td data-bind=\"attr: { colspan: $root.columns.length }\" style=\" padding-top: 0; padding-bottom: 30px \">' +
- ' <div class=\"ui four column equal row grid\">' +
- ' <!-- ko foreach: $parent.detailColumns -->' +
- ' <!-- ko if: $root.detailNode.length > 0 -->' +
- ' <!-- ko foreach: $parent[$root.detailNode] -->' +
- ' <div class=\"column\" data-bind=\"attr: {id: $parent.rowText}\">' +
- ' <label data-bind=\"text: $parent.headerText\"></label>' +
- ' </div>' +
- ' <!-- ko if: $data.hasOwnProperty(\'lookup\') && $data.hasOwnProperty(\'lookupCode\')-->' +
- ' <div class=\"column\">' +
- ' <!-- ko text: $parent[lookupCode].description --><!-- /ko -->' +
- ' </div>' +
- ' <!-- /ko -->' +
- ' <!-- ko if: !$data.hasOwnProperty(\'lookup\') && !$data.hasOwnProperty(\'lookupCode\')-->' +
- ' <div class=\"column\">' +
- ' <label data-bind=\"text: typeof rowText == \'function\' ? rowText($parent) : formatter($parent, $data[$parent.rowText]) \"></label>' +
- ' </div>' +
- ' <!-- /ko -->' +
- ' <!-- /ko -->' +
- ' <!-- /ko -->' +
- ' <!-- ko if: $root.detailNode.length == 0 -->' +
- ' <!-- ko if: $data.hasOwnProperty(\'headerText\') -->' +
- ' <div class=\"column\" data-bind=\"attr: {id: $data.rowText}\">' +
- ' <label data-bind=\"text: headerText\"></label>' +
- ' </div>' +
- ' <!-- ko if: $data.hasOwnProperty(\'lookup\') && $data.hasOwnProperty(\'lookupCode\')-->' +
- ' <div class=\"column\">' +
- ' <!-- ko text: $parent[lookupCode].description --><!-- /ko -->' +
- ' </div>' +
- ' <!-- /ko -->' +
- ' <!-- ko if: !$data.hasOwnProperty(\'lookup\') && !$data.hasOwnProperty(\'lookupCode\')-->' +
- ' <div class=\"column\">' +
- ' <label data-bind=\"text: typeof rowText == \'function\' ? rowText($parent) : formatter($data, $parent[rowText]) \"></label>' +
- ' </div>' +
- ' <!-- /ko -->' +
- ' <!-- /ko -->' +
- ' <!-- ko if: $data.hasOwnProperty(\'rowTemplate\') -->' +
- ' <div class=\"column row\" data-bind=\"html: rowTemplate\"></div>' +
- ' <!-- /ko -->' +
- ' <!-- ko if: $data.hasOwnProperty(\'customTemplate\') -->' +
- ' <!-- ko template: customTemplate --><!-- /ko -->' +
- ' <!-- /ko -->' +
- ' <!-- /ko -->' +
- ' <!-- /ko -->' +
- ' </div>' +
- ' </td>' +
- ' </tr>' +
- ' <!-- /ko -->' +
- ' </tbody>' +
- pagerTemplate +
- ' </table>' +
- ' </div>' +
- '</div>';
- templateEngine.addTemplate("littleGrid", myTemplate);
- // The "littleGrid" binding
- ko.bindingHandlers.littleGrid = {
- init: function () {
- return {'controlsDescendantBindings': true};
- },
- // This method is called to initialize the node, and will also be called again if you change what the grid is bound to
- update: function (element, viewModelAccessor, allBindings) {
- var viewModel = viewModelAccessor();
- // Empty the element
- while (element.firstChild)
- ko.removeNode(element.firstChild);
- // Allow the default templates to be overridden
- var gridTemplateName = allBindings.get('littleGridTemplate') || "littleGrid";
- // Render the main grid
- var gridContainer = element.appendChild(document.createElement("DIV"));
- ko.renderTemplate(gridTemplateName, viewModel, {templateEngine: templateEngine}, gridContainer, "replaceNode");
- }
- };
- })();
- //changes to values to lookups
- function reworkLookupsToObservables(columns, detailColumns, dataArray) {
- var lookupColumns = columns.filter(function (column) {
- return column.lookup && column.lookupCode;
- });
- setLookupObservable(lookupColumns, dataArray);
- if (detailColumns !== undefined) {
- var lookupDetailColumns = detailColumns.filter(function (column) {
- return column.lookup && column.lookupCode;
- });
- setLookupObservable(lookupDetailColumns, dataArray);
- }
- return dataArray;
- }
- function setLookupObservable(columns, dataArray) {
- if (columns.length) {
- if (dataArray && !jQuery.isEmptyObject(dataArray)) {
- dataArray.forEach(function (dataItem) {
- columns.forEach(function (column) {
- var lookupArray = column.lookup;//the lookup observableArray
- var codeProperty = column.lookupCode;//the property of the data item that is the code for the lookup
- var observ = ko.pureComputed(function () {
- var found = findArray(lookupArray(), dataItem[codeProperty]);
- if (found) {
- return found.description;
- } else {
- return '-';
- }
- });
- var value;
- var desc;
- if (dataItem[codeProperty]) {
- if (dataItem[codeProperty].value) {
- value = dataItem[codeProperty].value;
- desc = dataItem[codeProperty].description;
- }
- else {
- value = dataItem[codeProperty];
- }
- }
- dataItem[codeProperty] = {
- value: value,
- description: desc ? desc : observ()
- };
- });
- });
- }
- }
- }
- function findArray(arr, value) {
- return arr.filter(function (lookupItem) {
- return lookupItem.value === value;
- })[0];
- }
- function columnsCheck(configuration, columns) {
- // ensure column configuration is correct
- for (var index in columns) {
- var column = columns[index];
- // only add the expand button if the detail setting is true
- if (configuration.detail) {
- column.expandButton = false;
- }
- // check to see that the button configuration is there
- if (column.button === undefined) {
- column.button = false;
- }
- // check to see that the width configuration is there
- if (column.width === undefined) {
- column.width = "";
- }
- // if there is a href on the column we need to see if there are placeholders that need replacing
- if (column.href !== undefined) {
- var href = column.href;
- column.hrefPlaceHolder = ""; // default placeholder will be an empty string
- // dynamically replace placeholder with value from items
- if (href.indexOf("{") > 0 && href.indexOf("}") > 0) {
- var placeholder = href.substring(href.indexOf("{") + 1, href.indexOf("}"));
- column.href = href.replace("{" + placeholder + "}", "");
- column.hrefPlaceHolder = placeholder;
- }
- }
- }
- }
- /**
- * This method checks which columns data needs to be formatted on the grid while binding
- *
- * @param column
- * @param value
- * @returns {*}
- */
- function formatter(column, value) {
- if (!value || value === null || value.toString().toUpperCase() === "NULL" || value.toString().trim().length === 0) {
- return "-";
- }
- if (column.money) {
- return currencyFormatter("$", value);
- }
- else if (column.dateFormat !== undefined && column.displayFormat !== undefined) {
- return moment(value, column.dateFormat).format(column.displayFormat);
- }
- return value;
- }
- function currencyFormatter(currencySymbol, value) {
- if (currencySymbol) {
- if (value === ' ') {
- return "-";
- } else {
- var num = numberFormat(value);
- if (num === "-") {
- return num;
- } else {
- return currencySymbol + " " + num;
- }
- }
- } else {
- return numberFormat(value);
- }
- }
- function numberFormat(value) {
- if (value) {
- var strippedNumber = stripNumber(value);
- if (isNumber(value)) {
- var num = Number(strippedNumber);
- num = num.toFixed(2);
- return num;
- } else {
- return "-";
- }
- } else {
- return "-";
- }
- }
- function stripNumber(n) {
- if (n && !isNumber(n)) {
- var numberToStrip = n.trim();
- var x = 0;
- while (!isNumber(numberToStrip[x])) {
- numberToStrip = numberToStrip.substring(x, numberToStrip.length);
- x++;
- }
- return numberToStrip.trim();
- } else {
- return n;
- }
- }
- function isNumber(n) {
- return !isNaN(parseFloat(n)) && isFinite(n);
- }
Add Comment
Please, Sign In to add comment