|
|
/* * jsGrid v1.5.3 (http://js-grid.com)
* (c) 2016 Artem Tabalin * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
*/
(function (window, $, undefined) { var JSGRID = "JSGrid", JSGRID_DATA_KEY = JSGRID, JSGRID_ROW_DATA_KEY = "JSGridItem", JSGRID_EDIT_ROW_DATA_KEY = "JSGridEditRow",
SORT_ORDER_ASC = "asc", SORT_ORDER_DESC = "desc",
FIRST_PAGE_PLACEHOLDER = "{first}", PAGES_PLACEHOLDER = "{pages}", PREV_PAGE_PLACEHOLDER = "{prev}", NEXT_PAGE_PLACEHOLDER = "{next}", LAST_PAGE_PLACEHOLDER = "{last}", PAGE_INDEX_PLACEHOLDER = "{pageIndex}", PAGE_COUNT_PLACEHOLDER = "{pageCount}", ITEM_COUNT_PLACEHOLDER = "{itemCount}",
EMPTY_HREF = "javascript:void(0);";
var getOrApply = function (value, context) { if ($.isFunction(value)) { return value.apply(context, $.makeArray(arguments).slice(2)); } return value; };
var normalizePromise = function (promise) { var d = $.Deferred();
if (promise && promise.then) { promise.then(function () { d.resolve.apply(d, arguments); }, function () { d.reject.apply(d, arguments); }); } else { d.resolve(promise); }
return d.promise(); };
var defaultController = { loadData: $.noop, insertItem: $.noop, updateItem: $.noop, deleteItem: $.noop };
function Grid(element, config) { var $element = $(element);
$element.data(JSGRID_DATA_KEY, this);
this._container = $element;
this.data = []; this.total = 0;//John Add
this.fields = [];
this._editingRow = null; this._sortField = null; this._sortOrder = SORT_ORDER_ASC; this._firstDisplayingPage = 1;
this._init(config); this.render(); }
Grid.prototype = { width: "auto", height: "auto", updateOnResize: true,
rowClass: $.noop, rowRenderer: null,
rowClick: function (args) { if (this.editing) { this.editItem($(args.event.target).closest("tr")); } }, rowDoubleClick: $.noop, rowMouseDown: $.noop, rowMouseUp: $.noop, rowMouseUut: $.noop,
noDataContent: "Not found", noDataRowClass: "jsgrid-nodata-row",
heading: true, headerRowRenderer: null, headerRowClass: "jsgrid-header-row", headerCellClass: "jsgrid-header-cell",
filtering: false, filterRowRenderer: null, filterRowClass: "jsgrid-filter-row",
inserting: false, insertRowRenderer: null, insertRowClass: "jsgrid-insert-row",
editing: false, editRowRenderer: null, editRowClass: "jsgrid-edit-row",
confirmDeleting: true, deleteConfirm: "Are you sure?",
selecting: true, selectedRowClass: "jsgrid-selected-row", oddRowClass: "jsgrid-row", evenRowClass: "jsgrid-alt-row", cellClass: "jsgrid-cell",
sorting: false, sortableClass: "jsgrid-header-sortable", sortAscClass: "jsgrid-header-sort jsgrid-header-sort-asc", sortDescClass: "jsgrid-header-sort jsgrid-header-sort-desc",
paging: false, pagerContainer: null, pageIndex: 1, pageSize: 20, pageButtonCount: 15, //pagerFormat: "Pages: {first} {prev} {pages} {next} {last} {pageIndex} of {pageCount} {pagepernumber}",
pagerFormat: "{Total} {itemCount} {Pen} {first} {prev} {pages} {next} {last} {Numth} {pageIndex} {Page} {Total} {pageCount} {Page}", pagePrevText: "Prev", pageNextText: "Next", pageFirstText: "First", pageLastText: "Last", pageNavigatorNextText: "...", pageNavigatorPrevText: "...", pagerContainerClass: "jsgrid-pager-container", pagerClass: "jsgrid-pager", pagerNavButtonClass: "jsgrid-pager-nav-button", pagerNavButtonInactiveClass: "jsgrid-pager-nav-inactive-button", pageClass: "jsgrid-pager-page", currentPageClass: "jsgrid-pager-current-page",
customLoading: false, pageLoading: false,
autoload: false, controller: defaultController,
loadIndication: true, loadIndicationDelay: 500, loadMessage: "Please, wait...", loadShading: true,
invalidMessage: "Invalid data entered!",
invalidNotify: function (args) { var messages = $.map(args.errors, function (error) { return error.message || null; });
//window.alert([this.invalidMessage].concat(messages).join("\n"));
showMsg([this.invalidMessage].concat(messages).join("<br>"), 'info'); },
onInit: $.noop, onRefreshing: $.noop, onRefreshed: $.noop, onPageChanged: $.noop, onItemDeleting: $.noop, onItemDeleted: $.noop, onItemInserting: $.noop, onItemInserted: $.noop, onItemEditing: $.noop, onItemUpdating: $.noop, onItemUpdated: $.noop, onItemInvalid: $.noop, onDataLoading: $.noop, onDataLoaded: $.noop, onOptionChanging: $.noop, onOptionChanged: $.noop, onError: $.noop,
invalidClass: "jsgrid-invalid",
containerClass: "jsgrid", tableClass: "jsgrid-table", gridHeaderClass: "jsgrid-grid-header", gridBodyClass: "jsgrid-grid-body",
_init: function (config) { //debugger;
$.extend(this, config); this._initLoadStrategy(); this._initController(); this._initFields(); this._attachWindowLoadResize(); this._attachWindowResizeCallback(); this._callEventHandler(this.onInit); if (!this.dfheight) { this.dfheight = this.height; } },
loadStrategy: function () { return this.pageLoading ? new jsGrid.loadStrategies.PageLoadingStrategy(this) : new jsGrid.loadStrategies.DirectLoadingStrategy(this); },
_initLoadStrategy: function () { this._loadStrategy = getOrApply(this.loadStrategy, this); },
_initController: function () { this._controller = $.extend({}, defaultController, getOrApply(this.controller, this)); },
renderTemplate: function (source, context, config) { args = []; for (var key in config) { args.push(config[key]); }
args.unshift(source, context);
source = getOrApply.apply(null, args); return (source === undefined || source === null) ? "" : source; },
loadIndicator: function (config) { return new jsGrid.LoadIndicator(config); },
validation: function (config) { return jsGrid.Validation && new jsGrid.Validation(config); },
_initFields: function () { var self = this; self.fields = $.map(self.fields, function (field) { if ($.isPlainObject(field)) { var fieldConstructor = (field.type && jsGrid.fields[field.type]) || jsGrid.Field; field = new fieldConstructor(field); } field._grid = self; return field; }); },
_attachWindowLoadResize: function () { $(window).on("load", $.proxy(this._refreshSize, this)); },
_attachWindowResizeCallback: function () { if (this.updateOnResize) { $(window).on("resize", $.proxy(this._refreshSize, this)); } },
_detachWindowResizeCallback: function () { $(window).off("resize", this._refreshSize); },
option: function (key, value) { var optionChangingEventArgs, optionChangedEventArgs;
if (arguments.length === 1) return this[key];
optionChangingEventArgs = { option: key, oldValue: this[key], newValue: value }; this._callEventHandler(this.onOptionChanging, optionChangingEventArgs);
this._handleOptionChange(optionChangingEventArgs.option, optionChangingEventArgs.newValue);
optionChangedEventArgs = { option: optionChangingEventArgs.option, value: optionChangingEventArgs.newValue }; this._callEventHandler(this.onOptionChanged, optionChangedEventArgs); },
fieldOption: function (field, key, value) { field = this._normalizeField(field);
if (arguments.length === 2) return field[key];
field[key] = value; this._renderGrid(); },
_handleOptionChange: function (name, value) { this[name] = value;
switch (name) { case "width": case "height": this._refreshSize(); break; case "rowClass": case "rowRenderer": case "rowClick": case "rowDoubleClick": case "rowMouseDown": case "rowMouseUp": case "rowMouseUut": case "noDataRowClass": case "noDataContent": case "selecting": case "selectedRowClass": case "oddRowClass": case "evenRowClass": this._refreshContent(); break; case "pageButtonCount": case "pagerFormat": case "pagePrevText": case "pageNextText": case "pageFirstText": case "pageLastText": case "pageNavigatorNextText": case "pageNavigatorPrevText": case "pagerClass": case "pagerNavButtonClass": case "pageClass": case "currentPageClass": case "pagerRenderer": this._refreshPager(); break; case "fields": this._initFields(); this.render(); break; case "data": case "editing": case "heading": case "filtering": case "inserting": case "paging": this.refresh(); break; case "loadStrategy": case "pageLoading": this._initLoadStrategy(); this.search(); break; case "pageIndex": this.openPage(value); break; case "pageSize": this.refresh(); this.search(); break; case "editRowRenderer": case "editRowClass": this.cancelEdit(); break; case "updateOnResize": this._detachWindowResizeCallback(); this._attachWindowResizeCallback(); break; case "invalidNotify": case "invalidMessage": break; default: this.render(); break; } },
destroy: function () { this._detachWindowResizeCallback(); this._clear(); this._container.removeData(JSGRID_DATA_KEY); },
render: function () { this._renderGrid(); return this.autoload ? this.loadData() : $.Deferred().resolve().promise(); },
_renderGrid: function () { this._clear();
this._container.addClass(this.containerClass) .css("position", "relative") .append(this._createHeader()) .append(this._createBody());
this._pagerContainer = this._createPagerContainer(); this._loadIndicator = this._createLoadIndicator(); this._validation = this._createValidation();
this.refresh(); },
_createLoadIndicator: function () { return getOrApply(this.loadIndicator, this, { message: this.loadMessage, shading: this.loadShading, container: this._container }); },
_createValidation: function () { return getOrApply(this.validation, this); },
_clear: function () { this.cancelEdit();
clearTimeout(this._loadingTimer);
this._pagerContainer && this._pagerContainer.empty();
this._container.empty() .css({ position: "", width: "", height: "" }); },
_createHeader: function () { var $headerRow = this._headerRow = this._createHeaderRow(), $filterRow = this._filterRow = this._createFilterRow(), $insertRow = this._insertRow = this._createInsertRow();
var $headerGrid = this._headerGrid = $("<table>").addClass(this.tableClass) .append($headerRow) .append($filterRow) .append($insertRow);
var $header = this._header = $("<div>").addClass(this.gridHeaderClass) .addClass(this._scrollBarWidth() ? "jsgrid-header-scrollbar" : "") .append($headerGrid);
return $header; },
_createBody: function () { var $content = this._content = $("<tbody>");
var $bodyGrid = this._bodyGrid = $("<table>").addClass(this.tableClass) .append($content);
var $body = this._body = $("<div>").addClass(this.gridBodyClass) .append($bodyGrid) .on("scroll", $.proxy(function (e) { this._header.scrollLeft(e.target.scrollLeft); }, this));
return $body; },
_createPagerContainer: function () { var pagerContainer = this.pagerContainer || $("<div>").appendTo(this._container); return $(pagerContainer).addClass(this.pagerContainerClass); },
_eachField: function (callBack) { var self = this; $.each(this.fields, function (index, field) { if (field.visible) { callBack.call(self, field, index); } }); },
_createHeaderRow: function () { if ($.isFunction(this.headerRowRenderer)) return $(this.renderTemplate(this.headerRowRenderer, this));
var $result = $("<tr>").addClass(this.headerRowClass);
this._eachField(function (field, index) { var $th = this._prepareCell("<th>", field, "headercss", this.headerCellClass) .append(this.renderTemplate(field.headerTemplate, field));
if (field.title) { $th.attr('data-i18n', field.title); } $th.appendTo($result);
if (this.sorting && field.sorting) { $th.addClass(this.sortableClass) .on("click", $.proxy(function () { if (typeof this.headerClick === 'function') { this.headerClick(); } this.sort(index); }, this)); } });
return $result; },
_prepareCell: function (cell, field, cssprop, cellClass) { return $(cell).css("width", field.width) .addClass(cellClass || this.cellClass) .addClass((cssprop && field[cssprop]) || field.css) .addClass(field.align ? ("jsgrid-align-" + field.align) : ""); },
_createFilterRow: function () { if ($.isFunction(this.filterRowRenderer)) return $(this.renderTemplate(this.filterRowRenderer, this));
var $result = $("<tr>").addClass(this.filterRowClass);
this._eachField(function (field) { this._prepareCell("<td>", field, "filtercss") .append(this.renderTemplate(field.filterTemplate, field)) .appendTo($result); });
return $result; },
_createInsertRow: function () { if ($.isFunction(this.insertRowRenderer)) return $(this.renderTemplate(this.insertRowRenderer, this));
var $result = $("<tr>").addClass(this.insertRowClass);
this._eachField(function (field) { this._prepareCell("<td>", field, "insertcss") .append(this.renderTemplate(field.insertTemplate, field)) .appendTo($result); });
return $result; },
_callEventHandler: function (handler, eventParams) { handler.call(this, $.extend(eventParams, { grid: this }));
return eventParams; },
reset: function () { this._resetSorting(); this._resetPager(); return this._loadStrategy.reset(); },
_resetPager: function () { this._firstDisplayingPage = 1; this._setPage(1); },
_resetSorting: function () { this._sortField = null; this._sortOrder = SORT_ORDER_ASC; this._clearSortingCss(); },
refresh: function () { this._callEventHandler(this.onRefreshing);
this.cancelEdit();
this._refreshHeading(); this._refreshFiltering(); this._refreshInserting(); this._refreshContent(); this._refreshPager(); this._refreshSize();
this._callEventHandler(this.onRefreshed); },
_refreshHeading: function () { this._headerRow.toggle(this.heading); },
_refreshFiltering: function () { this._filterRow.toggle(this.filtering); },
_refreshInserting: function () { this._insertRow.toggle(this.inserting); },
_refreshContent: function () { var $content = this._content; $content.empty();
if (!this.data.length) { $content.append(this._createNoDataRow()); return this; }
var indexFrom = this._loadStrategy.firstDisplayIndex(); var indexTo = this._loadStrategy.lastDisplayIndex();
for (var itemIndex = indexFrom; itemIndex < indexTo; itemIndex++) { var item = this.data[itemIndex]; $content.append(this._createRow(item, itemIndex)); } },
_createNoDataRow: function () { var amountOfFields = 0; this._eachField(function () { amountOfFields++; });
return $("<tr>").addClass(this.noDataRowClass) .append($("<td>").addClass(this.cellClass).attr("colspan", amountOfFields) .append(this.renderTemplate(this.noDataContent, this))); },
_createRow: function (item, itemIndex) { var $result;
if ($.isFunction(this.rowRenderer)) { $result = this.renderTemplate(this.rowRenderer, this, { item: item, itemIndex: itemIndex }); } else { $result = $("<tr>"); this._renderCells($result, item); }
$result.addClass(this._getRowClasses(item, itemIndex)) .data(JSGRID_ROW_DATA_KEY, item) .on("click", $.proxy(function (e) { this.rowClick({ item: item, itemIndex: itemIndex, event: e }); $result.siblings().removeClass('grid-selected'); $result.addClass('grid-selected'); }, this)) .on("dblclick", $.proxy(function (e) { this.rowDoubleClick({ item: item, itemIndex: itemIndex, event: e }); }, this)) .on("mousedown", $.proxy(function (e) { this.rowMouseDown({ item: item, itemIndex: itemIndex, event: e }); }, this)) .on("mouseup", $.proxy(function (e) { this.rowMouseUp({ item: item, itemIndex: itemIndex, event: e }); }, this)) .on("mouseout", $.proxy(function (e) { this.rowMouseUut({ item: item, itemIndex: itemIndex, event: e }); }, this));
if (this.selecting) { this._attachRowHover($result); }
return $result; },
_getRowClasses: function (item, itemIndex) { var classes = []; classes.push(((itemIndex + 1) % 2) ? this.oddRowClass : this.evenRowClass); classes.push(getOrApply(this.rowClass, this, item, itemIndex)); return classes.join(" "); },
_attachRowHover: function ($row) { var selectedRowClass = this.selectedRowClass; $row.hover(function () { $(this).addClass(selectedRowClass); }, function () { $(this).removeClass(selectedRowClass); } ); },
_renderCells: function ($row, item) { this._eachField(function (field) { $row.append(this._createCell(item, field)); }); return this; },
_createCell: function (item, field) { var $result; var fieldValue = this._getItemFieldValue(item, field);
var args = { value: fieldValue, item: item }; if ($.isFunction(field.cellRenderer)) { $result = this.renderTemplate(field.cellRenderer, field, args); } else { $result = $("<td>").append(this.renderTemplate(field.itemTemplate || fieldValue, field, args)); }
return this._prepareCell($result, field); },
_getItemFieldValue: function (item, field) { var props = field.name.split('.'); var result = item[props.shift()];
while (result && props.length) { result = result[props.shift()]; }
return result; },
_setItemFieldValue: function (item, field, value) { var props = field.name.split('.'); var current = item; var prop = props[0];
while (current && props.length) { item = current; prop = props.shift(); current = item[prop]; }
if (!current) { while (props.length) { item = item[prop] = {}; prop = props.shift(); } }
item[prop] = value; },
sort: function (field, order) { if ($.isPlainObject(field)) { order = field.order; field = field.field; }
this._clearSortingCss(); this._setSortingParams(field, order); this._setSortingCss(); return this._loadStrategy.sort(); },
_clearSortingCss: function () { this._headerRow.find("th") .removeClass(this.sortAscClass) .removeClass(this.sortDescClass); },
_setSortingParams: function (field, order) { field = this._normalizeField(field); order = order || ((this._sortField === field) ? this._reversedSortOrder(this._sortOrder) : SORT_ORDER_ASC);
this._sortField = field; this._sortOrder = order; },
_normalizeField: function (field) { if ($.isNumeric(field)) { return this.fields[field]; }
if (typeof field === "string") { return $.grep(this.fields, function (f) { return f.name === field; })[0]; }
return field; },
_reversedSortOrder: function (order) { return (order === SORT_ORDER_ASC ? SORT_ORDER_DESC : SORT_ORDER_ASC); },
_setSortingCss: function () { var fieldIndex = this._visibleFieldIndex(this._sortField);
this._headerRow.find("th").eq(fieldIndex) .addClass(this._sortOrder === SORT_ORDER_ASC ? this.sortAscClass : this.sortDescClass); },
_visibleFieldIndex: function (field) { return $.inArray(field, $.grep(this.fields, function (f) { return f.visible; })); },
_sortData: function () { var sortFactor = this._sortFactor(), sortField = this._sortField;
if (sortField) { this.data.sort(function (item1, item2) { return sortFactor * sortField.sortingFunc(item1[sortField.name], item2[sortField.name]); }); } },
_sortFactor: function () { return this._sortOrder === SORT_ORDER_ASC ? 1 : -1; },
_itemsCount: function () { return this._loadStrategy.itemsCount(); },
_pagesCount: function () { //debugger;
var itemsCount = this._itemsCount(), pageSize = this.pageSize; return Math.floor(itemsCount / pageSize) + (itemsCount % pageSize ? 1 : 0); },
_refreshPager: function () { var $pagerContainer = this._pagerContainer; $pagerContainer.empty();
if (this.paging) { $pagerContainer.append(this._createPager()); }
var showPager = this.paging && this._pagesCount() > 1; if (!showPager) $pagerContainer.find('#PerPageNum').val(''); $pagerContainer.toggle(showPager); refreshLang(); },
_createPager: function () { var $result;
if ($.isFunction(this.pagerRenderer)) { $result = $(this.pagerRenderer({ pageIndex: this.pageIndex, pageCount: this._pagesCount() })); } else { $result = $("<div>").append(this._createPagerByFormat()).append([' <span data-i18n="common.PerPage"></span>', $('<input/>', {// ╠common.PerPage⇒每頁╣
id: 'PerPageNum', 'class': 'form-control w50', value: this.pageSize, keyup: function () { var sValue = this.value, sNewStr = ''; for (var i = 0; i < sValue.length; i++) { if (!isNaN(sValue[i])) { sNewStr += sValue[i]; } } this.value = sNewStr; } }), '<span data-i18n="common.Pen"></span>']);// ╠common.Pen⇒筆╣
}
$result.addClass(this.pagerClass);
return $result; },
_createPagerByFormat: function () { //debugger;
var pageIndex = this.pageIndex, pageCount = this._pagesCount(), itemCount = this._itemsCount(), pagerParts = this.pagerFormat.split(" ");
return $.map(pagerParts, $.proxy(function (pagerPart) { var result = pagerPart;
if (pagerPart === PAGES_PLACEHOLDER) { result = this._createPages(); } else if (pagerPart === FIRST_PAGE_PLACEHOLDER) { result = this._createPagerNavButton(this.pageFirstText, 1, pageIndex > 1); } else if (pagerPart === PREV_PAGE_PLACEHOLDER) { result = this._createPagerNavButton(this.pagePrevText, pageIndex - 1, pageIndex > 1); } else if (pagerPart === NEXT_PAGE_PLACEHOLDER) { result = this._createPagerNavButton(this.pageNextText, pageIndex + 1, pageIndex < pageCount); } else if (pagerPart === LAST_PAGE_PLACEHOLDER) { result = this._createPagerNavButton(this.pageLastText, pageCount, pageIndex < pageCount); } else if (pagerPart === PAGE_INDEX_PLACEHOLDER) { result = pageIndex; } else if (pagerPart === PAGE_COUNT_PLACEHOLDER) { result = pageCount; } else if (pagerPart === ITEM_COUNT_PLACEHOLDER) { result = itemCount; } else if (pagerPart === '{Total}') { result = '<span data-i18n="common.Total"></span>';// ╠common.Total⇒共╣
} else if (pagerPart === '{Pen}') { result = '<span data-i18n="common.Pen"></span>';// ╠common.Pen⇒筆╣
} else if (pagerPart === '{Numth}') { result = '<span data-i18n="common.Numth"></span>';// ╠common.Numth⇒第╣
} else if (pagerPart === '{Page}') { result = '<span data-i18n="common.Page"></span>';// ╠common.Page⇒頁╣
}
return $.isArray(result) ? result.concat([" "]) : [result, " "]; }, this)); },
_createPages: function () { var pageCount = this._pagesCount(), pageButtonCount = this.pageButtonCount, firstDisplayingPage = this._firstDisplayingPage, pages = [];
if (firstDisplayingPage > 1) { pages.push(this._createPagerPageNavButton(this.pageNavigatorPrevText, this.showPrevPages)); }
for (var i = 0, pageNumber = firstDisplayingPage; i < pageButtonCount && pageNumber <= pageCount; i++ , pageNumber++) { pages.push(pageNumber === this.pageIndex ? this._createPagerCurrentPage() : this._createPagerPage(pageNumber)); }
if ((firstDisplayingPage + pageButtonCount - 1) < pageCount) { pages.push(this._createPagerPageNavButton(this.pageNavigatorNextText, this.showNextPages)); }
return pages; },
_createPagerNavButton: function (text, pageIndex, isActive) { return this._createPagerButton(text, this.pagerNavButtonClass + (isActive ? "" : " " + this.pagerNavButtonInactiveClass), isActive ? function () { this.openPage(pageIndex); } : $.noop); },
_createPagerPageNavButton: function (text, handler) { return this._createPagerButton(text, this.pagerNavButtonClass, handler); },
_createPagerPage: function (pageIndex) { return this._createPagerButton(pageIndex, this.pageClass, function () { this.openPage(pageIndex); }); },
_createPagerButton: function (text, css, handler) { var $link = $("<a>").attr("href", EMPTY_HREF) .html(text) .on("click", $.proxy(handler, this));
return $("<span>").addClass(css).append($link); },
_createPagerCurrentPage: function () { return $("<span>") .addClass(this.pageClass) .addClass(this.currentPageClass) .text(this.pageIndex); },
_refreshSize: function () { this._refreshHeight(); this._refreshWidth(); },
_refreshWidth: function () { var width = (this.width === "auto") ? this._getAutoWidth() : this.width;
this._container.width(width); },
_getAutoWidth: function () { var $headerGrid = this._headerGrid, $header = this._header;
$headerGrid.width("auto");
var contentWidth = $headerGrid.outerWidth(); var borderWidth = $header.outerWidth() - $header.innerWidth();
$headerGrid.width("");
return contentWidth + borderWidth; },
_scrollBarWidth: (function () { var result;
return function () { if (result === undefined) { var $ghostContainer = $("<div style='width:50px;height:50px;overflow:hidden;position:absolute;top:-10000px;left:-10000px;'></div>"); var $ghostContent = $("<div style='height:100px;'></div>"); $ghostContainer.append($ghostContent).appendTo("body"); var width = $ghostContent.innerWidth(); $ghostContainer.css("overflow-y", "auto"); var widthExcludingScrollBar = $ghostContent.innerWidth(); $ghostContainer.remove(); result = width - widthExcludingScrollBar; } return result; }; })(),
_refreshHeight: function () { var container = this._container, pagerContainer = this._pagerContainer, height = this.height, nonBodyHeight;
container.height(height);
if (height !== "auto") { height = container.height();
nonBodyHeight = this._header.outerHeight(true); if (pagerContainer.parents(container).length) { nonBodyHeight += pagerContainer.outerHeight(true); }
this._body.outerHeight(height - (nonBodyHeight === 0 ? 90 : nonBodyHeight)); } },
showPrevPages: function () { var firstDisplayingPage = this._firstDisplayingPage, pageButtonCount = this.pageButtonCount;
this._firstDisplayingPage = (firstDisplayingPage > pageButtonCount) ? firstDisplayingPage - pageButtonCount : 1;
this._refreshPager(); },
showNextPages: function () { var firstDisplayingPage = this._firstDisplayingPage, pageButtonCount = this.pageButtonCount, pageCount = this._pagesCount();
this._firstDisplayingPage = (firstDisplayingPage + 2 * pageButtonCount > pageCount) ? pageCount - pageButtonCount + 1 : firstDisplayingPage + pageButtonCount;
this._refreshPager(); },
openPage: function (pageIndex) { //if (pageIndex < 1 || pageIndex > this._pagesCount())
// return;
this._setPage(pageIndex); this._loadStrategy.openPage(pageIndex); },
_setPage: function (pageIndex) { var firstDisplayingPage = this._firstDisplayingPage, pageButtonCount = this.pageButtonCount;
this.pageIndex = pageIndex;
if (pageIndex < firstDisplayingPage) { this._firstDisplayingPage = pageIndex; }
if (pageIndex > firstDisplayingPage + pageButtonCount - 1) { this._firstDisplayingPage = pageIndex - pageButtonCount + 1; }
this._callEventHandler(this.onPageChanged, { pageIndex: pageIndex }); },
_controllerCall: function (method, param, isCanceled, doneCallback) { if (isCanceled) return $.Deferred().reject().promise();
this._showLoading();
var controller = this._controller; if (!controller || !controller[method]) { throw Error("controller has no method '" + method + "'"); }
return normalizePromise(controller[method](param)) .done($.proxy(doneCallback, this)) .fail($.proxy(this._errorHandler, this)) .always($.proxy(this._hideLoading, this)); },
_errorHandler: function () { this._callEventHandler(this.onError, { args: $.makeArray(arguments) }); },
_showLoading: function () { if (!this.loadIndication) return;
clearTimeout(this._loadingTimer);
this._loadingTimer = setTimeout($.proxy(function () { this._loadIndicator.show(); }, this), this.loadIndicationDelay); },
_hideLoading: function () { if (!this.loadIndication) return;
clearTimeout(this._loadingTimer); this._loadIndicator.hide(); },
search: function (filter) { this._resetSorting(); this._resetPager(); return this.loadData(filter); },
loadData: function (filter) { //debugger;
filter = filter || (this.filtering ? this.getFilter() : {});
$.extend(filter, this._loadStrategy.loadParams(), this._sortingParams());
var args = this._callEventHandler(this.onDataLoading, { filter: filter });
return this._controllerCall("loadData", filter, args.cancel, function (res) { if (!res) { return; } var _data = {}, loadedData = {}; if (res.itemsCount >= 0) { loadedData = res; } else { if (res[0]) { res = res[0]; } if ((res.RESULT !== undefined && !res.RESULT) || (res.d !== undefined && !res.d)) { return; }
if (res.RESULT !== undefined) { _data = res.DATA.rel; if ($.isArray(_data)) { _data = { DataList: _data, Total: _data.length }; } } else { _data = JSON.parse(res.d); } loadedData = { data: _data.DataList, itemsCount: _data.Total }; }
this._loadStrategy.finishLoad(loadedData);
this._callEventHandler(this.onDataLoaded, { data: loadedData }); }); },
getFilter: function () { var result = {}; this._eachField(function (field) { if (field.filtering) { this._setItemFieldValue(result, field, field.filterValue()); } }); return result; },
_sortingParams: function () { if (this.sorting && this._sortField) { return { sortField: this._sortField.name, sortOrder: this._sortOrder }; } return {}; },
getSorting: function () { var sortingParams = this._sortingParams(); return { field: sortingParams.sortField, order: sortingParams.sortOrder }; },
clearFilter: function () { var $filterRow = this._createFilterRow(); this._filterRow.replaceWith($filterRow); this._filterRow = $filterRow; return this.search(); },
insertItem: function (item) { //debugger;
var insertingItem = item || this._getValidatedInsertItem();
if (!insertingItem) return $.Deferred().reject().promise();
var args = this._callEventHandler(this.onItemInserting, { item: insertingItem });
return this._controllerCall("insertItem", insertingItem, args.cancel, function (insertedItem) { //debugger;
insertedItem = insertedItem || insertingItem; this._loadStrategy.finishInsert(insertedItem);
this._callEventHandler(this.onItemInserted, { item: insertedItem }); }); },
_getValidatedInsertItem: function () { var item = this._getInsertItem(); return this._validateItem(item, this._insertRow) ? item : null; },
_getInsertItem: function () { var result = {}; this._eachField(function (field) { if (field.inserting) { this._setItemFieldValue(result, field, field.insertValue()); } }); return result; },
_validateItem: function (item, $row) { var validationErrors = [];
var args = { item: item, itemIndex: this._rowIndex($row), row: $row };
this._eachField(function (field) { if (!field.validate || ($row === this._insertRow && !field.inserting) || ($row === this._getEditRow() && !field.editing)) return;
var fieldValue = this._getItemFieldValue(item, field);
var errors = this._validation.validate($.extend({ value: fieldValue, rules: field.validate }, args));
this._setCellValidity($row.children().eq(this._visibleFieldIndex(field)), errors);
if (!errors.length) return;
validationErrors.push.apply(validationErrors, $.map(errors, function (message) { return { field: field, message: message }; })); });
if (!validationErrors.length) return true;
var invalidArgs = $.extend({ errors: validationErrors }, args); this._callEventHandler(this.onItemInvalid, invalidArgs); this.invalidNotify(invalidArgs);
return false; },
_setCellValidity: function ($cell, errors) { $cell .toggleClass(this.invalidClass, !!errors.length) .attr("title", errors.join("\n")); },
clearInsert: function () { var insertRow = this._createInsertRow(); this._insertRow.replaceWith(insertRow); this._insertRow = insertRow; this.refresh(); },
editItem: function (item) { var $row = this.rowByItem(item); if ($row.length) { this._editRow($row); } },
rowByItem: function (item) { if (item.jquery || item.nodeType) return $(item);
return this._content.find("tr").filter(function () { return $.data(this, JSGRID_ROW_DATA_KEY) === item; }); },
_editRow: function ($row) { if (!this.editing) return;
var item = $row.data(JSGRID_ROW_DATA_KEY);
var args = this._callEventHandler(this.onItemEditing, { row: $row, item: item, itemIndex: this._itemIndex(item) });
if (args.cancel) return;
if (this._editingRow) { this.cancelEdit(); }
var $editRow = this._createEditRow(item);
this._editingRow = $row; $row.hide(); $editRow.insertBefore($row); $row.data(JSGRID_EDIT_ROW_DATA_KEY, $editRow); },
_createEditRow: function (item) { if ($.isFunction(this.editRowRenderer)) { return $(this.renderTemplate(this.editRowRenderer, this, { item: item, itemIndex: this._itemIndex(item) })); }
var $result = $("<tr>").addClass(this.editRowClass);
this._eachField(function (field) { var fieldValue = this._getItemFieldValue(item, field);
this._prepareCell("<td>", field, "editcss") .append(this.renderTemplate(field.editTemplate || "", field, { value: fieldValue, item: item })) .appendTo($result); });
return $result; },
updateItem: function (item, editedItem) { //debugger;
if (arguments.length === 1) { editedItem = item; }
var $row = item ? this.rowByItem(item) : this._editingRow; editedItem = editedItem || this._getValidatedEditedItem();
if (!editedItem) return;
return this._updateRow($row, editedItem); },
_getValidatedEditedItem: function () { var item = this._getEditedItem(); return this._validateItem(item, this._getEditRow()) ? item : null; },
_updateRow: function ($updatingRow, editedItem) { //debugger;
var updatingItem = $updatingRow.data(JSGRID_ROW_DATA_KEY), updatingItemIndex = this._itemIndex(updatingItem), updatedItem = $.extend(true, {}, updatingItem, editedItem);
var args = this._callEventHandler(this.onItemUpdating, { row: $updatingRow, item: updatedItem, itemIndex: updatingItemIndex, previousItem: updatingItem });
return this._controllerCall("updateItem", updatedItem, args.cancel, function (res) { var loadedUpdatedItem = !res || typeof res.DATA.rel !== 'object' ? undefined : res.DATA.rel, previousItem = $.extend(true, {}, updatingItem); updatedItem = loadedUpdatedItem || $.extend(true, updatingItem, editedItem);
var $updatedRow = this._finishUpdate($updatingRow, updatedItem, updatingItemIndex);
this._callEventHandler(this.onItemUpdated, { row: $updatedRow, item: updatedItem, itemIndex: updatingItemIndex, previousItem: previousItem }); }); },
_rowIndex: function (row) { return this._content.children().index($(row)); },
_itemIndex: function (item) { return $.inArray(item, this.data); },
_finishUpdate: function ($updatingRow, updatedItem, updatedItemIndex) { this.cancelEdit(); this.data[updatedItemIndex] = updatedItem;
var $updatedRow = this._createRow(updatedItem, updatedItemIndex); $updatingRow.replaceWith($updatedRow); return $updatedRow; },
_getEditedItem: function () { var result = {}; this._eachField(function (field) { if (field.editing) { this._setItemFieldValue(result, field, field.editValue()); } }); return result; },
cancelEdit: function () { if (!this._editingRow) return;
this._getEditRow().remove(); this._editingRow.show(); this._editingRow = null; },
_getEditRow: function () { return this._editingRow && this._editingRow.data(JSGRID_EDIT_ROW_DATA_KEY); },
deleteItem: function (item) { //debugger;
var $row = this.rowByItem(item), _this = this;
if (!$row.length) return;
if (this.confirmDeleting) { layer.confirm(getOrApply(this.deleteConfirm, this, $row.data(JSGRID_ROW_DATA_KEY)), { icon: 3, title: i18next.t('common.Tips') }, function (index) { layer.close(index); //debugger;
return _this._deleteRow($row); }); }
//return this._deleteRow($row);
},
_deleteRow: function ($row) { var deletingItem = $row.data(JSGRID_ROW_DATA_KEY), deletingItemIndex = this._itemIndex(deletingItem);
var args = this._callEventHandler(this.onItemDeleting, { row: $row, item: deletingItem, itemIndex: deletingItemIndex });
return this._controllerCall("deleteItem", deletingItem, args.cancel, function () { this._loadStrategy.finishDelete(deletingItem, deletingItemIndex);
this._callEventHandler(this.onItemDeleted, { row: $row, item: deletingItem, itemIndex: deletingItemIndex }); }); } };
$.fn.jsGrid = function (config) { var args = $.makeArray(arguments), methodArgs = args.slice(1), result = this;
this.each(function () { var $element = $(this), instance = $element.data(JSGRID_DATA_KEY), methodResult;
if (instance) { if (typeof config === "string") { methodResult = instance[config].apply(instance, methodArgs); if (methodResult !== undefined && methodResult !== instance) { result = methodResult; return false; } } else { instance._detachWindowResizeCallback(); instance._init(config); instance.render(); } } else { new Grid($element, config); } });
return result; };
var fields = {};
var setDefaults = function (config) { var componentPrototype;
if ($.isPlainObject(config)) { componentPrototype = Grid.prototype; } else { componentPrototype = fields[config].prototype; config = arguments[1] || {}; }
$.extend(componentPrototype, config); };
var locales = {};
var locale = function (lang) { var localeConfig = $.isPlainObject(lang) ? lang : locales[lang];
if (!localeConfig) throw Error("unknown locale " + lang);
setLocale(jsGrid, localeConfig); };
var setLocale = function (obj, localeConfig) { $.each(localeConfig, function (field, value) { if ($.isPlainObject(value)) { setLocale(obj[field] || obj[field[0].toUpperCase() + field.slice(1)], value); return; }
if (obj.hasOwnProperty(field)) { obj[field] = value; } else { obj.prototype[field] = value; } }); };
window.jsGrid = { Grid: Grid, fields: fields, setDefaults: setDefaults, locales: locales, locale: locale, version: '1.5.3' }; }(window, jQuery));
(function (jsGrid, $, undefined) { function LoadIndicator(config) { this._init(config); }
LoadIndicator.prototype = { container: "body", message: "Loading...", shading: true,
zIndex: 1000, shaderClass: "jsgrid-load-shader", loadPanelClass: "jsgrid-load-panel",
_init: function (config) { $.extend(true, this, config);
this._initContainer(); this._initShader(); this._initLoadPanel(); },
_initContainer: function () { this._container = $(this.container); },
_initShader: function () { if (!this.shading) return;
this._shader = $("<div>").addClass(this.shaderClass) .hide() .css({ position: "absolute", top: 0, right: 0, bottom: 0, left: 0, zIndex: this.zIndex }) .appendTo(this._container); },
_initLoadPanel: function () { this._loadPanel = $("<div>").addClass(this.loadPanelClass) .text(this.message) .hide() .css({ position: "absolute", top: "50%", left: "50%", zIndex: this.zIndex }) .appendTo(this._container); },
show: function () { var $loadPanel = this._loadPanel.show();
var actualWidth = $loadPanel.outerWidth(); var actualHeight = $loadPanel.outerHeight();
$loadPanel.css({ marginTop: -actualHeight / 2, marginLeft: -actualWidth / 2 });
this._shader.show(); },
hide: function () { this._loadPanel.hide(); this._shader.hide(); } };
jsGrid.LoadIndicator = LoadIndicator; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { function DirectLoadingStrategy(grid) { this._grid = grid; }
DirectLoadingStrategy.prototype = { firstDisplayIndex: function () { var grid = this._grid; return grid.option("paging") ? (grid.option("pageIndex") - 1) * grid.option("pageSize") : 0; },
lastDisplayIndex: function () { var grid = this._grid; //var itemsCount = grid.option("data").length;
var itemsCount = grid.option("total").length;//John modified
return grid.option("paging") ? Math.min(grid.option("pageIndex") * grid.option("pageSize"), itemsCount) : itemsCount; },
itemsCount: function () { //return this._grid.option("data").length;
//debugger;
return this._grid.option("total").length;//John modified
},
openPage: function (index) { this._grid.refresh(); },
loadParams: function () { return {}; },
sort: function () { this._grid._sortData(); this._grid.refresh(); return $.Deferred().resolve().promise(); },
reset: function () { this._grid.refresh(); return $.Deferred().resolve().promise(); },
finishLoad: function (loadedData) { this._grid.option("data", loadedData); },
finishInsert: function (insertedItem) { var grid = this._grid; grid.option("data").push(insertedItem); grid.refresh(); },
finishDelete: function (deletedItem, deletedItemIndex) { var grid = this._grid; grid.option("data").splice(deletedItemIndex, 1); grid.reset(); } };
function PageLoadingStrategy(grid) { this._grid = grid; this._itemsCount = 0; }
PageLoadingStrategy.prototype = { firstDisplayIndex: function () { return 0; },
lastDisplayIndex: function () { return this._grid.option("data").length; },
itemsCount: function () { return this._itemsCount; },
openPage: function (index) { this._grid.loadData(); },
loadParams: function () { var grid = this._grid; return { pageIndex: grid.option("pageIndex"), pageSize: grid.option("pageSize") }; },
reset: function () { return this._grid.loadData(); },
sort: function () { return this._grid.loadData(); },
finishLoad: function (loadedData) { this._itemsCount = loadedData.itemsCount; this._grid.option("data", loadedData.data); },
finishInsert: function (insertedItem) { this._grid.search(); },
finishDelete: function (deletedItem, deletedItemIndex) { this._grid.search(); } };
jsGrid.loadStrategies = { DirectLoadingStrategy: DirectLoadingStrategy, PageLoadingStrategy: PageLoadingStrategy }; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { var isDefined = function (val) { return typeof (val) !== "undefined" && val !== null; };
var sortStrategies = { string: function (str1, str2) { if (!isDefined(str1) && !isDefined(str2)) return 0;
if (!isDefined(str1)) return -1;
if (!isDefined(str2)) return 1;
return ("" + str1).localeCompare("" + str2); },
number: function (n1, n2) { return n1 - n2; },
date: function (dt1, dt2) { return dt1 - dt2; },
numberAsString: function (n1, n2) { return parseFloat(n1) - parseFloat(n2); } };
jsGrid.sortStrategies = sortStrategies; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { function Validation(config) { this._init(config); }
Validation.prototype = { _init: function (config) { $.extend(true, this, config); },
validate: function (args) { var errors = [];
$.each(this._normalizeRules(args.rules), function (_, rule) { if (rule.validator(args.value, args.item, rule.param)) return;
var errorMessage = $.isFunction(rule.message) ? rule.message(args.value, args.item) : rule.message; errors.push(errorMessage); });
return errors; },
_normalizeRules: function (rules) { if (!$.isArray(rules)) rules = [rules];
return $.map(rules, $.proxy(function (rule) { return this._normalizeRule(rule); }, this)); },
_normalizeRule: function (rule) { if (typeof rule === "string") rule = { validator: rule };
if ($.isFunction(rule)) rule = { validator: rule };
if ($.isPlainObject(rule)) rule = $.extend({}, rule); else throw Error("wrong validation config specified");
if ($.isFunction(rule.validator)) return rule;
return this._applyNamedValidator(rule, rule.validator); },
_applyNamedValidator: function (rule, validatorName) { delete rule.validator;
var validator = validators[validatorName]; if (!validator) throw Error("unknown validator \"" + validatorName + "\"");
if ($.isFunction(validator)) { validator = { validator: validator }; }
return $.extend({}, validator, rule); } };
jsGrid.Validation = Validation;
var validators = { required: { message: "Field is required", validator: function (value) { return value !== undefined && value !== null && value !== ""; } },
rangeLength: { message: "Field value length is out of the defined range", validator: function (value, _, param) { return value.length >= param[0] && value.length <= param[1]; } },
minLength: { message: "Field value is too short", validator: function (value, _, param) { return value.length >= param; } },
maxLength: { message: "Field value is too long", validator: function (value, _, param) { return value.length <= param; } },
pattern: { message: "Field value is not matching the defined pattern", validator: function (value, _, param) { if (typeof param === "string") { param = new RegExp("^(?:" + param + ")$"); } return param.test(value); } },
range: { message: "Field value is out of the defined range", validator: function (value, _, param) { return value >= param[0] && value <= param[1]; } },
min: { message: "Field value is too small", validator: function (value, _, param) { return value >= param; } },
max: { message: "Field value is too large", validator: function (value, _, param) { return value <= param; } } };
jsGrid.validators = validators; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { function Field(config) { $.extend(true, this, config); this.sortingFunc = this._getSortingFunc(); }
Field.prototype = { name: "", title: null, css: "", align: "", width: 100,
visible: true, filtering: true, inserting: true, editing: true, sorting: true, sorter: "string", // name of SortStrategy or function to compare elements
headerTemplate: function () { return (this.title === undefined || this.title === null) ? this.name : this.title; },
itemTemplate: function (value, item) { return value; },
filterTemplate: function () { return ""; },
insertTemplate: function () { return ""; },
editTemplate: function (value, item) { this._value = value; return this.itemTemplate(value, item); },
filterValue: function () { return ""; },
insertValue: function () { return ""; },
editValue: function () { return this._value; },
_getSortingFunc: function () { var sorter = this.sorter;
if ($.isFunction(sorter)) { return sorter; }
if (typeof sorter === "string") { return jsGrid.sortStrategies[sorter]; }
throw Error("wrong sorter for the field \"" + this.name + "\"!"); } };
jsGrid.Field = Field; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { var Field = jsGrid.Field;
function TextField(config) { Field.call(this, config); }
TextField.prototype = new Field({ autosearch: true, readOnly: false,
filterTemplate: function () { if (!this.filtering) return "";
var grid = this._grid, $result = this.filterControl = this._createTextBox();
if (this.autosearch) { $result.on("keypress", function (e) { if (e.which === 13) { grid.search(); e.preventDefault(); } }); }
return $result; },
insertTemplate: function () { if (!this.inserting) return "";
return this.insertControl = this._createTextBox(); },
editTemplate: function (value) { if (!this.editing) return this.itemTemplate.apply(this, arguments);
var $result = this.editControl = this._createTextBox(); $result.val(value); return $result; },
filterValue: function () { return this.filterControl.val(); },
insertValue: function () { return this.insertControl.val(); },
editValue: function () { return this.editControl.val(); },
_createTextBox: function () { return $("<input>").attr("type", "text").attr("class", "form-control w100p") .prop("readonly", !!this.readOnly); } });
jsGrid.fields.text = jsGrid.TextField = TextField; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { var TextField = jsGrid.TextField;
function NumberField(config) { TextField.call(this, config); }
NumberField.prototype = new TextField({ sorter: "number", align: "right", readOnly: false,
filterValue: function () { return this.filterControl.val() ? parseInt(this.filterControl.val() || 0, 10) : undefined; },
insertValue: function () { return this.insertControl.val() ? parseInt(this.insertControl.val() || 0, 10) : undefined; },
editValue: function () { return this.editControl.val() ? parseInt(this.editControl.val() || 0, 10) : undefined; },
_createTextBox: function () { return $("<input>").attr("type", "number").attr("class", "form-control w100p") .prop("readonly", !!this.readOnly); } });
jsGrid.fields.number = jsGrid.NumberField = NumberField; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { var TextField = jsGrid.TextField;
function TextAreaField(config) { TextField.call(this, config); }
TextAreaField.prototype = new TextField({ insertTemplate: function () { if (!this.inserting) return "";
return this.insertControl = this._createTextArea(); },
editTemplate: function (value) { if (!this.editing) return this.itemTemplate.apply(this, arguments);
var $result = this.editControl = this._createTextArea(); $result.val(value); return $result; },
_createTextArea: function () { return $("<textarea>").prop("readonly", !!this.readOnly); } });
jsGrid.fields.textarea = jsGrid.TextAreaField = TextAreaField; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { var NumberField = jsGrid.NumberField; var numberValueType = "number"; var stringValueType = "string";
function SelectField(config) { this.items = []; this.selectedIndex = -1; this.valueField = ""; this.textField = "";
if (config.valueField && config.items.length) { var firstItemValue = config.items[0][config.valueField]; this.valueType = (typeof firstItemValue) === numberValueType ? numberValueType : stringValueType; }
this.sorter = this.valueType;
NumberField.call(this, config); }
SelectField.prototype = new NumberField({ align: "center", valueType: numberValueType,
itemTemplate: function (value) { var items = this.items, valueField = this.valueField, textField = this.textField, resultItem;
if (valueField) { resultItem = $.grep(items, function (item, index) { return item[valueField] === value; })[0] || {}; } else { resultItem = items[value]; }
var result = (textField ? resultItem[textField] : resultItem);
return (result === undefined || result === null) ? "" : result; },
filterTemplate: function () { if (!this.filtering) return "";
var grid = this._grid, $result = this.filterControl = this._createSelect();
if (this.autosearch) { $result.on("change", function (e) { grid.search(); }); }
return $result; },
insertTemplate: function () { if (!this.inserting) return "";
return this.insertControl = this._createSelect(); },
editTemplate: function (value) { if (!this.editing) return this.itemTemplate.apply(this, arguments);
var $result = this.editControl = this._createSelect(); (value !== undefined) && $result.val(value); return $result; },
filterValue: function () { var val = this.filterControl.val(); return this.valueType === numberValueType ? parseInt(val || 0, 10) : val; },
insertValue: function () { var val = this.insertControl.val(); return this.valueType === numberValueType ? parseInt(val || 0, 10) : val; },
editValue: function () { var val = this.editControl.val(); return this.valueType === numberValueType ? parseInt(val || 0, 10) : val; },
_createSelect: function () { var $result = $("<select>"), valueField = this.valueField, textField = this.textField, selectedIndex = this.selectedIndex;
$.each(this.items, function (index, item) { var value = valueField ? item[valueField] : index, text = textField ? item[textField] : item;
var $option = $("<option>") .attr("value", value) .text(text) .appendTo($result);
$option.prop("selected", (selectedIndex === index)); });
$result.prop("disabled", !!this.readOnly);
return $result; } });
jsGrid.fields.select = jsGrid.SelectField = SelectField; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { var Field = jsGrid.Field;
function CheckboxField(config) { Field.call(this, config); }
CheckboxField.prototype = new Field({ sorter: "number", align: "center", autosearch: true,
itemTemplate: function (value) { return this._createCheckbox().prop({ checked: value, disabled: true }); },
filterTemplate: function () { if (!this.filtering) return "";
var grid = this._grid, $result = this.filterControl = this._createCheckbox();
$result.prop({ readOnly: true, indeterminate: true });
$result.on("click", function () { var $cb = $(this);
if ($cb.prop("readOnly")) { $cb.prop({ checked: false, readOnly: false }); } else if (!$cb.prop("checked")) { $cb.prop({ readOnly: true, indeterminate: true }); } });
if (this.autosearch) { $result.on("click", function () { grid.search(); }); }
return $result; },
insertTemplate: function () { if (!this.inserting) return "";
return this.insertControl = this._createCheckbox(); },
editTemplate: function (value) { if (!this.editing) return this.itemTemplate.apply(this, arguments);
var $result = this.editControl = this._createCheckbox(); $result.prop("checked", value); return $result; },
filterValue: function () { return this.filterControl.get(0).indeterminate ? undefined : this.filterControl.is(":checked"); },
insertValue: function () { return this.insertControl.is(":checked"); },
editValue: function () { return this.editControl.is(":checked"); },
_createCheckbox: function () { return $("<input>").attr("type", "checkbox"); } });
jsGrid.fields.checkbox = jsGrid.CheckboxField = CheckboxField; }(jsGrid, jQuery));
(function (jsGrid, $, undefined) { var Field = jsGrid.Field;
function ControlField(config) { Field.call(this, config); this._configInitialized = false; }
ControlField.prototype = new Field({ css: "jsgrid-control-field", align: "center", width: 50, filtering: false, inserting: false, editing: false, sorting: false,
buttonClass: "jsgrid-button", modeButtonClass: "jsgrid-mode-button",
modeOnButtonClass: "jsgrid-mode-on-button", searchModeButtonClass: "jsgrid-search-mode-button", insertModeButtonClass: "jsgrid-insert-mode-button", editButtonClass: "jsgrid-edit-button", deleteButtonClass: "jsgrid-delete-button", searchButtonClass: "jsgrid-search-button", clearFilterButtonClass: "jsgrid-clear-filter-button", insertButtonClass: "jsgrid-insert-button", updateButtonClass: "jsgrid-update-button", cancelEditButtonClass: "jsgrid-cancel-edit-button",
searchModeButtonTooltip: "Switch to searching", insertModeButtonTooltip: "Switch to inserting", editButtonTooltip: "Edit", deleteButtonTooltip: "Delete", searchButtonTooltip: "Search", clearFilterButtonTooltip: "Clear filter", insertButtonTooltip: "Insert", updateButtonTooltip: "Update", cancelEditButtonTooltip: "Cancel edit",
editButton: true, deleteButton: true, clearFilterButton: true, modeSwitchButton: true,
_initConfig: function () { this._hasFiltering = this._grid.filtering; this._hasInserting = this._grid.inserting;
if (this._hasInserting && this.modeSwitchButton) { this._grid.inserting = false; }
this._configInitialized = true; },
headerTemplate: function () { if (!this._configInitialized) { this._initConfig(); }
var hasFiltering = this._hasFiltering; var hasInserting = this._hasInserting;
if (!this.modeSwitchButton || (!hasFiltering && !hasInserting)) return "";
if (hasFiltering && !hasInserting) return this._createFilterSwitchButton();
if (hasInserting && !hasFiltering) return this._createInsertSwitchButton();
return this._createModeSwitchButton(); },
itemTemplate: function (value, item) { var $result = $([]);
if (this.editButton) { $result = $result.add(this._createEditButton(item)); }
if (this.deleteButton) { $result = $result.add(this._createDeleteButton(item)); }
return $result; },
filterTemplate: function () { var $result = this._createSearchButton(); return this.clearFilterButton ? $result.add(this._createClearFilterButton()) : $result; },
insertTemplate: function () { return this._createInsertButton(); },
editTemplate: function () { return this._createUpdateButton().add(this._createCancelEditButton()); },
_createFilterSwitchButton: function () { return this._createOnOffSwitchButton("filtering", this.searchModeButtonClass, true); },
_createInsertSwitchButton: function () { return this._createOnOffSwitchButton("inserting", this.insertModeButtonClass, false); },
_createOnOffSwitchButton: function (option, cssClass, isOnInitially) { var isOn = isOnInitially;
var updateButtonState = $.proxy(function () { $button.toggleClass(this.modeOnButtonClass, isOn); }, this);
var $button = this._createGridButton(this.modeButtonClass + " " + cssClass, "", function (grid) { isOn = !isOn; grid.option(option, isOn); updateButtonState(); });
updateButtonState();
return $button; },
_createModeSwitchButton: function () { var isInserting = false;
var updateButtonState = $.proxy(function () { $button.attr("title", isInserting ? this.searchModeButtonTooltip : this.insertModeButtonTooltip) .toggleClass(this.insertModeButtonClass, !isInserting) .toggleClass(this.searchModeButtonClass, isInserting); }, this);
var $button = this._createGridButton(this.modeButtonClass, "", function (grid) { isInserting = !isInserting; grid.option("inserting", isInserting); grid.option("filtering", !isInserting); updateButtonState(); });
updateButtonState();
return $button; },
_createEditButton: function (item) { return this._createGridButton(this.editButtonClass, this.editButtonTooltip, function (grid, e) { grid.editItem(item); e.stopPropagation(); }); },
_createDeleteButton: function (item) { return this._createGridButton(this.deleteButtonClass, this.deleteButtonTooltip, function (grid, e) { grid.deleteItem(item); e.stopPropagation(); }); },
_createSearchButton: function () { return this._createGridButton(this.searchButtonClass, this.searchButtonTooltip, function (grid) { grid.search(); }); },
_createClearFilterButton: function () { return this._createGridButton(this.clearFilterButtonClass, this.clearFilterButtonTooltip, function (grid) { grid.clearFilter(); }); },
_createInsertButton: function () { return this._createGridButton(this.insertButtonClass, this.insertButtonTooltip, function (grid) { grid.insertItem().done(function () { grid.clearInsert(); }); }); },
_createUpdateButton: function () { return this._createGridButton(this.updateButtonClass, this.updateButtonTooltip, function (grid, e) { grid.updateItem(); e.stopPropagation(); }); },
_createCancelEditButton: function () { return this._createGridButton(this.cancelEditButtonClass, this.cancelEditButtonTooltip, function (grid, e) { grid.cancelEdit(); e.stopPropagation(); }); },
_createGridButton: function (cls, tooltip, clickHandler) { var grid = this._grid;
return $("<input>").addClass(this.buttonClass) .addClass(cls) .attr({ type: "button", title: tooltip }) .on("click", function (e) { clickHandler(grid, e); }); },
editValue: function () { return ""; } });
jsGrid.fields.control = jsGrid.ControlField = ControlField; }(jsGrid, jQuery));
|