From 3499bbf0632bee0c16a12056eea58cf52a37c699 Mon Sep 17 00:00:00 2001 From: alekseybobkov Date: Tue, 13 Jan 2015 21:05:45 -0800 Subject: [PATCH] Compiled Table JavaScript files, removed old table-min.js --- .../widgets/table/assets/js/build-min.js | 3986 ++++------------- .../widgets/table/assets/js/table-min.js | 3 - 2 files changed, 927 insertions(+), 3062 deletions(-) delete mode 100644 modules/backend/widgets/table/assets/js/table-min.js diff --git a/modules/backend/widgets/table/assets/js/build-min.js b/modules/backend/widgets/table/assets/js/build-min.js index b45a8e30b..240ff44e9 100644 --- a/modules/backend/widgets/table/assets/js/build-min.js +++ b/modules/backend/widgets/table/assets/js/build-min.js @@ -1,3060 +1,928 @@ -/* - * Table control class - * - * Dependences: - * - Scrollbar (october.scrollbar.js) - */ -+function ($) { "use strict"; - // TABLE CONTROL NAMESPACES - // ============================ - - if ($.oc === undefined) - $.oc = {} - - if ($.oc.table === undefined) - $.oc.table = {} - - // TABLE CLASS DEFINITION - // ============================ - - var Table = function(element, options) { - this.el = element - this.$el = $(element) - - this.options = options - - // - // State properties - // - - // The data source object - this.dataSource = null - - // The cell processors list - this.cellProcessors = {} - - // A reference to the currently active cell processor - this.activeCellProcessor = null - - // A reference to the currently active table cell - this.activeCell = null - - // A reference to the tables container - this.tableContainer = null - - // A reference to the data table container - this.dataTableContainer = null - - // The key of the row which is being edited at the moment. - // This key corresponds the data source row key which - // uniquely identifies the row in the data set. When the - // table grid notices that a cell in another row is edited it commits - // the previously edited record to the data source. - this.editedRowKey = null - - // A reference to the data table - this.dataTable = null - - // A reference to the header table - this.headerTable = null - - // A reference to the toolbar - this.toolbar = null - - // Event handlers - this.clickHandler = this.onClick.bind(this) - this.keydownHandler = this.onKeydown.bind(this) - this.documentClickHandler = this.onDocumentClick.bind(this) - this.toolbarClickHandler = this.onToolbarClick.bind(this) - - if (this.options.postback && this.options.clientDataSourceClass == 'client') - this.formSubmitHandler = this.onFormSubmit.bind(this) - - // Navigation helper - this.navigation = null - - // Number of records added or deleted during the session - this.recordsAddedOrDeleted = 0 - - // - // Initialization - // - - this.init() - } - - // INTERNAL METHODS - // ============================ - - Table.prototype.init = function() { - // Create the data source object - this.createDataSource() - - // Create cell processors - this.initCellProcessors() - - // Initialize helpers - this.navigation = new $.oc.table.helper.navigation(this) - - // Create the UI - this.buildUi() - - // Register event handlers - this.registerHandlers() - } - - Table.prototype.disposeCellProcessors = function() { - // For the performance reasons cell processors are stored - // in an object structure with keys matching the column names. - // We can iterate through then with the for cycle if we know - // the column names. We use the for cycle for the performance - // reasons: http://jsperf.com/for-vs-foreach/37, - // http://jonraasch.com/blog/10-javascript-performance-boosting-tips-from-nicholas-zakas - - for (var i = 0, len = this.options.columns.length; i < len; i++) { - var column = this.options.columns[i].key - - this.cellProcessors[column].dispose() - this.cellProcessors[column] = null - } - - this.cellProcessors = null - this.activeCellProcessor = null - } - - Table.prototype.createDataSource = function() { - var dataSourceClass = this.options.clientDataSourceClass - - if ($.oc.table.datasource === undefined || $.oc.table.datasource[dataSourceClass] == undefined) - throw new Error('The table client-side data source class "'+dataSourceClass+'" is not ' + - 'found in the $.oc.table.datasource namespace.') - - this.dataSource = new $.oc.table.datasource[dataSourceClass](this) - } - - Table.prototype.registerHandlers = function() { - this.el.addEventListener('click', this.clickHandler) - this.el.addEventListener('keydown', this.keydownHandler) - document.addEventListener('click', this.documentClickHandler) - - if (this.options.postback && this.options.clientDataSourceClass == 'client') - this.$el.closest('form').bind('oc.beforeRequest', this.formSubmitHandler) - - var toolbar = this.getToolbar() - if (toolbar) - toolbar.addEventListener('click', this.toolbarClickHandler); - } - - Table.prototype.unregisterHandlers = function() { - this.el.removeEventListener('click', this.clickHandler); - document.removeEventListener('click', this.documentClickHandler) - - this.clickHandler = null - - this.el.removeEventListener('keydown', this.keydownHandler); - this.keydownHandler = null - - var toolbar = this.getToolbar() - if (toolbar) - toolbar.removeEventListener('click', this.toolbarClickHandler); - - this.toolbarClickHandler = null - - if (this.formSubmitHandler) { - this.$el.closest('form').unbind('oc.beforeRequest', this.formSubmitHandler) - this.formSubmitHandler = null - } - } - - Table.prototype.initCellProcessors = function() { - for (var i = 0, len = this.options.columns.length; i < len; i++) { - var columnConfiguration = this.options.columns[i], - column = columnConfiguration.key, - columnType = columnConfiguration.type - - // Resolve the default column type to string - if (columnType === undefined) { - columnType = 'string' - this.options.columns[i].type = columnType - } - - if ($.oc.table.processor === undefined || $.oc.table.processor[columnType] == undefined) - throw new Error('The table cell processor for the column type "'+columnType+'" is not ' + - 'found in the $.oc.table.processor namespace.') - - this.cellProcessors[column] = new $.oc.table.processor[columnType](this, column, columnConfiguration) - } - } - - Table.prototype.getCellProcessor = function(columnName) { - return this.cellProcessors[columnName] - } - - Table.prototype.buildUi = function() { - this.tableContainer = document.createElement('div') - this.tableContainer.setAttribute('class', 'table-container') - - // Build the toolbar - if (this.options.toolbar) - this.buildToolbar() - - // Build the headers table - this.tableContainer.appendChild(this.buildHeaderTable()) - - // Append the table container to the element - this.el.insertBefore(this.tableContainer, this.el.children[0]) - - if (!this.options.height) - this.dataTableContainer = this.tableContainer - else - this.dataTableContainer = this.buildScrollbar() - - // Build the data table - this.updateDataTable() - } - - Table.prototype.buildToolbar = function() { - if (!this.options.adding && !this.options.deleting) - return - - this.toolbar = document.createElement('div') - this.toolbar.setAttribute('class', 'toolbar') - - if (this.options.adding) { - var addBelowButton = document.createElement('a') - addBelowButton.setAttribute('class', 'btn add-table-row-below') - addBelowButton.setAttribute('data-cmd', 'record-add-below') - this.toolbar.appendChild(addBelowButton) - - if (this.navigation.paginationEnabled() || !this.options.rowSorting) { - // When the pagination is enabled, or sorting is disabled, - // new records can only be added to the bottom of the - // table. - addBelowButton.textContent = 'Add row' - } else { - addBelowButton.textContent = 'Add row below' - - var addAboveButton = document.createElement('a') - addAboveButton.setAttribute('class', 'btn add-table-row-above') - addAboveButton.textContent = 'Add row above' - addAboveButton.setAttribute('data-cmd', 'record-add-above') - this.toolbar.appendChild(addAboveButton) - } - } - - if (this.options.deleting) { - var deleteButton = document.createElement('a') - deleteButton.setAttribute('class', 'btn delete-table-row') - deleteButton.textContent = 'Delete row' - deleteButton.setAttribute('data-cmd', 'record-delete') - this.toolbar.appendChild(deleteButton) - } - - this.tableContainer.appendChild(this.toolbar) - } - - Table.prototype.buildScrollbar = function() { - var scrollbar = document.createElement('div'), - scrollbarContent = document.createElement('div') - - scrollbar.setAttribute('class', 'control-scrollbar') - - if (this.options.dynamicHeight) - scrollbar.setAttribute('style', 'max-height: ' + this.options.height + 'px') - else - scrollbar.setAttribute('style', 'height: ' + this.options.height + 'px') - - scrollbar.appendChild(scrollbarContent) - this.tableContainer.appendChild(scrollbar) - - $(scrollbar).scrollbar({animation: false}) - - return scrollbarContent - } - - Table.prototype.buildHeaderTable = function() { - var headersTable = document.createElement('table'), - row = document.createElement('tr') - - headersTable.className = 'headers' - headersTable.appendChild(row) - - for (var i = 0, len = this.options.columns.length; i < len; i++) { - var header = document.createElement('th') - - if (this.options.columns[i].width) - header.setAttribute('style', 'width: '+this.options.columns[i].width) - - header.textContent !== undefined - ? header.textContent = this.options.columns[i].title - : header.innerText = this.options.columns[i].title - - row.appendChild(header) - } - - this.headerTable = headersTable - - return headersTable - } - - Table.prototype.updateDataTable = function(onSuccess) { - var self = this - - this.unfocusTable() - - this.fetchRecords(function onUpdateDataTableSuccess(records, totalCount){ - self.buildDataTable(records, totalCount) - - if (onSuccess) - onSuccess() - - if (totalCount == 0) - self.addRecord('above', true) - - self = null - }) - } - - Table.prototype.updateColumnWidth = function() { - var headerCells = this.headerTable.querySelectorAll('th'), - dataCells = this.dataTable.querySelectorAll('tr:first-child td') - - for (var i = 0, len = headerCells.length; i < len; i++) { - if (dataCells[i]) - dataCells[i].setAttribute('style', headerCells[i].getAttribute('style')) - } - } - - Table.prototype.buildDataTable = function(records, totalCount) { - var dataTable = document.createElement('table'), - tbody = document.createElement('tbody'), - keyColumn = this.options.keyColumn - - dataTable.setAttribute('class', 'data') - - for (var i = 0, len = records.length; i < len; i++) { - var row = document.createElement('tr') - - if (records[i][keyColumn] === undefined) - throw new Error('The row attribute '+keyColumn+' is not set for the row #'+i); - - row.setAttribute('data-row', records[i][keyColumn]) - for (var j = 0, colsLen = this.options.columns.length; j < colsLen; j++) { - var cell = document.createElement('td'), - dataContainer = document.createElement('input'), - cellContentContainer = document.createElement('div'), - column = this.options.columns[j], - columnName = column.key, - cellProcessor = this.getCellProcessor(columnName) - - cell.setAttribute('data-column', columnName) - cell.setAttribute('data-column-type', column.type) - - dataContainer.setAttribute('type', 'hidden') - dataContainer.setAttribute('data-container', 'data-container') - dataContainer.value = records[i][columnName] !== undefined ? - records[i][columnName] : - "" - - cellContentContainer.setAttribute('class', 'content-container') - - cell.appendChild(cellContentContainer) - row.appendChild(cell) - cell.appendChild(dataContainer) - - cellProcessor.renderCell(records[i][columnName], cellContentContainer) - } - - tbody.appendChild(row) - } - - dataTable.appendChild(tbody) - - // Inject the data table to the DOM or replace the existing table - if (this.dataTable !== null) - this.dataTableContainer.replaceChild(dataTable, this.dataTable) - else - this.dataTableContainer.appendChild(dataTable) - - this.dataTable = dataTable - - // Update column widths - this.updateColumnWidth() - - // Update the scrollbar - this.updateScrollbar() - - // Update the pagination links - this.navigation.buildPagination(totalCount) - } - - Table.prototype.fetchRecords = function(onSuccess) { - this.dataSource.getRecords( - this.navigation.getPageFirstRowOffset(), - this.options.recordsPerPage, - onSuccess) - } - - Table.prototype.updateScrollbar = function() { - if (!this.options.height) - return - - $(this.dataTableContainer.parentNode).data('oc.scrollbar').update() - } - - Table.prototype.scrollCellIntoView = function() { - if (!this.options.height || !this.activeCell) - return - - $(this.dataTableContainer.parentNode).data('oc.scrollbar').gotoElement(this.activeCell) - } - - Table.prototype.disposeScrollbar = function() { - if (!this.options.height) - return - - $(this.dataTableContainer.parentNode).data('oc.scrollbar').dispose() - $(this.dataTableContainer.parentNode).data('oc.scrollbar', null) - } - - /* - * Makes a cell processor active and hides the previously - * active editor. - */ - Table.prototype.setActiveProcessor = function(processor) { - if (this.activeCellProcessor) - this.activeCellProcessor.onUnfocus() - - this.activeCellProcessor = processor - } - - Table.prototype.commitEditedRow = function() { - if (this.editedRowKey === null) - return - - var editedRow = this.dataTable.querySelector('tr[data-row="'+this.editedRowKey+'"]') - if (!editedRow) - return - - if (editedRow.getAttribute('data-dirty') != 1) - return - - var cells = editedRow.children, - data = {} - - for (var i=0, len = cells.length; i < len; i++) { - var cell = cells[i] - - data[cell.getAttribute('data-column')] = this.getCellValue(cell) - } - - this.dataSource.updateRecord(this.editedRowKey, data) - editedRow.setAttribute('data-dirty', 0) - } - - /* - * Removes editor from the currently edited cell and commits the row if needed. - */ - Table.prototype.unfocusTable = function() { - this.elementRemoveClass(this.el, 'active') - - if (this.activeCellProcessor) - this.activeCellProcessor.onUnfocus() - - this.commitEditedRow() - this.activeCellProcessor = null - - if (this.activeCell) - this.activeCell.setAttribute('class', '') - - this.activeCell = null - } - - /* - * Makes the table focused in the UI - */ - Table.prototype.focusTable = function() { - this.elementAddClass(this.el, 'active') - } - - /* - * Calls the onFocus() method for the cell processor responsible for the - * newly focused cell. Commit the previous edited row to the data source - * if needed. - */ - Table.prototype.focusCell = function(cellElement, isClick) { - var columnName = cellElement.getAttribute('data-column') - if (columnName === null) - return - - this.focusTable() - - var processor = this.getCellProcessor(columnName) - if (!processor) - throw new Error("Cell processor not found for the column "+columnName) - - if (this.activeCell !== cellElement) { - if (this.activeCell) - this.elementRemoveClass(this.activeCell, 'active') - - this.setActiveProcessor(processor) - this.activeCell = cellElement - - if (processor.isCellFocusable()) - this.elementAddClass(this.activeCell, 'active') - } - - // If the cell belongs to other row than the currently edited, - // commit currently edited row to the data source. Update the - // currently edited row key. - var rowKey = this.getCellRowKey(cellElement) - - if (this.editedRowKey !== null && rowKey != this.editedRowKey) - this.commitEditedRow() - - this.editedRowKey = rowKey - - processor.onFocus(cellElement, isClick) - - this.scrollCellIntoView() - } - - Table.prototype.markCellRowDirty = function(cellElement) { - cellElement.parentNode.setAttribute('data-dirty', 1) - } - - Table.prototype.addRecord = function(placement, noFocus) { - // If there is no active cell, or the pagination is enabled or - // row sorting is disabled, add the record to the bottom of - // the table (last page). - - if (!this.activeCell || this.navigation.paginationEnabled() || !this.options.rowSorting) - placement = 'bottom' - - var relativeToKey = null, - currentRowIndex = null - - if (placement == 'above' || placement == 'below') { - relativeToKey = this.getCellRowKey(this.activeCell) - currentRowIndex = this.getCellRowIndex(this.activeCell) - } - - this.unfocusTable() - - if (this.navigation.paginationEnabled()) { - var newPageIndex = this.navigation.getNewRowPage(placement, currentRowIndex) - - if (newPageIndex != this.navigation.pageIndex) { - // Validate data on the current page if adding a new record - // is going to create another page. - if (!this.validate()) - return - } - - this.navigation.pageIndex = newPageIndex - } - - this.recordsAddedOrDeleted++ - - // New records have negative keys - var keyColumn = this.options.keyColumn, - recordData = {}, - self = this - - recordData[keyColumn] = -1*this.recordsAddedOrDeleted - - this.dataSource.createRecord(recordData, placement, relativeToKey, - this.navigation.getPageFirstRowOffset(), - this.options.recordsPerPage, - function onAddRecordDataTableSuccess(records, totalCount) { - self.buildDataTable(records, totalCount) - - var row = self.findRowByKey(recordData[keyColumn]) - if (!row) - throw new Error('New row is not found in the updated table: '+recordData[keyColumn]) - - if (!noFocus) - self.navigation.focusCell(row, 0) - - self = null - } - ) - } - - Table.prototype.deleteRecord = function() { - if (!this.activeCell) - return - - var currentRowIndex = this.getCellRowIndex(this.activeCell), - key = this.getCellRowKey(this.activeCell), - self = this, - paginationEnabled = this.navigation.paginationEnabled(), - currentPageIndex = this.navigation.pageIndex, - currentCellIndex = this.activeCell.cellIndex - - if (paginationEnabled) - this.navigation.pageIndex = this.navigation.getPageAfterDeletion(currentRowIndex) - - this.recordsAddedOrDeleted++ - - // New records have negative keys - var keyColumn = this.options.keyColumn, - newRecordData = {} - - newRecordData[keyColumn] = -1*this.recordsAddedOrDeleted - - this.dataSource.deleteRecord(key, - newRecordData, - this.navigation.getPageFirstRowOffset(), - this.options.recordsPerPage, - function onDeleteRecordDataTableSuccess(records, totalCount) { - self.buildDataTable(records, totalCount) - - if (!paginationEnabled) - self.navigation.focusCellInReplacedRow(currentRowIndex, currentCellIndex) - else { - if (currentPageIndex != self.navigation.pageIndex) - self.navigation.focusCell('bottom', currentCellIndex) - else - self.navigation.focusCellInReplacedRow(currentRowIndex, currentCellIndex) - } - - self = null - } - ) - } - - Table.prototype.notifyRowProcessorsOnChange = function(cellElement) { - var columnName = cellElement.getAttribute('data-column'), - row = cellElement.parentNode - - for (var i = 0, len = row.children.length; i < len; i++) { - var column = this.options.columns[i].key - - this.cellProcessors[column].onRowValueChanged(columnName, row.children[i]) - } - } - - Table.prototype.getToolbar = function() { - return this.tableContainer.querySelector('div.toolbar') - } - - /* - * Validaates data on the current page - */ - Table.prototype.validate = function() { - var rows = this.dataTable.querySelectorAll('tbody tr[data-row]') - - for (var i = 0, len = rows.length; i < len; i++) { - var row = rows[i] - - this.elementRemoveClass(row, 'error') - } - - for (var i = 0, rowsLen = rows.length; i < rowsLen; i++) { - var row = rows[i], - rowData = this.getRowData(row) - - for (var j = 0, colsLen = row.children.length; j < colsLen; j++) - this.elementRemoveClass(row.children[j], 'error') - - for (var columnName in rowData) { - var cellProcessor = this.getCellProcessor(columnName), - message = cellProcessor.validate(rowData[columnName], rowData) - - if (message !== undefined) { - var cell = row.querySelector('td[data-column="'+columnName+'"]'), - self = this - - this.elementAddClass(row, 'error') - this.elementAddClass(cell, 'error') - - $.oc.flashMsg({text: message, 'class': 'error'}) - - window.setTimeout(function(){ - self.focusCell(cell, false) - cell = null - self = null - cellProcessor = null - }, 100) - return false - } - } - } - - return true - } - - // EVENT HANDLERS - // ============================ - - Table.prototype.onClick = function(ev) { - this.focusTable() - - if (this.navigation.onClick(ev) === false) - return - - for (var i = 0, len = this.options.columns.length; i < len; i++) { - var column = this.options.columns[i].key - - this.cellProcessors[column].onClick(ev) - } - - var target = this.getEventTarget(ev, 'TD') - - if (!target) - return - - if (target.tagName != 'TD') - return - - this.focusCell(target, true) - } - - Table.prototype.onKeydown = function(ev) { - if (ev.keyCode == 65 && ev.altKey && this.options.adding) { - if (!ev.shiftKey) { - // alt+a - add record below - this.addRecord('below') - } else { - // alt+shift+a - add record above - this.addRecord('above') - } - - this.stopEvent(ev) - return - } - - if (ev.keyCode == 68 && ev.altKey && this.options.deleting) { - // alt+d - delete record - this.deleteRecord() - - this.stopEvent(ev) - return - } - - for (var i = 0, len = this.options.columns.length; i < len; i++) { - var column = this.options.columns[i].key - - this.cellProcessors[column].onKeyDown(ev) - } - - if (this.navigation.onKeydown(ev) === false) - return - } - - Table.prototype.onFormSubmit = function(ev, data) { - if (data.handler == this.options.postbackHandlerName) { - this.unfocusTable() - - if (!this.validate()) { - ev.preventDefault() - return - } - - var fieldName = this.options.alias.indexOf('[') > -1 ? - this.options.alias + '[TableData]' : - this.options.alias + 'TableData'; - - data.options.data[fieldName] = this.dataSource.getAllData() - } - } - - Table.prototype.onToolbarClick = function(ev) { - var target = this.getEventTarget(ev), - cmd = target.getAttribute('data-cmd') - - switch (cmd) { - case 'record-add-below': - this.addRecord('below') - break - case 'record-add-above': - this.addRecord('above') - break - case 'record-delete': - this.deleteRecord() - break - } - - this.stopEvent(ev) - } - - Table.prototype.onDocumentClick = function(ev) { - var target = this.getEventTarget(ev) - - // Determine if the click was inside the table element - // and just exit if so - if (this.parentContainsElement(this.el, target)) - return - - // Request the active cell processor if the clicked - // element belongs to any extra-table element created - // by the processor - - if (this.activeCellProcessor && this.activeCellProcessor.elementBelongsToProcessor(target)) - return - - this.unfocusTable() - } - - // PUBLIC METHODS - // ============================ - - Table.prototype.dispose = function() { - // Remove an editor and commit the data if needed - this.unfocusTable() - - // Dispose the data source and clean up the reference - this.dataSource.dispose() - this.dataSource = null - - // Unregister event handlers - this.unregisterHandlers() - - // Remove references to DOM elements - this.dataTable = null - this.headerTable = null - this.toolbar = null - - // Dispose cell processors - this.disposeCellProcessors() - - // Dispose helpers and remove references - this.navigation.dispose() - this.navigation = null - - // Delete references to the control HTML elements. - // The script doesn't remove any DOM elements themselves. - // If it's needed it should be done by the outer script, - // we only make sure that the table widget doesn't hold - // references to the detached DOM tree so that the garbage - // collector can delete the elements if needed. - this.disposeScrollbar() - this.el = null - this.tableContainer = null - this.$el = null - this.dataTableContainer = null - - // Delete references to other DOM elements - this.activeCell = null - } - - // HELPER METHODS - // ============================ - - Table.prototype.getElement = function() { - return this.el - } - - Table.prototype.getAlias = function() { - return this.options.alias - } - - Table.prototype.getTableContainer = function() { - return this.tableContainer - } - - Table.prototype.getDataTableBody = function() { - return this.dataTable.children[0] - } - - Table.prototype.getEventTarget = function(ev, tag) { - // TODO: refactor to a core library - - var target = ev.target ? ev.target : ev.srcElement - - if (tag === undefined) - return target - - var tagName = target.tagName - - while (tagName != tag) { - target = target.parentNode - - if (!target) - return null - - tagName = target.tagName - } - - return target - } - - Table.prototype.stopEvent = function(ev) { - // TODO: refactor to a core library - - if (ev.stopPropagation) - ev.stopPropagation() - else - ev.cancelBubble = true - - if(ev.preventDefault) - ev.preventDefault() - else - ev.returnValue = false - } - - Table.prototype.elementHasClass = function(el, className) { - // TODO: refactor to a core library - - if (el.classList) - return el.classList.contains(className); - - return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); - } - - Table.prototype.elementAddClass = function(el, className) { - // TODO: refactor to a core library - - if (this.elementHasClass(el, className)) - return - - if (el.classList) - el.classList.add(className); - else - el.className += ' ' + className; - } - - Table.prototype.elementRemoveClass = function(el, className) { - // TODO: refactor to a core library - - if (el.classList) - el.classList.remove(className); - else - el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); - } - - Table.prototype.parentContainsElement = function(parent, element) { - while (element && element != parent) { - element = element.parentNode - } - - return element ? true : false - } - - Table.prototype.getCellValue = function(cellElement) { - return cellElement.querySelector('[data-container]').value - } - - Table.prototype.getCellRowKey = function(cellElement) { - return parseInt(cellElement.parentNode.getAttribute('data-row')) - } - - Table.prototype.findRowByKey = function(key) { - return this.dataTable.querySelector('tbody tr[data-row="'+key+'"]') - } - - Table.prototype.findRowByIndex = function(index) { - return this.getDataTableBody().children[index] - } - - Table.prototype.getCellRowIndex = function(cellElement) { - return parseInt(cellElement.parentNode.rowIndex) - } - - Table.prototype.getRowCellValueByColumnName = function(row, columnName) { - var cell = row.querySelector('td[data-column="'+columnName+'"]') - - if (!cell) - return cell - - return this.getCellValue(cell) - } - - Table.prototype.getRowData = function(row) { - var result = {} - - for (var i = 0, len = row.children.length; i < len; i++) { - var cell = row.children[i] - result[cell.getAttribute('data-column')] = this.getCellValue(cell) - } - - return result - } - - Table.prototype.setCellValue = function(cellElement, value) { - var dataContainer = cellElement.querySelector('[data-container]') - - if (dataContainer.value != value) { - dataContainer.value = value - - this.markCellRowDirty(cellElement) - - this.notifyRowProcessorsOnChange(cellElement) - } - } - - Table.DEFAULTS = { - clientDataSourceClass: 'client', - keyColumn: 'id', - recordsPerPage: false, - data: null, - postback: true, - postbackHandlerName: 'onSave', - adding: true, - deleting: true, - toolbar: true, - rowSorting: false, - height: false, - dynamicHeight: false - } - - // TABLE PLUGIN DEFINITION - // ============================ - - var old = $.fn.table - - $.fn.table = function (option) { - var args = Array.prototype.slice.call(arguments, 1), - result = undefined - - this.each(function () { - var $this = $(this) - var data = $this.data('oc.table') - var options = $.extend({}, Table.DEFAULTS, $this.data(), typeof option == 'object' && option) - if (!data) $this.data('oc.table', (data = new Table(this, options))) - if (typeof option == 'string') result = data[option].apply(data, args) - if (typeof result != 'undefined') return false - }) - - return result ? result : this - } - - $.fn.table.Constructor = Table - - $.oc.table.table = Table - - // TABLE NO CONFLICT - // ================= - - $.fn.table.noConflict = function () { - $.fn.table = old - return this - } - - // TABLE DATA-API - // =============== - - $(document).on('render', function(){ - $('div[data-control=table]').table() - }) - -}(window.jQuery); - -/* ********************************************** - Begin table.datasource.base.js -********************************************** */ - -/* - * Base class for the table data sources. - */ -+function ($) { "use strict"; - - // DATASOURCE NAMESPACES - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.datasource === undefined) - $.oc.table.datasource = {} - - // CLASS DEFINITION - // ============================ - - var Base = function(tableObj) { - // - // State properties - // - - this.tableObj = tableObj - } - - Base.prototype.dispose = function() { - this.tableObj = null - } - - /* - * Fetches records from the underlying data source and - * passes them to the onSuccess callback function. - * The onSuccess callback parameters: records, totalCount. - * Each record contains the key field which uniquely identifies - * the record. The name of the key field is defined with the table - * widget options. - */ - Base.prototype.getRecords = function(offset, count, onSuccess) { - onSuccess([]) - } - - /* - * Creates a record with the passed data and returns the updated page records - * to the onSuccess callback function. - * - * - recordData - the record fields - * - placement - "bottom" (the end of the data set), "above", "below" - * - relativeToKey - a row key, required if the placement is not "bottom" - * - offset - the current page's first record index (zero-based) - * - count - number of records to return - * - onSuccess - a callback function to execute when the updated data gets available. - * - * The onSuccess callback parameters: records, totalCount. - */ - Base.prototype.createRecord = function(recordData, placement, relativeToKey, offset, count, onSuccess) { - onSuccess([], 0) - } - - /* - * Updates a record with the specified key with the passed data - * - * - key - the record key in the dataset (primary key, etc) - * - recordData - the record fields. - */ - Base.prototype.updateRecord = function(key, recordData) { - } - - /* - * Deletes a record with the specified key. - * - * - key - the record key in the dataset (primary key, etc). - * - newRecordData - replacement record to add to the dataset if the deletion - * empties it. - * - offset - the current page's first record key (zero-based) - * - count - number of records to return - * - onSuccess - a callback function to execute when the updated data gets available. - * - * The onSuccess callback parameters: records, totalCount. - */ - Base.prototype.deleteRecord = function(key, newRecordData, offset, count, onSuccess) { - onSuccess([], 0) - } - - $.oc.table.datasource.base = Base; -}(window.jQuery); - -/* ********************************************** - Begin table.processor.base.js -********************************************** */ - -/* - * Base class for the table cell processors. - */ -+function ($) { "use strict"; - - // PROCESSOR NAMESPACES - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.processor === undefined) - $.oc.table.processor = {} - - // CLASS DEFINITION - // ============================ - - var Base = function(tableObj, columnName, columnConfiguration) { - // - // State properties - // - - this.tableObj = tableObj - - this.columnName = columnName - - this.columnConfiguration = columnConfiguration - - this.activeCell = null - - this.validators = [] - - // Register event handlers - this.registerHandlers() - - // Initialize validators - this.initValidators() - } - - Base.prototype.dispose = function() { - // Register event handlers - this.unregisterHandlers() - - // Remove references to the DOM - this.tableObj = null - - this.activeCell = null - } - - /* - * Renders the cell in the normal (no edit) mode - */ - Base.prototype.renderCell = function(value, cellContentContainer) { - } - - /* - * Registers event handlers required for the cell processor. - * Event handers should be bound to the container control element - * (not to the table element). - */ - Base.prototype.registerHandlers = function() { - } - - /* - * Unregisters event handlers previously registered with - * registerHandlers(). - */ - Base.prototype.unregisterHandlers = function() { - } - - /* - * This method is called when the cell managed by the processor - * is focused (clicked or navigated with the keyboard). - */ - Base.prototype.onFocus = function(cellElement, isClick) { - } - - - /* - * Forces the processor to hide the editor when the user navigates - * away from the cell. Processors can update the sell value in this method. - * Processors must clear the reference to the active cell in this method. - */ - Base.prototype.onUnfocus = function() { - } - - /* - * Event handler for the keydown event. The table class calls this method - * for all processors. - */ - Base.prototype.onKeyDown = function(ev) { - } - - /* - * Event handler for the click event. The table class calls this method - * for all processors. - */ - Base.prototype.onClick = function(ev) { - } - - /* - * This method is called when a cell value in the row changes. - */ - Base.prototype.onRowValueChanged = function(columnName, cellElement) { - } - - /* - * Determines if the keyboard navigation in the specified direction is allowed - * by the cell processor. Some processors could reject the navigation, for example - * the string processor could cancel the left array navigation if the caret - * in the text input is not in the beginning of the text. - */ - Base.prototype.keyNavigationAllowed = function(ev, direction) { - return true - } - - /* - * Determines if the processor's cell is focusable. - */ - Base.prototype.isCellFocusable = function() { - return true - } - - /* - * Returns the content container element of a cell - */ - Base.prototype.getCellContentContainer = function(cellElement) { - return cellElement.querySelector('.content-container') - } - - /* - * Creates a cell view data container (a DIV element that contains - * the current cell value). This functionality is required for most - * of the processors, perhaps except the checkbox cell processor. - */ - Base.prototype.createViewContainer = function(cellContentContainer, value) { - var viewContainer = document.createElement('div') - - viewContainer.setAttribute('data-view-container', 'data-view-container') - viewContainer.textContent = value - - cellContentContainer.appendChild(viewContainer) - - return viewContainer - } - - /* - * Returns the cell's view container element. - */ - Base.prototype.getViewContainer = function(cellElement) { - return cellElement.querySelector('[data-view-container]') - } - - /* - * Displays the view container - */ - Base.prototype.showViewContainer = function(cellElement) { - return this.getViewContainer(cellElement).setAttribute('class', '') - } - - /* - * Hides the view container - */ - Base.prototype.hideViewContainer = function(cellElement) { - return this.getViewContainer(cellElement).setAttribute('class', 'hide') - } - - /* - * Sets visual value for the view container - */ - Base.prototype.setViewContainerValue = function(cellElement, value) { - return this.getViewContainer(cellElement).textContent = value - } - - /* - * Determines whether the specified element is some element created by the - * processor. - */ - Base.prototype.elementBelongsToProcessor = function(element) { - return false - } - - Base.prototype.initValidators = function() { - if (this.columnConfiguration.validation === undefined) - return - - for (var validatorName in this.columnConfiguration.validation) { - if ($.oc.table.validator === undefined || $.oc.table.validator[validatorName] == undefined) - throw new Error('The table cell validator "'+validatorName+'" for the column "'+this.columnName+'" is not ' + - 'found in the $.oc.table.validator namespace.') - - var validator = new $.oc.table.validator[validatorName]( - this.columnConfiguration.validation[validatorName] - ) - - this.validators.push(validator) - } - } - - Base.prototype.validate = function(value, rowData) { - for (var i=0, len=this.validators.length; i 0) { - var self = this - - this.gotoPage(this.pageIndex-1, function navUpPageSuccess(){ - self.focusCell('bottom', cellIndex) - self = null - }) - } - } - } - - Navigation.prototype.navigateLeft = function(ev, isTab) { - if (!this.tableObj.activeCell) - return - - if (!isTab && this.tableObj.activeCellProcessor && !this.tableObj.activeCellProcessor.keyNavigationAllowed(ev, 'left')) - return - - var row = this.tableObj.activeCell.parentNode, - newIndex = (!ev.shiftKey || isTab) ? - this.tableObj.activeCell.cellIndex-1 : - 0 - - var cell = row.children[newIndex] - - if (cell) - this.tableObj.focusCell(cell) - else { - // Try to navigate up if that's possible - this.navigateUp(ev, row.children.length-1, isTab) - } - } - - Navigation.prototype.navigateRight = function(ev, isTab) { - if (!this.tableObj.activeCell) - return - - if (!isTab && this.tableObj.activeCellProcessor && !this.tableObj.activeCellProcessor.keyNavigationAllowed(ev, 'right')) - return - - var row = this.tableObj.activeCell.parentNode, - newIndex = !ev.shiftKey ? - this.tableObj.activeCell.cellIndex+1 : - row.children.length-1 - - var cell = row.children[newIndex] - - if (cell) - this.tableObj.focusCell(cell) - else { - // Try to navigate down if that's possible - this.navigateDown(ev, 0) - } - } - - Navigation.prototype.navigateNext = function(ev) { - if (!this.tableObj.activeCell) - return - - if (this.tableObj.activeCellProcessor && !this.tableObj.activeCellProcessor.keyNavigationAllowed(ev, 'tab')) - return - - if (!ev.shiftKey) - this.navigateRight(ev, true) - else - this.navigateLeft(ev, true) - - this.tableObj.stopEvent(ev) - } - - Navigation.prototype.focusCell = function(rowReference, cellIndex) { - var row = null, - tbody = this.tableObj.getDataTableBody() - - if (typeof rowReference === 'object') - row = rowReference - else { - if (rowReference == 'bottom') { - row = tbody.children[tbody.children.length-1] - } - else if (rowReference == 'top') { - row = tbody.children[0] - } - } - - if (!row) - return - - var cell = row.children[cellIndex] - if (cell) - this.tableObj.focusCell(cell) - } - - Navigation.prototype.focusCellInReplacedRow = function(rowIndex, cellIndex) { - if (rowIndex == 0) - this.focusCell('top', cellIndex) - else { - var focusRow = this.tableObj.findRowByIndex(rowIndex) - - if (!focusRow) - focusRow = this.tableObj.findRowByIndex(rowIndex-1) - - if (focusRow) - this.focusCell(focusRow, cellIndex) - else - this.focusCell('top', cellIndex) - } - } - - // EVENT HANDLERS - // ============================ - - Navigation.prototype.onKeydown = function(ev) { - // The navigation object uses the table's keydown handler - // and doesn't register own handler. - - if (ev.keyCode == 40) - return this.navigateDown(ev) - else if (ev.keyCode == 38) - return this.navigateUp(ev) - else if (ev.keyCode == 37) - return this.navigateLeft(ev) - if (ev.keyCode == 39) - return this.navigateRight(ev) - if (ev.keyCode == 9) - return this.navigateNext(ev) - } - - Navigation.prototype.onClick = function(ev) { - // The navigation object uses the table's click handler - // and doesn't register own click handler. - - var target = this.tableObj.getEventTarget(ev, 'A') - - if (!target) - return - - var pageIndex = parseInt(target.getAttribute('data-page-index')) - - if (pageIndex === null) - return - - this.gotoPage(pageIndex) - this.tableObj.stopEvent(ev) - - return false - } - - $.oc.table.helper.navigation = Navigation; -}(window.jQuery); - -/* ********************************************** - Begin table.datasource.client.js -********************************************** */ - -/* - * Client memory data source for the table control. - */ -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.datasource === undefined) - throw new Error("The $.oc.table.datasource namespace is not defined. Make sure that the table.datasource.base.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.datasource.base, - BaseProto = Base.prototype - - var Client = function(tableObj) { - Base.call(this, tableObj) - - var dataString = tableObj.getElement().getAttribute('data-data') - - if (dataString === null || dataString === undefined) - throw new Error('The required data-data attribute is not found on the table control element.') - - this.data = JSON.parse(dataString) - }; - - Client.prototype = Object.create(BaseProto) - Client.prototype.constructor = Client - - Client.prototype.dispose = function() { - BaseProto.dispose.call(this) - this.data = null - } - - /* - * Fetches records from the underlying data source and - * passes them to the onSuccess callback function. - * The onSuccess callback parameters: records, totalCount. - * Each record contains the key field which uniquely identifies - * the record. The name of the key field is defined with the table - * widget options. - */ - Client.prototype.getRecords = function(offset, count, onSuccess) { - if (!count) { - // Return all records - onSuccess(this.data, this.data.length) - } else { - // Return a subset of records - onSuccess(this.data.slice(offset, offset+count), this.data.length) - } - } - - /* - * Creates a record with the passed data and returns the updated page records - * to the onSuccess callback function. - * - * - recordData - the record fields - * - placement - "bottom" (the end of the data set), "above", "below" - * - relativeToKey - a row key, required if the placement is not "bottom" - * - offset - the current page's first record index (zero-based) - * - count - number of records to return - * - onSuccess - a callback function to execute when the updated data gets available. - * - * The onSuccess callback parameters: records, totalCount. - */ - Client.prototype.createRecord = function(recordData, placement, relativeToKey, offset, count, onSuccess) { - if (placement === 'bottom') { - // Add record to the bottom of the dataset - this.data.push(recordData) - } - else if (placement == 'above' || placement == 'below') { - // Add record above or below the passed record key - var recordIndex = this.getIndexOfKey(relativeToKey) - if (placement == 'below') - recordIndex ++ - - this.data.splice(recordIndex, 0, recordData) - } - - this.getRecords(offset, count, onSuccess) - } - - /* - * Updates a record with the specified key with the passed data - * - * - key - the record key in the dataset (primary key, etc) - * - recordData - the record fields. - */ - Client.prototype.updateRecord = function(key, recordData) { - var recordIndex = this.getIndexOfKey(key) - - if (recordIndex !== -1) { - recordData[this.tableObj.options.keyColumn] = key - this.data[recordIndex] = recordData - } - else { - throw new Error('Record with they key '+key+ ' is not found in the data set') - } - } - - /* - * Deletes a record with the specified key. - * - * - key - the record key in the dataset (primary key, etc). - * - newRecordData - replacement record to add to the dataset if the deletion - * empties it. - * - offset - the current page's first record key (zero-based) - * - count - number of records to return - * - onSuccess - a callback function to execute when the updated data gets available. - * - * The onSuccess callback parameters: records, totalCount. - */ - Base.prototype.deleteRecord = function(key, newRecordData, offset, count, onSuccess) { - var recordIndex = this.getIndexOfKey(key) - - if (recordIndex !== -1) { - this.data.splice(recordIndex, 1) - - if (this.data.length == 0) - this.data.push(newRecordData) - - this.getRecords(offset, count, onSuccess) - } - else { - throw new Error('Record with they key '+key+ ' is not found in the data set') - } - } - - Client.prototype.getIndexOfKey = function(key) { - var keyColumn = this.tableObj.options.keyColumn - - return this.data.map(function(record) { - return record[keyColumn] + "" - }).indexOf(key + "") - } - - Client.prototype.getAllData = function() { - return this.data - } - - $.oc.table.datasource.client = Client -}(window.jQuery); - -/* ********************************************** - Begin table.processor.checkbox.js -********************************************** */ - -/* - * Checkbox cell processor for the table control. - */ -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.processor === undefined) - throw new Error("The $.oc.table.processor namespace is not defined. Make sure that the table.processor.base.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.processor.base, - BaseProto = Base.prototype - - var CheckboxProcessor = function(tableObj, columnName, columnConfiguration) { - // - // Parent constructor - // - - Base.call(this, tableObj, columnName, columnConfiguration) - } - - CheckboxProcessor.prototype = Object.create(BaseProto) - CheckboxProcessor.prototype.constructor = CheckboxProcessor - - CheckboxProcessor.prototype.dispose = function() { - BaseProto.dispose.call(this) - } - - /* - * Determines if the processor's cell is focusable. - */ - CheckboxProcessor.prototype.isCellFocusable = function() { - return false - } - - /* - * Renders the cell in the normal (no edit) mode - */ - CheckboxProcessor.prototype.renderCell = function(value, cellContentContainer) { - var checkbox = document.createElement('div') - checkbox.setAttribute('data-checkbox-element', 'true') - checkbox.setAttribute('tabindex', '0') - - if (value && value != 0 && value != "false") - checkbox.setAttribute('class', 'checked') - - cellContentContainer.appendChild(checkbox) - } - - /* - * This method is called when the cell managed by the processor - * is focused (clicked or navigated with the keyboard). - */ - CheckboxProcessor.prototype.onFocus = function(cellElement, isClick) { - cellElement.querySelector('div[data-checkbox-element]').focus() - } - - /* - * Event handler for the keydown event. The table class calls this method - * for all processors. - */ - CheckboxProcessor.prototype.onKeyDown = function(ev) { - if (ev.keyCode == 32) - this.onClick(ev) - } - - /* - * Event handler for the click event. The table class calls this method - * for all processors. - */ - CheckboxProcessor.prototype.onClick = function(ev) { - var target = this.tableObj.getEventTarget(ev, 'DIV') - - if (target.getAttribute('data-checkbox-element')) { - this.changeState(target) - } - } - - CheckboxProcessor.prototype.changeState = function(divElement) { - var cell = divElement.parentNode.parentNode - - if (divElement.getAttribute('class') == 'checked') { - divElement.setAttribute('class', '') - this.tableObj.setCellValue(cell, 0) - } else { - divElement.setAttribute('class', 'checked') - this.tableObj.setCellValue(cell, 1) - } - } - - $.oc.table.processor.checkbox = CheckboxProcessor; -}(window.jQuery); - -/* ********************************************** - Begin table.processor.dropdown.js -********************************************** */ - -/* - * Drop-down cell processor for the table control. - */ - -/* - * TODO: implement the search - */ - -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.processor === undefined) - throw new Error("The $.oc.table.processor namespace is not defined. Make sure that the table.processor.base.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.processor.base, - BaseProto = Base.prototype - - var DropdownProcessor = function(tableObj, columnName, columnConfiguration) { - // - // State properties - // - - this.itemListElement = null - - this.cachedOptionPromises = {} - - // Event handlers - this.itemClickHandler = this.onItemClick.bind(this) - this.itemKeyDownHandler = this.onItemKeyDown.bind(this) - - // - // Parent constructor - // - - Base.call(this, tableObj, columnName, columnConfiguration) - } - - DropdownProcessor.prototype = Object.create(BaseProto) - DropdownProcessor.prototype.constructor = DropdownProcessor - - DropdownProcessor.prototype.dispose = function() { - this.unregisterListHandlers() - this.itemClickHandler = null - this.itemKeyDownHandler = null - this.itemListElement = null - this.cachedOptionPromises = null - BaseProto.dispose.call(this) - } - - DropdownProcessor.prototype.unregisterListHandlers = function() { - if (this.itemListElement) - { - // This processor binds custom click handler to the item list, - // the standard registerHandlers/unregisterHandlers functionality - // can't be used here because the element belongs to the document - // body, not to the table. - this.itemListElement.removeEventListener('click', this.itemClickHandler) - this.itemListElement.removeEventListener('keydown', this.itemKeyDownHandler) - } - } - - /* - * Renders the cell in the normal (no edit) mode - */ - DropdownProcessor.prototype.renderCell = function(value, cellContentContainer) { - var viewContainer = this.createViewContainer(cellContentContainer, '...') - - this.fetchOptions(cellContentContainer.parentNode, function renderCellFetchOptions(options) { - if (options[value] !== undefined) - viewContainer.textContent = options[value] - - cellContentContainer.setAttribute('tabindex', 0) - }) - } - - /* - * This method is called when the cell managed by the processor - * is focused (clicked or navigated with the keyboard). - */ - DropdownProcessor.prototype.onFocus = function(cellElement, isClick) { - if (this.activeCell === cellElement) { - this.showDropdown() - return - } - - this.activeCell = cellElement - var cellContentContainer = this.getCellContentContainer(cellElement) - this.buildEditor(cellElement, cellContentContainer, isClick) - - if (!isClick) - cellContentContainer.focus() - } - - /* - * Forces the processor to hide the editor when the user navigates - * away from the cell. Processors can update the sell value in this method. - * Processors must clear the reference to the active cell in this method. - */ - DropdownProcessor.prototype.onUnfocus = function() { - if (!this.activeCell) - return - - this.unregisterListHandlers() - - this.hideDropdown() - this.itemListElement = null - this.activeCell = null - } - - DropdownProcessor.prototype.buildEditor = function(cellElement, cellContentContainer, isClick) { - // Create the select control - var currentValue = this.tableObj.getCellValue(cellElement), - containerPosition = this.getAbsolutePosition(cellContentContainer) - self = this - - this.itemListElement = document.createElement('div') - - this.itemListElement.addEventListener('click', this.itemClickHandler) - this.itemListElement.addEventListener('keydown', this.itemKeyDownHandler) - - this.itemListElement.setAttribute('class', 'table-control-dropdown-list') - this.itemListElement.style.width = cellContentContainer.offsetWidth + 'px' - this.itemListElement.style.left = containerPosition.left + 'px' - this.itemListElement.style.top = containerPosition.top - 2 + cellContentContainer.offsetHeight + 'px' - - this.fetchOptions(cellElement, function renderCellFetchOptions(options) { - var listElement = document.createElement('ul') - - for (var value in options) { - var itemElement = document.createElement('li') - itemElement.setAttribute('data-value', value) - itemElement.textContent = options[value] - itemElement.setAttribute('tabindex', 0) - - if (value == currentValue) - itemElement.setAttribute('class', 'selected') - - listElement.appendChild(itemElement) - } - - self.itemListElement.appendChild(listElement) - - if (isClick) - self.showDropdown() - - self = null - }) - } - - /* - * Hide the drop-down, but don't delete it. - */ - DropdownProcessor.prototype.hideDropdown = function() { - if (this.itemListElement && this.activeCell && this.itemListElement.parentNode) { - var cellContentContainer = this.getCellContentContainer(this.activeCell) - cellContentContainer.setAttribute('data-dropdown-open', 'false') - - this.itemListElement.parentNode.removeChild(this.itemListElement) - - cellContentContainer.focus() - } - } - - DropdownProcessor.prototype.showDropdown = function() { - if (this.itemListElement && this.itemListElement.parentNode !== document.body) { - this.getCellContentContainer(this.activeCell).setAttribute('data-dropdown-open', 'true') - document.body.appendChild(this.itemListElement) - - var activeItemElement = this.itemListElement.querySelector('ul li.selected') - - if (!activeItemElement) { - activeItemElement = this.itemListElement.querySelector('ul li:first-child') - - if (activeItemElement) - activeItemElement.setAttribute('class', 'selected') - } - - if (activeItemElement) { - window.setTimeout(function(){ - activeItemElement.focus() - }, 0) - } - } - } - - DropdownProcessor.prototype.fetchOptions = function(cellElement, onSuccess) { - if (this.columnConfiguration.options) - onSuccess(this.columnConfiguration.options) - else { - // If options are not provided and not found in the cache, - // request them from the server. For dependent drop-downs - // the caching key contains the master column values. - - var row = cellElement.parentNode, - cachingKey = this.createOptionsCachingKey(row), - viewContainer = this.getViewContainer(cellElement) - - // Request options from the server. When the table widget builds, - // multiple cells in the column could require loading the options. - // The AJAX promises are cached here so that we have a single - // request per caching key. - - viewContainer.setAttribute('class', 'loading') - - if (!this.cachedOptionPromises[cachingKey]) { - var requestData = { - column: this.columnName, - rowData: this.tableObj.getRowData(row) - }, - handlerName = this.tableObj.getAlias()+'::onGetDropdownOptions' - - this.cachedOptionPromises[cachingKey] = this.tableObj.$el.request(handlerName, {data: requestData}) - } - - this.cachedOptionPromises[cachingKey].done(function onDropDownLoadOptionsSuccess(data){ - onSuccess(data.options) - }).always(function onDropDownLoadOptionsAlways(){ - viewContainer.setAttribute('class', '') - }) - } - } - - DropdownProcessor.prototype.createOptionsCachingKey = function(row) { - var cachingKey = 'non-dependent', - dependsOn = this.columnConfiguration.dependsOn - - if (dependsOn) { - if (typeof dependsOn == 'object') { - for (var i = 0, len = dependsOn.length; i < len; i++ ) - cachingKey += dependsOn[i] + this.tableObj.getRowCellValueByColumnName(row, dependsOn[i]) - } else - cachingKey = dependsOn + this.tableObj.getRowCellValueByColumnName(row, dependsOn) - } - - return cachingKey - } - - DropdownProcessor.prototype.getAbsolutePosition = function(element) { - // TODO: refactor to a core library - - var top = document.body.scrollTop, - left = 0 - - do { - top += element.offsetTop || 0; - top -= element.scrollTop || 0; - left += element.offsetLeft || 0; - element = element.offsetParent; - } while(element) - - return { - top: top, - left: left - } - } - - DropdownProcessor.prototype.updateCellFromSelectedItem = function(selectedItem) { - this.tableObj.setCellValue(this.activeCell, selectedItem.getAttribute('data-value')) - this.setViewContainerValue(this.activeCell, selectedItem.textContent) - } - - DropdownProcessor.prototype.findSelectedItem = function() { - if (this.itemListElement) - return this.itemListElement.querySelector('ul li.selected') - - return null - } - - DropdownProcessor.prototype.onItemClick = function(ev) { - var target = this.tableObj.getEventTarget(ev) - - if (target.tagName == 'LI') { - this.updateCellFromSelectedItem(target) - - var selected = this.findSelectedItem() - if (selected) - selected.setAttribute('class', '') - - target.setAttribute('class', 'selected') - this.hideDropdown() - } - } - - DropdownProcessor.prototype.onItemKeyDown = function(ev) { - if (!this.itemListElement) - return - - if (ev.keyCode == 40 || ev.keyCode == 38) - { - // Up or down keys - find previous/next list item and select it - var selected = this.findSelectedItem(), - newSelectedItem = selected.nextElementSibling - - if (ev.keyCode == 38) - newSelectedItem = selected.previousElementSibling - - if (newSelectedItem) { - selected.setAttribute('class', '') - newSelectedItem.setAttribute('class', 'selected') - newSelectedItem.focus() - } - - return - } - - if (ev.keyCode == 13 || ev.keyCode == 32) { - // Return or space keys - update the selected value and hide the editor - this.updateCellFromSelectedItem(this.findSelectedItem()) - - this.hideDropdown() - return - } - - if (ev.keyCode == 9) { - // Tab - update the selected value and pass control to the table navigation - this.updateCellFromSelectedItem(this.findSelectedItem()) - this.tableObj.navigation.navigateNext(ev) - this.tableObj.stopEvent(ev) - } - - if (ev.keyCode == 27) { - // Esc - hide the drop-down - this.hideDropdown() - } - } - - /* - * Event handler for the keydown event. The table class calls this method - * for all processors. - */ - DropdownProcessor.prototype.onKeyDown = function(ev) { - if (ev.keyCode == 32) - this.showDropdown() - } - - /* - * This method is called when a cell value in the row changes. - */ - DropdownProcessor.prototype.onRowValueChanged = function(columnName, cellElement) { - // Determine if this drop-down depends on the changed column - // and update the option list if necessary - - if (!this.columnConfiguration.dependsOn) - return - - var dependsOnColumn = false, - dependsOn = this.columnConfiguration.dependsOn - - if (typeof dependsOn == 'object') { - for (var i = 0, len = dependsOn.length; i < len; i++ ) { - if (dependsOn[i] == columnName) { - dependsOnColumn = true - break - } - } - } - else { - dependsOnColumn = dependsOn == columnName - } - - if (!dependsOnColumn) - return - - var currentValue = this.tableObj.getCellValue(cellElement), - viewContainer = this.getViewContainer(cellElement) - - this.fetchOptions(cellElement, function rowValueChangedFetchOptions(options) { - var value = options[currentValue] !== undefined - ? options[currentValue] - : '...' - - viewContainer.textContent = value - viewContainer = null - }) - } - - /* - * Determines whether the specified element is some element created by the - * processor. - */ - DropdownProcessor.prototype.elementBelongsToProcessor = function(element) { - if (!this.itemListElement) - return false - - return this.tableObj.parentContainsElement(this.itemListElement, element) - } - - $.oc.table.processor.dropdown = DropdownProcessor; -}(window.jQuery); - -/* ********************************************** - Begin table.processor.string.js -********************************************** */ - -/* - * String cell processor for the table control. - * The string processor allows to edit cell values with a simple - * input control. - */ -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.processor === undefined) - throw new Error("The $.oc.table.processor namespace is not defined. Make sure that the table.processor.base.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.processor.base, - BaseProto = Base.prototype - - var StringProcessor = function(tableObj, columnName, columnConfiguration) { - // - // State properties - // - - this.focusTimeoutHandler = this.onFocusTimeout.bind(this) - - // - // Parent constructor - // - - Base.call(this, tableObj, columnName, columnConfiguration) - } - - StringProcessor.prototype = Object.create(BaseProto) - StringProcessor.prototype.constructor = StringProcessor - - StringProcessor.prototype.dispose = function() { - BaseProto.dispose.call(this) - this.focusTimeoutHandler = null - } - - /* - * Renders the cell in the normal (no edit) mode - */ - StringProcessor.prototype.renderCell = function(value, cellContentContainer) { - this.createViewContainer(cellContentContainer, value) - } - - /* - * This method is called when the cell managed by the processor - * is focused (clicked or navigated with the keyboard). - */ - StringProcessor.prototype.onFocus = function(cellElement, isClick) { - if (this.activeCell === cellElement) - return - - this.activeCell = cellElement - this.buildEditor(cellElement, this.getCellContentContainer(cellElement)) - } - - /* - * Forces the processor to hide the editor when the user navigates - * away from the cell. Processors can update the sell value in this method. - * Processors must clear the reference to the active cell in this method. - */ - StringProcessor.prototype.onUnfocus = function() { - if (!this.activeCell) - return - - var editor = this.activeCell.querySelector('.string-input') - if (editor) { - // Update the cell value and remove the editor - this.tableObj.setCellValue(this.activeCell, editor.value) - this.setViewContainerValue(this.activeCell, editor.value) - editor.parentNode.removeChild(editor) - } - - this.showViewContainer(this.activeCell) - this.activeCell = null - } - - StringProcessor.prototype.buildEditor = function(cellElement, cellContentContainer) { - // Hide the view container - this.hideViewContainer(this.activeCell) - - // Create the input control - var input = document.createElement('input') - input.setAttribute('type', 'text') - input.setAttribute('class', 'string-input') - input.value = this.tableObj.getCellValue(cellElement) - cellContentContainer.appendChild(input) - - this.setCaretPosition(input, 0) - - // Focus the element in the next frame. - // http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful - window.setTimeout(this.focusTimeoutHandler, 0) - } - - /* - * Determines if the keyboard navigation in the specified direction is allowed - * by the cell processor. Some processors could reject the navigation, for example - * the string processor could cancel the left array navigation if the caret - * in the text input is not in the beginning of the text. - */ - StringProcessor.prototype.keyNavigationAllowed = function(ev, direction) { - if (direction != 'left' && direction != 'right') - return true - - if (!this.activeCell) - return true - - var editor = this.activeCell.querySelector('.string-input') - if (!editor) - return true - - var caretPosition = this.getCaretPosition(editor) - - if (direction == 'left') - return caretPosition == 0 - - if (direction == 'right') - return caretPosition == editor.value.length - - return true - } - - StringProcessor.prototype.onFocusTimeout = function() { - if (!this.activeCell) - return - - var editor = this.activeCell.querySelector('.string-input') - if (!editor) - return - - editor.focus() - this.setCaretPosition(editor, 0) - } - - StringProcessor.prototype.getCaretPosition = function(input) { - // TODO: refactor to a core library - - if (document.selection) { - var selection = document.selection.createRange() - - selection.moveStart('character', -input.value.length) - return selection.text.length - } - - if (input.selectionStart !== undefined) - return input.selectionStart - - return 0 - } - - StringProcessor.prototype.setCaretPosition = function(input, position) { - // TODO: refactor to a core library - - if (document.selection) { - var range = input.createTextRange() - - setTimeout(function() { - // Asynchronous layout update, better performance - range.collapse(true) - range.moveStart("character", position) - range.moveEnd("character", 0) - range.select() - }, 0) - } - - if (input.selectionStart !== undefined) { - setTimeout(function() { - // Asynchronous layout update - input.selectionStart = position - input.selectionEnd = position - }, 0) - } - - return 0 - } - - $.oc.table.processor.string = StringProcessor; -}(window.jQuery); - -/* ********************************************** - Begin table.validator.base.js -********************************************** */ - -/* - * Base class for the table validators. - */ -+function ($) { "use strict"; - - // VALIDATOR NAMESPACES - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.validator === undefined) - $.oc.table.validator = {} - - // CLASS DEFINITION - // ============================ - - var Base = function(options) { - // - // State properties - // - - this.options = options - } - - /* - * Validates a value and returns the error message. If there - * are no errors, returns undefined. - * The rowData parameter is an object containing all values in the - * target row. - */ - Base.prototype.validate = function(value, rowData) { - if (this.options.requiredWith !== undefined && !this.rowHasValue(this.options.requiredWith, rowData)) - return - - return this.validateValue(value, rowData) - } - - /* - * Validates a value and returns the error message. If there - * are no errors, returns undefined. This method should be redefined - * in descendant classes. - * The rowData parameter is an object containing all values in the - * target row. - */ - Base.prototype.validateValue = function(value, rowData) { - - } - - Base.prototype.trim = function(value) { - if (String.prototype.trim) - return value.trim() - - return value.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '') - } - - Base.prototype.getMessage = function(defaultValue) { - if (this.options.message !== undefined) - return this.options.message - - return defaultValue - } - - Base.prototype.rowHasValue = function(columnName, rowData) { - if (rowData[columnName] === undefined) - return false - - if (typeof rowData[columnName] == 'boolean') - return rowData[columnName] - - var value = this.trim(String(rowData[columnName])) - - return value.length > 0 - } - - $.oc.table.validator.base = Base; -}(window.jQuery); - -/* ********************************************** - Begin table.validator.required.js -********************************************** */ - -/* - * Required table validator. - */ -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.validator === undefined) - throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.validator.base, - BaseProto = Base.prototype - - var Required = function(options) { - Base.call(this, options) - }; - - Required.prototype = Object.create(BaseProto) - Required.prototype.constructor = Required - - /* - * Validates a value and returns the error message. If there - * are no errors, returns undefined. - * The rowData parameter is an object containing all values in the - * target row. - */ - Required.prototype.validateValue = function(value, rowData) { - value = this.trim(value) - - if (value.length === 0) - return this.getMessage("The value should not be empty.") - - return - } - - $.oc.table.validator.required = Required -}(window.jQuery); - -/* ********************************************** - Begin table.validator.basenumber.js -********************************************** */ - -/* - * Base class for number validators. - */ -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.validator === undefined) - throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.validator.base, - BaseProto = Base.prototype - - var BaseNumber = function(options) { - Base.call(this, options) - }; - - BaseNumber.prototype = Object.create(BaseProto) - BaseNumber.prototype.constructor = BaseNumber - - BaseNumber.prototype.doCommonChecks = function(value) { - if (this.options.min !== undefined || this.options.max !== undefined) { - if (this.options.min !== undefined) { - if (this.options.min.value === undefined) - throw new Error('The min.value parameter is not defined in the table validator configuration') - - if (value < this.options.min.value) { - return this.options.min.message !== undefined ? - this.options.min.message : - "The value should not be less than " + this.options.min.value - } - } - - if (this.options.max !== undefined) { - if (this.options.max.value === undefined) - throw new Error('The max.value parameter is not defined in the table validator configuration') - - if (value > this.options.max.value) { - return this.options.max.message !== undefined ? - this.options.max.message : - "The value should not be more than " + this.options.max.value - } - } - } - - return - } - - $.oc.table.validator.baseNumber = BaseNumber -}(window.jQuery); - -/* ********************************************** - Begin table.validator.integer.js -********************************************** */ - -/* - * Integer table validator. - */ -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.validator === undefined) - throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded."); - - if ($.oc.table.validator.baseNumber === undefined) - throw new Error("The $.oc.table.validator.baseNumber namespace is not defined. Make sure that the table.validator.baseNumber.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.validator.baseNumber, - BaseProto = Base.prototype - - var Integer = function(options) { - Base.call(this, options) - }; - - Integer.prototype = Object.create(BaseProto) - Integer.prototype.constructor = Integer - - /* - * Validates a value and returns the error message. If there - * are no errors, returns undefined. - * The rowData parameter is an object containing all values in the - * target row. - */ - Integer.prototype.validateValue = function(value, rowData) { - value = this.trim(value) - - if (value.length == 0) - return - - var testResult = this.options.allowNegative ? - /^\-?[0-9]*$/.test(value) : - /^[0-9]*$/.test(value) - - if (!testResult) { - var defaultMessage = this.options.allowNegative ? - 'The value should be an integer.' : - 'The value should be a positive integer'; - - return this.getMessage(defaultMessage) - } - - return this.doCommonChecks(parseInt(value)) - } - - $.oc.table.validator.integer = Integer -}(window.jQuery); - -/* ********************************************** - Begin table.validator.float.js -********************************************** */ - -/* - * Float table validator. - */ -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.validator === undefined) - throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded."); - - if ($.oc.table.validator.baseNumber === undefined) - throw new Error("The $.oc.table.validator.baseNumber namespace is not defined. Make sure that the table.validator.baseNumber.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.validator.baseNumber, - BaseProto = Base.prototype - - var Float = function(options) { - Base.call(this, options) - }; - - Float.prototype = Object.create(BaseProto) - Float.prototype.constructor = Float - - /* - * Validates a value and returns the error message. If there - * are no errors, returns undefined. - * The rowData parameter is an object containing all values in the - * target row. - */ - Float.prototype.validateValue = function(value, rowData) { - value = this.trim(value) - - if (value.length == 0) - return - - var testResult = this.options.allowNegative ? - /^[-]?([0-9]+\.[0-9]+|[0-9]+)$/.test(value) : - /^([0-9]+\.[0-9]+|[0-9]+)$/.test(value) - - if (!testResult) { - var defaultMessage = this.options.allowNegative ? - 'The value should be a floating point number.' : - 'The value should be a positive floating point number'; - - return this.getMessage(defaultMessage) - } - - return this.doCommonChecks(parseFloat(value)) - } - - $.oc.table.validator.float = Float -}(window.jQuery); - -/* ********************************************** - Begin table.validator.length.js -********************************************** */ - -/* - * String length table validator. - */ -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.validator === undefined) - throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.validator.base, - BaseProto = Base.prototype - - var Length = function(options) { - Base.call(this, options) - }; - - Length.prototype = Object.create(BaseProto) - Length.prototype.constructor = Length - - /* - * Validates a value and returns the error message. If there - * are no errors, returns undefined. - * The rowData parameter is an object containing all values in the - * target row. - */ - Length.prototype.validateValue = function(value, rowData) { - value = this.trim(value) - - if (value.length == 0) - return - - if (this.options.min !== undefined || this.options.max !== undefined) { - if (this.options.min !== undefined) { - if (this.options.min.value === undefined) - throw new Error('The min.value parameter is not defined in the Length table validator configuration') - - if (value.length < this.options.min.value) { - return this.options.min.message !== undefined ? - this.options.min.message : - "The string should not be shorter than " + this.options.min.value - } - } - - if (this.options.max !== undefined) { - if (this.options.max.value === undefined) - throw new Error('The max.value parameter is not defined in the Length table validator configuration') - - if (value.length > this.options.max.value) { - return this.options.max.message !== undefined ? - this.options.max.message : - "The string should not be longer than " + this.options.max.value - } - } - } - - return - } - - $.oc.table.validator.length = Length -}(window.jQuery); - -/* ********************************************** - Begin table.validator.regex.js -********************************************** */ - -/* - * Regex length table validator. - */ -+function ($) { "use strict"; - - // NAMESPACE CHECK - // ============================ - - if ($.oc.table === undefined) - throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded."); - - if ($.oc.table.validator === undefined) - throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded."); - - // CLASS DEFINITION - // ============================ - - var Base = $.oc.table.validator.base, - BaseProto = Base.prototype - - var Regex = function(options) { - Base.call(this, options) - }; - - Regex.prototype = Object.create(BaseProto) - Regex.prototype.constructor = Regex - - /* - * Validates a value and returns the error message. If there - * are no errors, returns undefined. - * The rowData parameter is an object containing all values in the - * target row. - */ - Regex.prototype.validateValue = function(value, rowData) { - value = this.trim(value) - - if (value.length == 0) - return - - if (this.options.pattern === undefined) - throw new Error('The pattern parameter is not defined in the Regex table validator configuration') - - var regexObj = new RegExp(this.options.pattern, this.options.modifiers) - - if (!regexObj.test(value)) - return this.getMessage("Invalid value format.") - - return - } - - $.oc.table.validator.regex = Regex -}(window.jQuery); \ No newline at end of file ++function($){"use strict";if($.oc===undefined) +$.oc={} +if($.oc.table===undefined) +$.oc.table={} +var Table=function(element,options){this.el=element +this.$el=$(element) +this.options=options +this.dataSource=null +this.cellProcessors={} +this.activeCellProcessor=null +this.activeCell=null +this.tableContainer=null +this.dataTableContainer=null +this.editedRowKey=null +this.dataTable=null +this.headerTable=null +this.toolbar=null +this.clickHandler=this.onClick.bind(this) +this.keydownHandler=this.onKeydown.bind(this) +this.documentClickHandler=this.onDocumentClick.bind(this) +this.toolbarClickHandler=this.onToolbarClick.bind(this) +if(this.options.postback&&this.options.clientDataSourceClass=='client') +this.formSubmitHandler=this.onFormSubmit.bind(this) +this.navigation=null +this.recordsAddedOrDeleted=0 +this.init()} +Table.prototype.init=function(){this.createDataSource() +this.initCellProcessors() +this.navigation=new $.oc.table.helper.navigation(this) +this.buildUi() +this.registerHandlers()} +Table.prototype.disposeCellProcessors=function(){for(var i=0,len=this.options.columns.length;i-1?this.options.alias+'[TableData]':this.options.alias+'TableData';data.options.data[fieldName]=this.dataSource.getAllData()}} +Table.prototype.onToolbarClick=function(ev){var target=this.getEventTarget(ev),cmd=target.getAttribute('data-cmd') +switch(cmd){case'record-add-below':this.addRecord('below') +break +case'record-add-above':this.addRecord('above') +break +case'record-delete':this.deleteRecord() +break} +this.stopEvent(ev)} +Table.prototype.onDocumentClick=function(ev){var target=this.getEventTarget(ev) +if(this.parentContainsElement(this.el,target)) +return +if(this.activeCellProcessor&&this.activeCellProcessor.elementBelongsToProcessor(target)) +return +this.unfocusTable()} +Table.prototype.dispose=function(){this.unfocusTable() +this.dataSource.dispose() +this.dataSource=null +this.unregisterHandlers() +this.dataTable=null +this.headerTable=null +this.toolbar=null +this.disposeCellProcessors() +this.navigation.dispose() +this.navigation=null +this.disposeScrollbar() +this.el=null +this.tableContainer=null +this.$el=null +this.dataTableContainer=null +this.activeCell=null} +Table.prototype.getElement=function(){return this.el} +Table.prototype.getAlias=function(){return this.options.alias} +Table.prototype.getTableContainer=function(){return this.tableContainer} +Table.prototype.getDataTableBody=function(){return this.dataTable.children[0]} +Table.prototype.getEventTarget=function(ev,tag){var target=ev.target?ev.target:ev.srcElement +if(tag===undefined) +return target +var tagName=target.tagName +while(tagName!=tag){target=target.parentNode +if(!target) +return null +tagName=target.tagName} +return target} +Table.prototype.stopEvent=function(ev){if(ev.stopPropagation) +ev.stopPropagation() +else +ev.cancelBubble=true +if(ev.preventDefault) +ev.preventDefault() +else +ev.returnValue=false} +Table.prototype.elementHasClass=function(el,className){if(el.classList) +return el.classList.contains(className);return new RegExp('(^| )'+className+'( |$)','gi').test(el.className);} +Table.prototype.elementAddClass=function(el,className){if(this.elementHasClass(el,className)) +return +if(el.classList) +el.classList.add(className);else +el.className+=' '+className;} +Table.prototype.elementRemoveClass=function(el,className){if(el.classList) +el.classList.remove(className);else +el.className=el.className.replace(new RegExp('(^|\\b)'+className.split(' ').join('|')+'(\\b|$)','gi'),' ');} +Table.prototype.parentContainsElement=function(parent,element){while(element&&element!=parent){element=element.parentNode} +return element?true:false} +Table.prototype.getCellValue=function(cellElement){return cellElement.querySelector('[data-container]').value} +Table.prototype.getCellRowKey=function(cellElement){return parseInt(cellElement.parentNode.getAttribute('data-row'))} +Table.prototype.findRowByKey=function(key){return this.dataTable.querySelector('tbody tr[data-row="'+key+'"]')} +Table.prototype.findRowByIndex=function(index){return this.getDataTableBody().children[index]} +Table.prototype.getCellRowIndex=function(cellElement){return parseInt(cellElement.parentNode.rowIndex)} +Table.prototype.getRowCellValueByColumnName=function(row,columnName){var cell=row.querySelector('td[data-column="'+columnName+'"]') +if(!cell) +return cell +return this.getCellValue(cell)} +Table.prototype.getRowData=function(row){var result={} +for(var i=0,len=row.children.length;i0){var self=this +this.gotoPage(this.pageIndex-1,function navUpPageSuccess(){self.focusCell('bottom',cellIndex) +self=null})}}} +Navigation.prototype.navigateLeft=function(ev,isTab){if(!this.tableObj.activeCell) +return +if(!isTab&&this.tableObj.activeCellProcessor&&!this.tableObj.activeCellProcessor.keyNavigationAllowed(ev,'left')) +return +var row=this.tableObj.activeCell.parentNode,newIndex=(!ev.shiftKey||isTab)?this.tableObj.activeCell.cellIndex-1:0 +var cell=row.children[newIndex] +if(cell) +this.tableObj.focusCell(cell) +else{this.navigateUp(ev,row.children.length-1,isTab)}} +Navigation.prototype.navigateRight=function(ev,isTab){if(!this.tableObj.activeCell) +return +if(!isTab&&this.tableObj.activeCellProcessor&&!this.tableObj.activeCellProcessor.keyNavigationAllowed(ev,'right')) +return +var row=this.tableObj.activeCell.parentNode,newIndex=!ev.shiftKey?this.tableObj.activeCell.cellIndex+1:row.children.length-1 +var cell=row.children[newIndex] +if(cell) +this.tableObj.focusCell(cell) +else{this.navigateDown(ev,0)}} +Navigation.prototype.navigateNext=function(ev){if(!this.tableObj.activeCell) +return +if(this.tableObj.activeCellProcessor&&!this.tableObj.activeCellProcessor.keyNavigationAllowed(ev,'tab')) +return +if(!ev.shiftKey) +this.navigateRight(ev,true) +else +this.navigateLeft(ev,true) +this.tableObj.stopEvent(ev)} +Navigation.prototype.focusCell=function(rowReference,cellIndex){var row=null,tbody=this.tableObj.getDataTableBody() +if(typeof rowReference==='object') +row=rowReference +else{if(rowReference=='bottom'){row=tbody.children[tbody.children.length-1]} +else if(rowReference=='top'){row=tbody.children[0]}} +if(!row) +return +var cell=row.children[cellIndex] +if(cell) +this.tableObj.focusCell(cell)} +Navigation.prototype.focusCellInReplacedRow=function(rowIndex,cellIndex){if(rowIndex==0) +this.focusCell('top',cellIndex) +else{var focusRow=this.tableObj.findRowByIndex(rowIndex) +if(!focusRow) +focusRow=this.tableObj.findRowByIndex(rowIndex-1) +if(focusRow) +this.focusCell(focusRow,cellIndex) +else +this.focusCell('top',cellIndex)}} +Navigation.prototype.onKeydown=function(ev){if(ev.keyCode==40) +return this.navigateDown(ev) +else if(ev.keyCode==38) +return this.navigateUp(ev) +else if(ev.keyCode==37) +return this.navigateLeft(ev) +if(ev.keyCode==39) +return this.navigateRight(ev) +if(ev.keyCode==9) +return this.navigateNext(ev)} +Navigation.prototype.onClick=function(ev){var target=this.tableObj.getEventTarget(ev,'A') +if(!target) +return +var pageIndex=parseInt(target.getAttribute('data-page-index')) +if(pageIndex===null) +return +this.gotoPage(pageIndex) +this.tableObj.stopEvent(ev) +return false} +$.oc.table.helper.navigation=Navigation;}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) +throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.datasource===undefined) +$.oc.table.datasource={} +var Base=function(tableObj){this.tableObj=tableObj} +Base.prototype.dispose=function(){this.tableObj=null} +Base.prototype.getRecords=function(offset,count,onSuccess){onSuccess([])} +Base.prototype.createRecord=function(recordData,placement,relativeToKey,offset,count,onSuccess){onSuccess([],0)} +Base.prototype.updateRecord=function(key,recordData){} +Base.prototype.deleteRecord=function(key,newRecordData,offset,count,onSuccess){onSuccess([],0)} +$.oc.table.datasource.base=Base;}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) +throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.datasource===undefined) +throw new Error("The $.oc.table.datasource namespace is not defined. Make sure that the table.datasource.base.js script is loaded.");var Base=$.oc.table.datasource.base,BaseProto=Base.prototype +var Client=function(tableObj){Base.call(this,tableObj) +var dataString=tableObj.getElement().getAttribute('data-data') +if(dataString===null||dataString===undefined) +throw new Error('The required data-data attribute is not found on the table control element.') +this.data=JSON.parse(dataString)};Client.prototype=Object.create(BaseProto) +Client.prototype.constructor=Client +Client.prototype.dispose=function(){BaseProto.dispose.call(this) +this.data=null} +Client.prototype.getRecords=function(offset,count,onSuccess){if(!count){onSuccess(this.data,this.data.length)}else{onSuccess(this.data.slice(offset,offset+count),this.data.length)}} +Client.prototype.createRecord=function(recordData,placement,relativeToKey,offset,count,onSuccess){if(placement==='bottom'){this.data.push(recordData)} +else if(placement=='above'||placement=='below'){var recordIndex=this.getIndexOfKey(relativeToKey) +if(placement=='below') +recordIndex++ +this.data.splice(recordIndex,0,recordData)} +this.getRecords(offset,count,onSuccess)} +Client.prototype.updateRecord=function(key,recordData){var recordIndex=this.getIndexOfKey(key) +if(recordIndex!==-1){recordData[this.tableObj.options.keyColumn]=key +this.data[recordIndex]=recordData} +else{throw new Error('Record with they key '+key+' is not found in the data set')}} +Base.prototype.deleteRecord=function(key,newRecordData,offset,count,onSuccess){var recordIndex=this.getIndexOfKey(key) +if(recordIndex!==-1){this.data.splice(recordIndex,1) +if(this.data.length==0) +this.data.push(newRecordData) +this.getRecords(offset,count,onSuccess)} +else{throw new Error('Record with they key '+key+' is not found in the data set')}} +Client.prototype.getIndexOfKey=function(key){var keyColumn=this.tableObj.options.keyColumn +return this.data.map(function(record){return record[keyColumn]+""}).indexOf(key+"")} +Client.prototype.getAllData=function(){return this.data} +$.oc.table.datasource.client=Client}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) +throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.processor===undefined) +$.oc.table.processor={} +var Base=function(tableObj,columnName,columnConfiguration){this.tableObj=tableObj +this.columnName=columnName +this.columnConfiguration=columnConfiguration +this.activeCell=null +this.validators=[] +this.registerHandlers() +this.initValidators()} +Base.prototype.dispose=function(){this.unregisterHandlers() +this.tableObj=null +this.activeCell=null} +Base.prototype.renderCell=function(value,cellContentContainer){} +Base.prototype.registerHandlers=function(){} +Base.prototype.unregisterHandlers=function(){} +Base.prototype.onFocus=function(cellElement,isClick){} +Base.prototype.onUnfocus=function(){} +Base.prototype.onKeyDown=function(ev){} +Base.prototype.onClick=function(ev){} +Base.prototype.onRowValueChanged=function(columnName,cellElement){} +Base.prototype.keyNavigationAllowed=function(ev,direction){return true} +Base.prototype.isCellFocusable=function(){return true} +Base.prototype.getCellContentContainer=function(cellElement){return cellElement.querySelector('.content-container')} +Base.prototype.createViewContainer=function(cellContentContainer,value){var viewContainer=document.createElement('div') +viewContainer.setAttribute('data-view-container','data-view-container') +viewContainer.textContent=value +cellContentContainer.appendChild(viewContainer) +return viewContainer} +Base.prototype.getViewContainer=function(cellElement){return cellElement.querySelector('[data-view-container]')} +Base.prototype.showViewContainer=function(cellElement){return this.getViewContainer(cellElement).setAttribute('class','')} +Base.prototype.hideViewContainer=function(cellElement){return this.getViewContainer(cellElement).setAttribute('class','hide')} +Base.prototype.setViewContainerValue=function(cellElement,value){return this.getViewContainer(cellElement).textContent=value} +Base.prototype.elementBelongsToProcessor=function(element){return false} +Base.prototype.initValidators=function(){if(this.columnConfiguration.validation===undefined) +return +for(var validatorName in this.columnConfiguration.validation){if($.oc.table.validator===undefined||$.oc.table.validator[validatorName]==undefined) +throw new Error('The table cell validator "'+validatorName+'" for the column "'+this.columnName+'" is not '+'found in the $.oc.table.validator namespace.') +var validator=new $.oc.table.validator[validatorName](this.columnConfiguration.validation[validatorName]) +this.validators.push(validator)}} +Base.prototype.validate=function(value,rowData){for(var i=0,len=this.validators.length;i0} +$.oc.table.validator.base=Base;}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) +throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.validator===undefined) +throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");var Base=$.oc.table.validator.base,BaseProto=Base.prototype +var Required=function(options){Base.call(this,options)};Required.prototype=Object.create(BaseProto) +Required.prototype.constructor=Required +Required.prototype.validateValue=function(value,rowData){value=this.trim(value) +if(value.length===0) +return this.getMessage("The value should not be empty.") +return} +$.oc.table.validator.required=Required}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) +throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.validator===undefined) +throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");var Base=$.oc.table.validator.base,BaseProto=Base.prototype +var BaseNumber=function(options){Base.call(this,options)};BaseNumber.prototype=Object.create(BaseProto) +BaseNumber.prototype.constructor=BaseNumber +BaseNumber.prototype.doCommonChecks=function(value){if(this.options.min!==undefined||this.options.max!==undefined){if(this.options.min!==undefined){if(this.options.min.value===undefined) +throw new Error('The min.value parameter is not defined in the table validator configuration') +if(valuethis.options.max.value){return this.options.max.message!==undefined?this.options.max.message:"The value should not be more than "+this.options.max.value}}} +return} +$.oc.table.validator.baseNumber=BaseNumber}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) +throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.validator===undefined) +throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");if($.oc.table.validator.baseNumber===undefined) +throw new Error("The $.oc.table.validator.baseNumber namespace is not defined. Make sure that the table.validator.baseNumber.js script is loaded.");var Base=$.oc.table.validator.baseNumber,BaseProto=Base.prototype +var Integer=function(options){Base.call(this,options)};Integer.prototype=Object.create(BaseProto) +Integer.prototype.constructor=Integer +Integer.prototype.validateValue=function(value,rowData){value=this.trim(value) +if(value.length==0) +return +var testResult=this.options.allowNegative?/^\-?[0-9]*$/.test(value):/^[0-9]*$/.test(value) +if(!testResult){var defaultMessage=this.options.allowNegative?'The value should be an integer.':'The value should be a positive integer';return this.getMessage(defaultMessage)} +return this.doCommonChecks(parseInt(value))} +$.oc.table.validator.integer=Integer}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) +throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.validator===undefined) +throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");if($.oc.table.validator.baseNumber===undefined) +throw new Error("The $.oc.table.validator.baseNumber namespace is not defined. Make sure that the table.validator.baseNumber.js script is loaded.");var Base=$.oc.table.validator.baseNumber,BaseProto=Base.prototype +var Float=function(options){Base.call(this,options)};Float.prototype=Object.create(BaseProto) +Float.prototype.constructor=Float +Float.prototype.validateValue=function(value,rowData){value=this.trim(value) +if(value.length==0) +return +var testResult=this.options.allowNegative?/^[-]?([0-9]+\.[0-9]+|[0-9]+)$/.test(value):/^([0-9]+\.[0-9]+|[0-9]+)$/.test(value) +if(!testResult){var defaultMessage=this.options.allowNegative?'The value should be a floating point number.':'The value should be a positive floating point number';return this.getMessage(defaultMessage)} +return this.doCommonChecks(parseFloat(value))} +$.oc.table.validator.float=Float}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) +throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.validator===undefined) +throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");var Base=$.oc.table.validator.base,BaseProto=Base.prototype +var Length=function(options){Base.call(this,options)};Length.prototype=Object.create(BaseProto) +Length.prototype.constructor=Length +Length.prototype.validateValue=function(value,rowData){value=this.trim(value) +if(value.length==0) +return +if(this.options.min!==undefined||this.options.max!==undefined){if(this.options.min!==undefined){if(this.options.min.value===undefined) +throw new Error('The min.value parameter is not defined in the Length table validator configuration') +if(value.lengththis.options.max.value){return this.options.max.message!==undefined?this.options.max.message:"The string should not be longer than "+this.options.max.value}}} +return} +$.oc.table.validator.length=Length}(window.jQuery);+function($){"use strict";if($.oc.table===undefined) +throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if($.oc.table.validator===undefined) +throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");var Base=$.oc.table.validator.base,BaseProto=Base.prototype +var Regex=function(options){Base.call(this,options)};Regex.prototype=Object.create(BaseProto) +Regex.prototype.constructor=Regex +Regex.prototype.validateValue=function(value,rowData){value=this.trim(value) +if(value.length==0) +return +if(this.options.pattern===undefined) +throw new Error('The pattern parameter is not defined in the Regex table validator configuration') +var regexObj=new RegExp(this.options.pattern,this.options.modifiers) +if(!regexObj.test(value)) +return this.getMessage("Invalid value format.") +return} +$.oc.table.validator.regex=Regex}(window.jQuery); \ No newline at end of file diff --git a/modules/backend/widgets/table/assets/js/table-min.js b/modules/backend/widgets/table/assets/js/table-min.js deleted file mode 100644 index b40631a62..000000000 --- a/modules/backend/widgets/table/assets/js/table-min.js +++ /dev/null @@ -1,3 +0,0 @@ -+function(t){"use strict";void 0===t.oc&&(t.oc={}),void 0===t.oc.table&&(t.oc.table={});var e=function(e,o){this.el=e,this.$el=t(e),this.options=o,this.dataSource=null,this.cellProcessors={},this.activeCellProcessor=null,this.activeCell=null,this.tableContainer=null,this.dataTableContainer=null,this.editedRowKey=null,this.dataTable=null,this.headerTable=null,this.toolbar=null,this.clickHandler=this.onClick.bind(this),this.keydownHandler=this.onKeydown.bind(this),this.documentClickHandler=this.onDocumentClick.bind(this),this.toolbarClickHandler=this.onToolbarClick.bind(this),this.options.postback&&"client"==this.options.clientDataSourceClass&&(this.formSubmitHandler=this.onFormSubmit.bind(this)),this.navigation=null,this.recordsAddedOrDeleted=0,this.init()};e.prototype.init=function(){this.createDataSource(),this.initCellProcessors(),this.navigation=new t.oc.table.helper.navigation(this),this.buildUi(),this.registerHandlers()},e.prototype.disposeCellProcessors=function(){for(var t=0,e=this.options.columns.length;e>t;t++){var o=this.options.columns[t].key;this.cellProcessors[o].dispose(),this.cellProcessors[o]=null}this.cellProcessors=null,this.activeCellProcessor=null},e.prototype.createDataSource=function(){var e=this.options.clientDataSourceClass;if(void 0===t.oc.table.datasource||void 0==t.oc.table.datasource[e])throw new Error('The table client-side data source class "'+e+'" is not found in the $.oc.table.datasource namespace.');this.dataSource=new t.oc.table.datasource[e](this)},e.prototype.registerHandlers=function(){this.el.addEventListener("click",this.clickHandler),this.el.addEventListener("keydown",this.keydownHandler),document.addEventListener("click",this.documentClickHandler),this.options.postback&&"client"==this.options.clientDataSourceClass&&this.$el.closest("form").bind("oc.beforeRequest",this.formSubmitHandler);var t=this.getToolbar();t&&t.addEventListener("click",this.toolbarClickHandler)},e.prototype.unregisterHandlers=function(){this.el.removeEventListener("click",this.clickHandler),document.removeEventListener("click",this.documentClickHandler),this.clickHandler=null,this.el.removeEventListener("keydown",this.keydownHandler),this.keydownHandler=null;var t=this.getToolbar();t&&t.removeEventListener("click",this.toolbarClickHandler),this.toolbarClickHandler=null,this.formSubmitHandler&&(this.$el.closest("form").unbind("oc.beforeRequest",this.formSubmitHandler),this.formSubmitHandler=null)},e.prototype.initCellProcessors=function(){for(var e=0,o=this.options.columns.length;o>e;e++){var i=this.options.columns[e],a=i.key,n=i.type;if(void 0===n&&(n="string",this.options.columns[e].type=n),void 0===t.oc.table.processor||void 0==t.oc.table.processor[n])throw new Error('The table cell processor for the column type "'+n+'" is not found in the $.oc.table.processor namespace.');this.cellProcessors[a]=new t.oc.table.processor[n](this,a,i)}},e.prototype.getCellProcessor=function(t){return this.cellProcessors[t]},e.prototype.buildUi=function(){this.tableContainer=document.createElement("div"),this.tableContainer.setAttribute("class","table-container"),this.options.toolbar&&this.buildToolbar(),this.tableContainer.appendChild(this.buildHeaderTable()),this.el.insertBefore(this.tableContainer,this.el.children[0]),this.dataTableContainer=this.options.height?this.buildScrollbar():this.tableContainer,this.updateDataTable()},e.prototype.buildToolbar=function(){if(this.options.adding||this.options.deleting){if(this.toolbar=document.createElement("div"),this.toolbar.setAttribute("class","toolbar"),this.options.adding){var t=document.createElement("a");if(t.setAttribute("class","btn add-table-row-below"),t.setAttribute("data-cmd","record-add-below"),this.toolbar.appendChild(t),this.navigation.paginationEnabled()||!this.options.rowSorting)t.textContent="Add row";else{t.textContent="Add row below";var e=document.createElement("a");e.setAttribute("class","btn add-table-row-above"),e.textContent="Add row above",e.setAttribute("data-cmd","record-add-above"),this.toolbar.appendChild(e)}}if(this.options.deleting){var o=document.createElement("a");o.setAttribute("class","btn delete-table-row"),o.textContent="Delete row",o.setAttribute("data-cmd","record-delete"),this.toolbar.appendChild(o)}this.tableContainer.appendChild(this.toolbar)}},e.prototype.buildScrollbar=function(){var e=document.createElement("div"),o=document.createElement("div");return e.setAttribute("class","control-scrollbar"),this.options.dynamicHeight?e.setAttribute("style","max-height: "+this.options.height+"px"):e.setAttribute("style","height: "+this.options.height+"px"),e.appendChild(o),this.tableContainer.appendChild(e),t(e).scrollbar({animation:!1}),o},e.prototype.buildHeaderTable=function(){var t=document.createElement("table"),e=document.createElement("tr");t.className="headers",t.appendChild(e);for(var o=0,i=this.options.columns.length;i>o;o++){var a=document.createElement("th");this.options.columns[o].width&&a.setAttribute("style","width: "+this.options.columns[o].width),void 0!==a.textContent?a.textContent=this.options.columns[o].title:a.innerText=this.options.columns[o].title,e.appendChild(a)}return this.headerTable=t,t},e.prototype.updateDataTable=function(t){var e=this;this.unfocusTable(),this.fetchRecords(function o(i,a){e.buildDataTable(i,a),t&&t(),0==a&&e.addRecord("above",!0),e=null})},e.prototype.updateColumnWidth=function(){for(var t=this.headerTable.querySelectorAll("th"),e=this.dataTable.querySelectorAll("tr:first-child td"),o=0,i=t.length;i>o;o++)e[o]&&e[o].setAttribute("style",t[o].getAttribute("style"))},e.prototype.buildDataTable=function(t,e){var o=document.createElement("table"),i=document.createElement("tbody"),a=this.options.keyColumn;o.setAttribute("class","data");for(var n=0,s=t.length;s>n;n++){var r=document.createElement("tr");if(void 0===t[n][a])throw new Error("The row attribute "+a+" is not set for the row #"+n);r.setAttribute("data-row",t[n][a]);for(var l=0,c=this.options.columns.length;c>l;l++){var d=document.createElement("td"),h=document.createElement("input"),u=document.createElement("div"),p=this.options.columns[l],b=p.key,v=this.getCellProcessor(b);d.setAttribute("data-column",b),d.setAttribute("data-column-type",p.type),h.setAttribute("type","hidden"),h.setAttribute("data-container","data-container"),h.value=void 0!==t[n][b]?t[n][b]:"",u.setAttribute("class","content-container"),d.appendChild(u),r.appendChild(d),d.appendChild(h),v.renderCell(t[n][b],u)}i.appendChild(r)}o.appendChild(i),null!==this.dataTable?this.dataTableContainer.replaceChild(o,this.dataTable):this.dataTableContainer.appendChild(o),this.dataTable=o,this.updateColumnWidth(),this.updateScrollbar(),this.navigation.buildPagination(e)},e.prototype.fetchRecords=function(t){this.dataSource.getRecords(this.navigation.getPageFirstRowOffset(),this.options.recordsPerPage,t)},e.prototype.updateScrollbar=function(){this.options.height&&t(this.dataTableContainer.parentNode).data("oc.scrollbar").update()},e.prototype.scrollCellIntoView=function(){this.options.height&&this.activeCell&&t(this.dataTableContainer.parentNode).data("oc.scrollbar").gotoElement(this.activeCell)},e.prototype.disposeScrollbar=function(){this.options.height&&(t(this.dataTableContainer.parentNode).data("oc.scrollbar").dispose(),t(this.dataTableContainer.parentNode).data("oc.scrollbar",null))},e.prototype.setActiveProcessor=function(t){this.activeCellProcessor&&this.activeCellProcessor.onUnfocus(),this.activeCellProcessor=t},e.prototype.commitEditedRow=function(){if(null!==this.editedRowKey){var t=this.dataTable.querySelector('tr[data-row="'+this.editedRowKey+'"]');if(t&&1==t.getAttribute("data-dirty")){for(var e=t.children,o={},i=0,a=e.length;a>i;i++){var n=e[i];o[n.getAttribute("data-column")]=this.getCellValue(n)}this.dataSource.updateRecord(this.editedRowKey,o),t.setAttribute("data-dirty",0)}}},e.prototype.unfocusTable=function(){this.elementRemoveClass(this.el,"active"),this.activeCellProcessor&&this.activeCellProcessor.onUnfocus(),this.commitEditedRow(),this.activeCellProcessor=null,this.activeCell&&this.activeCell.setAttribute("class",""),this.activeCell=null},e.prototype.focusTable=function(){this.elementAddClass(this.el,"active")},e.prototype.focusCell=function(t,e){var o=t.getAttribute("data-column");if(null!==o){this.focusTable();var i=this.getCellProcessor(o);if(!i)throw new Error("Cell processor not found for the column "+o);this.activeCell!==t&&(this.activeCell&&this.elementRemoveClass(this.activeCell,"active"),this.setActiveProcessor(i),this.activeCell=t,i.isCellFocusable()&&this.elementAddClass(this.activeCell,"active"));var a=this.getCellRowKey(t);null!==this.editedRowKey&&a!=this.editedRowKey&&this.commitEditedRow(),this.editedRowKey=a,i.onFocus(t,e),this.scrollCellIntoView()}},e.prototype.markCellRowDirty=function(t){t.parentNode.setAttribute("data-dirty",1)},e.prototype.addRecord=function(t,e){this.activeCell&&!this.navigation.paginationEnabled()&&this.options.rowSorting||(t="bottom");var o=null,i=null;if(("above"==t||"below"==t)&&(o=this.getCellRowKey(this.activeCell),i=this.getCellRowIndex(this.activeCell)),this.unfocusTable(),this.navigation.paginationEnabled()){var a=this.navigation.getNewRowPage(t,i);if(a!=this.navigation.pageIndex&&!this.validate())return;this.navigation.pageIndex=a}this.recordsAddedOrDeleted++;var n=this.options.keyColumn,s={},r=this;s[n]=-1*this.recordsAddedOrDeleted,this.dataSource.createRecord(s,t,o,this.navigation.getPageFirstRowOffset(),this.options.recordsPerPage,function l(t,o){r.buildDataTable(t,o);var i=r.findRowByKey(s[n]);if(!i)throw new Error("New row is not found in the updated table: "+s[n]);e||r.navigation.focusCell(i,0),r=null})},e.prototype.deleteRecord=function(){if(this.activeCell){var t=this.getCellRowIndex(this.activeCell),e=this.getCellRowKey(this.activeCell),o=this,i=this.navigation.paginationEnabled(),a=this.navigation.pageIndex,n=this.activeCell.cellIndex;i&&(this.navigation.pageIndex=this.navigation.getPageAfterDeletion(t)),this.recordsAddedOrDeleted++;var s=this.options.keyColumn,r={};r[s]=-1*this.recordsAddedOrDeleted,this.dataSource.deleteRecord(e,r,this.navigation.getPageFirstRowOffset(),this.options.recordsPerPage,function l(e,s){o.buildDataTable(e,s),i&&a!=o.navigation.pageIndex?o.navigation.focusCell("bottom",n):o.navigation.focusCellInReplacedRow(t,n),o=null})}},e.prototype.notifyRowProcessorsOnChange=function(t){for(var e=t.getAttribute("data-column"),o=t.parentNode,i=0,a=o.children.length;a>i;i++){var n=this.options.columns[i].key;this.cellProcessors[n].onRowValueChanged(e,o.children[i])}},e.prototype.getToolbar=function(){return this.tableContainer.querySelector("div.toolbar")},e.prototype.validate=function(){for(var e=this.dataTable.querySelectorAll("tbody tr[data-row]"),o=0,i=e.length;i>o;o++){var a=e[o];this.elementRemoveClass(a,"error")}for(var o=0,n=e.length;n>o;o++){for(var a=e[o],s=this.getRowData(a),r=0,l=a.children.length;l>r;r++)this.elementRemoveClass(a.children[r],"error");for(var c in s){var d=this.getCellProcessor(c),h=d.validate(s[c],s);if(void 0!==h){var u=a.querySelector('td[data-column="'+c+'"]'),p=this;return this.elementAddClass(a,"error"),this.elementAddClass(u,"error"),t.oc.flashMsg({text:h,"class":"error"}),window.setTimeout(function(){p.focusCell(u,!1),u=null,p=null,d=null},100),!1}}}return!0},e.prototype.onClick=function(t){if(this.focusTable(),this.navigation.onClick(t)!==!1){for(var e=0,o=this.options.columns.length;o>e;e++){var i=this.options.columns[e].key;this.cellProcessors[i].onClick(t)}var a=this.getEventTarget(t,"TD");a&&"TD"==a.tagName&&this.focusCell(a,!0)}},e.prototype.onKeydown=function(t){if(65==t.keyCode&&t.altKey&&this.options.adding)return this.addRecord(t.shiftKey?"above":"below"),void this.stopEvent(t);if(68==t.keyCode&&t.altKey&&this.options.deleting)return this.deleteRecord(),void this.stopEvent(t);for(var e=0,o=this.options.columns.length;o>e;e++){var i=this.options.columns[e].key;this.cellProcessors[i].onKeyDown(t)}this.navigation.onKeydown(t)===!1},e.prototype.onFormSubmit=function(t,e){if(e.handler==this.options.postbackHandlerName){if(this.unfocusTable(),!this.validate())return void t.preventDefault();var o=this.options.alias.indexOf("[")>-1?this.options.alias+"[TableData]":this.options.alias+"TableData";e.options.data[o]=this.dataSource.getAllData()}},e.prototype.onToolbarClick=function(t){var e=this.getEventTarget(t),o=e.getAttribute("data-cmd");switch(o){case"record-add-below":this.addRecord("below");break;case"record-add-above":this.addRecord("above");break;case"record-delete":this.deleteRecord()}this.stopEvent(t)},e.prototype.onDocumentClick=function(t){var e=this.getEventTarget(t);this.parentContainsElement(this.el,e)||this.activeCellProcessor&&this.activeCellProcessor.elementBelongsToProcessor(e)||this.unfocusTable()},e.prototype.dispose=function(){this.unfocusTable(),this.dataSource.dispose(),this.dataSource=null,this.unregisterHandlers(),this.dataTable=null,this.headerTable=null,this.toolbar=null,this.disposeCellProcessors(),this.navigation.dispose(),this.navigation=null,this.disposeScrollbar(),this.el=null,this.tableContainer=null,this.$el=null,this.dataTableContainer=null,this.activeCell=null},e.prototype.getElement=function(){return this.el},e.prototype.getAlias=function(){return this.options.alias},e.prototype.getTableContainer=function(){return this.tableContainer},e.prototype.getDataTableBody=function(){return this.dataTable.children[0]},e.prototype.getEventTarget=function(t,e){var o=t.target?t.target:t.srcElement;if(void 0===e)return o;for(var i=o.tagName;i!=e;){if(o=o.parentNode,!o)return null;i=o.tagName}return o},e.prototype.stopEvent=function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,t.preventDefault?t.preventDefault():t.returnValue=!1},e.prototype.elementHasClass=function(t,e){return t.classList?t.classList.contains(e):new RegExp("(^| )"+e+"( |$)","gi").test(t.className)},e.prototype.elementAddClass=function(t,e){this.elementHasClass(t,e)||(t.classList?t.classList.add(e):t.className+=" "+e)},e.prototype.elementRemoveClass=function(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," ")},e.prototype.parentContainsElement=function(t,e){for(;e&&e!=t;)e=e.parentNode;return e?!0:!1},e.prototype.getCellValue=function(t){return t.querySelector("[data-container]").value},e.prototype.getCellRowKey=function(t){return parseInt(t.parentNode.getAttribute("data-row"))},e.prototype.findRowByKey=function(t){return this.dataTable.querySelector('tbody tr[data-row="'+t+'"]')},e.prototype.findRowByIndex=function(t){return this.getDataTableBody().children[t]},e.prototype.getCellRowIndex=function(t){return parseInt(t.parentNode.rowIndex)},e.prototype.getRowCellValueByColumnName=function(t,e){var o=t.querySelector('td[data-column="'+e+'"]');return o?this.getCellValue(o):o},e.prototype.getRowData=function(t){for(var e={},o=0,i=t.children.length;i>o;o++){var a=t.children[o];e[a.getAttribute("data-column")]=this.getCellValue(a)}return e},e.prototype.setCellValue=function(t,e){var o=t.querySelector("[data-container]");o.value!=e&&(o.value=e,this.markCellRowDirty(t),this.notifyRowProcessorsOnChange(t))},e.DEFAULTS={clientDataSourceClass:"client",keyColumn:"id",recordsPerPage:!1,data:null,postback:!0,postbackHandlerName:"onSave",adding:!0,deleting:!0,toolbar:!0,rowSorting:!1,height:!1,dynamicHeight:!1};var o=t.fn.table;t.fn.table=function(o){var i=Array.prototype.slice.call(arguments,1),a=void 0;return this.each(function(){var n=t(this),s=n.data("oc.table"),r=t.extend({},e.DEFAULTS,n.data(),"object"==typeof o&&o);return s||n.data("oc.table",s=new e(this,r)),"string"==typeof o&&(a=s[o].apply(s,i)),"undefined"!=typeof a?!1:void 0}),a?a:this},t.fn.table.Constructor=e,t.oc.table.table=e,t.fn.table.noConflict=function(){return t.fn.table=o,this},t(document).on("render",function(){t("div[data-control=table]").table()})}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");void 0===t.oc.table.datasource&&(t.oc.table.datasource={});var e=function(t){this.tableObj=t};e.prototype.dispose=function(){this.tableObj=null},e.prototype.getRecords=function(t,e,o){o([])},e.prototype.createRecord=function(t,e,o,i,a,n){n([],0)},e.prototype.updateRecord=function(t,e){},e.prototype.deleteRecord=function(t,e,o,i,a){a([],0)},t.oc.table.datasource.base=e}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");void 0===t.oc.table.processor&&(t.oc.table.processor={});var e=function(t,e,o){this.tableObj=t,this.columnName=e,this.columnConfiguration=o,this.activeCell=null,this.validators=[],this.registerHandlers(),this.initValidators()};e.prototype.dispose=function(){this.unregisterHandlers(),this.tableObj=null,this.activeCell=null},e.prototype.renderCell=function(t,e){},e.prototype.registerHandlers=function(){},e.prototype.unregisterHandlers=function(){},e.prototype.onFocus=function(t,e){},e.prototype.onUnfocus=function(){},e.prototype.onKeyDown=function(t){},e.prototype.onClick=function(t){},e.prototype.onRowValueChanged=function(t,e){},e.prototype.keyNavigationAllowed=function(t,e){return!0},e.prototype.isCellFocusable=function(){return!0},e.prototype.getCellContentContainer=function(t){return t.querySelector(".content-container")},e.prototype.createViewContainer=function(t,e){var o=document.createElement("div");return o.setAttribute("data-view-container","data-view-container"),o.textContent=e,t.appendChild(o),o},e.prototype.getViewContainer=function(t){return t.querySelector("[data-view-container]")},e.prototype.showViewContainer=function(t){return this.getViewContainer(t).setAttribute("class","")},e.prototype.hideViewContainer=function(t){return this.getViewContainer(t).setAttribute("class","hide")},e.prototype.setViewContainerValue=function(t,e){return this.getViewContainer(t).textContent=e},e.prototype.elementBelongsToProcessor=function(t){return!1},e.prototype.initValidators=function(){if(void 0!==this.columnConfiguration.validation)for(var e in this.columnConfiguration.validation){if(void 0===t.oc.table.validator||void 0==t.oc.table.validator[e])throw new Error('The table cell validator "'+e+'" for the column "'+this.columnName+'" is not found in the $.oc.table.validator namespace.');var o=new t.oc.table.validator[e](this.columnConfiguration.validation[e]);this.validators.push(o)}},e.prototype.validate=function(t,e){for(var o=0,i=this.validators.length;i>o;o++){var a=this.validators[o].validate(t,e);if(void 0!==a)return a}},t.oc.table.processor.base=e}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");void 0===t.oc.table.helper&&(t.oc.table.helper={});var e=function(t){this.tableObj=t,this.pageIndex=0,this.pageCount=0,this.init()};e.prototype.init=function(){},e.prototype.dispose=function(){this.tableObj=null},e.prototype.paginationEnabled=function(){return null!=this.tableObj.options.recordsPerPage&&0!=this.tableObj.options.recordsPerPage},e.prototype.getPageFirstRowOffset=function(){return this.pageIndex*this.tableObj.options.recordsPerPage},e.prototype.buildPagination=function(t){if(this.paginationEnabled()){var e=this.tableObj.getElement().querySelector(".pagination"),o=!1,i=0;if(this.pageCount=this.calculatePageCount(t,this.tableObj.options.recordsPerPage),e?i=this.getRecordCount(e):(e=document.createElement("div"),e.setAttribute("class","pagination"),o=!0),o||i!=t){e.setAttribute("data-record-count",t);var a=this.buildPaginationLinkList(t,this.tableObj.options.recordsPerPage,this.pageIndex);o?(e.appendChild(a),this.tableObj.getElement().appendChild(e)):e.replaceChild(a,e.children[0])}else this.markActiveLinkItem(e,this.pageIndex)}},e.prototype.calculatePageCount=function(t,e){var o=Math.ceil(t/e);return o||(o=1),o},e.prototype.getRecordCount=function(t){var e=t?t:this.tableObj.getElement().querySelector(".pagination");return parseInt(e.getAttribute("data-record-count"))},e.prototype.buildPaginationLinkList=function(t,e,o){for(var i=this.calculatePageCount(t,e),a=document.createElement("ul"),n=0;i>n;n++){var s=document.createElement("li"),r=document.createElement("a");n==o&&s.setAttribute("class","active"),r.innerText=n+1,r.setAttribute("data-page-index",n),r.setAttribute("href","#"),s.appendChild(r),a.appendChild(s)}return a},e.prototype.markActiveLinkItem=function(t,e){var o=t.querySelector(".active"),i=t.children[0];o.setAttribute("class","");for(var a=0,n=i.children.length;n>a;a++)a==e&&i.children[a].setAttribute("class","active")},e.prototype.gotoPage=function(t,e){this.tableObj.unfocusTable(),this.tableObj.validate()&&(this.pageIndex=t,this.tableObj.updateDataTable(e))},e.prototype.getRowCountOnPage=function(t){return this.tableObj.getDataTableBody().children.length},e.prototype.getNewRowPage=function(t,e){var o=this.getRecordCount();return"bottom"===t?this.calculatePageCount(o+1,this.tableObj.options.recordsPerPage)-1:"above"==t?this.pageIndex:"below"==t&&e==this.tableObj.options.recordsPerPage-1?this.pageIndex+1:this.pageIndex},e.prototype.getPageAfterDeletion=function(t){return 0==t&&1==this.getRowCountOnPage()?0==this.pageIndex?0:this.pageIndex-1:this.pageIndex},e.prototype.navigateDown=function(t,e){if(this.tableObj.activeCell&&(!this.tableObj.activeCellProcessor||this.tableObj.activeCellProcessor.keyNavigationAllowed(t,"down"))){var o=this.tableObj.activeCell.parentNode,i=t.shiftKey?o.parentNode.children[o.parentNode.children.length-1]:o.nextElementSibling,a=void 0!==e?e:this.tableObj.activeCell.cellIndex;if(i){var n=i.children[a];n&&this.tableObj.focusCell(n)}else{if(!this.paginationEnabled())return;if(this.pageIndex0){var r=this;this.gotoPage(this.pageIndex-1,function l(){r.focusCell("bottom",n),r=null})}}}},e.prototype.navigateLeft=function(t,e){if(this.tableObj.activeCell&&(e||!this.tableObj.activeCellProcessor||this.tableObj.activeCellProcessor.keyNavigationAllowed(t,"left"))){var o=this.tableObj.activeCell.parentNode,i=!t.shiftKey||e?this.tableObj.activeCell.cellIndex-1:0,a=o.children[i];a?this.tableObj.focusCell(a):this.navigateUp(t,o.children.length-1,e)}},e.prototype.navigateRight=function(t,e){if(this.tableObj.activeCell&&(e||!this.tableObj.activeCellProcessor||this.tableObj.activeCellProcessor.keyNavigationAllowed(t,"right"))){var o=this.tableObj.activeCell.parentNode,i=t.shiftKey?o.children.length-1:this.tableObj.activeCell.cellIndex+1,a=o.children[i];a?this.tableObj.focusCell(a):this.navigateDown(t,0)}},e.prototype.navigateNext=function(t){this.tableObj.activeCell&&(!this.tableObj.activeCellProcessor||this.tableObj.activeCellProcessor.keyNavigationAllowed(t,"tab"))&&(t.shiftKey?this.navigateLeft(t,!0):this.navigateRight(t,!0),this.tableObj.stopEvent(t))},e.prototype.focusCell=function(t,e){var o=null,i=this.tableObj.getDataTableBody();if("object"==typeof t?o=t:"bottom"==t?o=i.children[i.children.length-1]:"top"==t&&(o=i.children[0]),o){var a=o.children[e];a&&this.tableObj.focusCell(a)}},e.prototype.focusCellInReplacedRow=function(t,e){if(0==t)this.focusCell("top",e);else{var o=this.tableObj.findRowByIndex(t);o||(o=this.tableObj.findRowByIndex(t-1)),o?this.focusCell(o,e):this.focusCell("top",e)}},e.prototype.onKeydown=function(t){return 40==t.keyCode?this.navigateDown(t):38==t.keyCode?this.navigateUp(t):37==t.keyCode?this.navigateLeft(t):39==t.keyCode?this.navigateRight(t):9==t.keyCode?this.navigateNext(t):void 0},e.prototype.onClick=function(t){var e=this.tableObj.getEventTarget(t,"A");if(e){var o=parseInt(e.getAttribute("data-page-index"));if(null!==o)return this.gotoPage(o),this.tableObj.stopEvent(t),!1}},t.oc.table.helper.navigation=e}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.datasource)throw new Error("The $.oc.table.datasource namespace is not defined. Make sure that the table.datasource.base.js script is loaded.");var e=t.oc.table.datasource.base,o=e.prototype,i=function(t){e.call(this,t);var o=t.getElement().getAttribute("data-data");if(null===o||void 0===o)throw new Error("The required data-data attribute is not found on the table control element.");this.data=JSON.parse(o)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.dispose=function(){o.dispose.call(this),this.data=null},i.prototype.getRecords=function(t,e,o){e?o(this.data.slice(t,t+e),this.data.length):o(this.data,this.data.length)},i.prototype.createRecord=function(t,e,o,i,a,n){if("bottom"===e)this.data.push(t);else if("above"==e||"below"==e){var s=this.getIndexOfKey(o);"below"==e&&s++,this.data.splice(s,0,t)}this.getRecords(i,a,n)},i.prototype.updateRecord=function(t,e){var o=this.getIndexOfKey(t);if(-1===o)throw new Error("Record with they key "+t+" is not found in the data set");e[this.tableObj.options.keyColumn]=t,this.data[o]=e},e.prototype.deleteRecord=function(t,e,o,i,a){var n=this.getIndexOfKey(t);if(-1===n)throw new Error("Record with they key "+t+" is not found in the data set");this.data.splice(n,1),0==this.data.length&&this.data.push(e),this.getRecords(o,i,a)},i.prototype.getIndexOfKey=function(t){var e=this.tableObj.options.keyColumn;return this.data.map(function(t){return t[e]+""}).indexOf(t+"")},i.prototype.getAllData=function(){return this.data},t.oc.table.datasource.client=i}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.processor)throw new Error("The $.oc.table.processor namespace is not defined. Make sure that the table.processor.base.js script is loaded.");var e=t.oc.table.processor.base,o=e.prototype,i=function(t,o,i){e.call(this,t,o,i)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.dispose=function(){o.dispose.call(this)},i.prototype.isCellFocusable=function(){return!1},i.prototype.renderCell=function(t,e){var o=document.createElement("div");o.setAttribute("data-checkbox-element","true"),o.setAttribute("tabindex","0"),t&&0!=t&&"false"!=t&&o.setAttribute("class","checked"),e.appendChild(o)},i.prototype.onFocus=function(t,e){t.querySelector("div[data-checkbox-element]").focus()},i.prototype.onKeyDown=function(t){32==t.keyCode&&this.onClick(t)},i.prototype.onClick=function(t){var e=this.tableObj.getEventTarget(t,"DIV");e.getAttribute("data-checkbox-element")&&this.changeState(e)},i.prototype.changeState=function(t){var e=t.parentNode.parentNode;"checked"==t.getAttribute("class")?(t.setAttribute("class",""),this.tableObj.setCellValue(e,0)):(t.setAttribute("class","checked"),this.tableObj.setCellValue(e,1))},t.oc.table.processor.checkbox=i}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.processor)throw new Error("The $.oc.table.processor namespace is not defined. Make sure that the table.processor.base.js script is loaded.");var e=t.oc.table.processor.base,o=e.prototype,i=function(t,o,i){this.itemListElement=null,this.cachedOptionPromises={},this.itemClickHandler=this.onItemClick.bind(this),this.itemKeyDownHandler=this.onItemKeyDown.bind(this),e.call(this,t,o,i)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.dispose=function(){this.unregisterListHandlers(),this.itemClickHandler=null,this.itemKeyDownHandler=null,this.itemListElement=null,this.cachedOptionPromises=null,o.dispose.call(this)},i.prototype.unregisterListHandlers=function(){this.itemListElement&&(this.itemListElement.removeEventListener("click",this.itemClickHandler),this.itemListElement.removeEventListener("keydown",this.itemKeyDownHandler))},i.prototype.renderCell=function(t,e){var o=this.createViewContainer(e,"...");this.fetchOptions(e.parentNode,function i(a){void 0!==a[t]&&(o.textContent=a[t]),e.setAttribute("tabindex",0)})},i.prototype.onFocus=function(t,e){if(this.activeCell===t)return void this.showDropdown();this.activeCell=t;var o=this.getCellContentContainer(t);this.buildEditor(t,o,e),e||o.focus()},i.prototype.onUnfocus=function(){this.activeCell&&(this.unregisterListHandlers(),this.hideDropdown(),this.itemListElement=null,this.activeCell=null)},i.prototype.buildEditor=function(t,e,o){var i=this.tableObj.getCellValue(t),a=this.getAbsolutePosition(e);self=this,this.itemListElement=document.createElement("div"),this.itemListElement.addEventListener("click",this.itemClickHandler),this.itemListElement.addEventListener("keydown",this.itemKeyDownHandler),this.itemListElement.setAttribute("class","table-control-dropdown-list"),this.itemListElement.style.width=e.offsetWidth+"px",this.itemListElement.style.left=a.left+"px",this.itemListElement.style.top=a.top-2+e.offsetHeight+"px",this.fetchOptions(t,function n(t){var e=document.createElement("ul");for(var a in t){var n=document.createElement("li");n.setAttribute("data-value",a),n.textContent=t[a],n.setAttribute("tabindex",0),a==i&&n.setAttribute("class","selected"),e.appendChild(n)}self.itemListElement.appendChild(e),o&&self.showDropdown(),self=null})},i.prototype.hideDropdown=function(){if(this.itemListElement&&this.activeCell&&this.itemListElement.parentNode){var t=this.getCellContentContainer(this.activeCell);t.setAttribute("data-dropdown-open","false"),this.itemListElement.parentNode.removeChild(this.itemListElement),t.focus()}},i.prototype.showDropdown=function(){if(this.itemListElement&&this.itemListElement.parentNode!==document.body){this.getCellContentContainer(this.activeCell).setAttribute("data-dropdown-open","true"),document.body.appendChild(this.itemListElement);var t=this.itemListElement.querySelector("ul li.selected");t||(t=this.itemListElement.querySelector("ul li:first-child"),t&&t.setAttribute("class","selected")),t&&window.setTimeout(function(){t.focus()},0)}},i.prototype.fetchOptions=function(t,e){if(this.columnConfiguration.options)e(this.columnConfiguration.options);else{var o=t.parentNode,i=this.createOptionsCachingKey(o),a=this.getViewContainer(t);if(a.setAttribute("class","loading"),!this.cachedOptionPromises[i]){var n={column:this.columnName,rowData:this.tableObj.getRowData(o)},s=this.tableObj.getAlias()+"::onGetDropdownOptions";this.cachedOptionPromises[i]=this.tableObj.$el.request(s,{data:n})}this.cachedOptionPromises[i].done(function r(t){e(t.options)}).always(function l(){a.setAttribute("class","")})}},i.prototype.createOptionsCachingKey=function(t){var e="non-dependent",o=this.columnConfiguration.dependsOn;if(o)if("object"==typeof o)for(var i=0,a=o.length;a>i;i++)e+=o[i]+this.tableObj.getRowCellValueByColumnName(t,o[i]);else e=o+this.tableObj.getRowCellValueByColumnName(t,o);return e},i.prototype.getAbsolutePosition=function(t){var e=document.body.scrollTop,o=0;do e+=t.offsetTop||0,e-=t.scrollTop||0,o+=t.offsetLeft||0,t=t.offsetParent;while(t);return{top:e,left:o}},i.prototype.updateCellFromSelectedItem=function(t){this.tableObj.setCellValue(this.activeCell,t.getAttribute("data-value")),this.setViewContainerValue(this.activeCell,t.textContent)},i.prototype.findSelectedItem=function(){return this.itemListElement?this.itemListElement.querySelector("ul li.selected"):null -},i.prototype.onItemClick=function(t){var e=this.tableObj.getEventTarget(t);if("LI"==e.tagName){this.updateCellFromSelectedItem(e);var o=this.findSelectedItem();o&&o.setAttribute("class",""),e.setAttribute("class","selected"),this.hideDropdown()}},i.prototype.onItemKeyDown=function(t){if(this.itemListElement){if(40==t.keyCode||38==t.keyCode){var e=this.findSelectedItem(),o=e.nextElementSibling;return 38==t.keyCode&&(o=e.previousElementSibling),void(o&&(e.setAttribute("class",""),o.setAttribute("class","selected"),o.focus()))}if(13==t.keyCode||32==t.keyCode)return this.updateCellFromSelectedItem(this.findSelectedItem()),void this.hideDropdown();9==t.keyCode&&(this.updateCellFromSelectedItem(this.findSelectedItem()),this.tableObj.navigation.navigateNext(t),this.tableObj.stopEvent(t)),27==t.keyCode&&this.hideDropdown()}},i.prototype.onKeyDown=function(t){32==t.keyCode&&this.showDropdown()},i.prototype.onRowValueChanged=function(t,e){if(this.columnConfiguration.dependsOn){var o=!1,i=this.columnConfiguration.dependsOn;if("object"==typeof i){for(var a=0,n=i.length;n>a;a++)if(i[a]==t){o=!0;break}}else o=i==t;if(o){var s=this.tableObj.getCellValue(e),r=this.getViewContainer(e);this.fetchOptions(e,function l(t){var e=void 0!==t[s]?t[s]:"...";r.textContent=e,r=null})}}},i.prototype.elementBelongsToProcessor=function(t){return this.itemListElement?this.tableObj.parentContainsElement(this.itemListElement,t):!1},t.oc.table.processor.dropdown=i}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.processor)throw new Error("The $.oc.table.processor namespace is not defined. Make sure that the table.processor.base.js script is loaded.");var e=t.oc.table.processor.base,o=e.prototype,i=function(t,o,i){this.focusTimeoutHandler=this.onFocusTimeout.bind(this),e.call(this,t,o,i)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.dispose=function(){o.dispose.call(this),this.focusTimeoutHandler=null},i.prototype.renderCell=function(t,e){this.createViewContainer(e,t)},i.prototype.onFocus=function(t,e){this.activeCell!==t&&(this.activeCell=t,this.buildEditor(t,this.getCellContentContainer(t)))},i.prototype.onUnfocus=function(){if(this.activeCell){var t=this.activeCell.querySelector(".string-input");t&&(this.tableObj.setCellValue(this.activeCell,t.value),this.setViewContainerValue(this.activeCell,t.value),t.parentNode.removeChild(t)),this.showViewContainer(this.activeCell),this.activeCell=null}},i.prototype.buildEditor=function(t,e){this.hideViewContainer(this.activeCell);var o=document.createElement("input");o.setAttribute("type","text"),o.setAttribute("class","string-input"),o.value=this.tableObj.getCellValue(t),e.appendChild(o),this.setCaretPosition(o,0),window.setTimeout(this.focusTimeoutHandler,0)},i.prototype.keyNavigationAllowed=function(t,e){if("left"!=e&&"right"!=e)return!0;if(!this.activeCell)return!0;var o=this.activeCell.querySelector(".string-input");if(!o)return!0;var i=this.getCaretPosition(o);return"left"==e?0==i:"right"==e?i==o.value.length:!0},i.prototype.onFocusTimeout=function(){if(this.activeCell){var t=this.activeCell.querySelector(".string-input");t&&(t.focus(),this.setCaretPosition(t,0))}},i.prototype.getCaretPosition=function(t){if(document.selection){var e=document.selection.createRange();return e.moveStart("character",-t.value.length),e.text.length}return void 0!==t.selectionStart?t.selectionStart:0},i.prototype.setCaretPosition=function(t,e){if(document.selection){var o=t.createTextRange();setTimeout(function(){o.collapse(!0),o.moveStart("character",e),o.moveEnd("character",0),o.select()},0)}return void 0!==t.selectionStart&&setTimeout(function(){t.selectionStart=e,t.selectionEnd=e},0),0},t.oc.table.processor.string=i}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");void 0===t.oc.table.validator&&(t.oc.table.validator={});var e=function(t){this.options=t};e.prototype.validate=function(t,e){return void 0===this.options.applyIfNotEmpty||this.rowHasValue(this.options.applyIfNotEmpty,e)?this.validateValue(t,e):void 0},e.prototype.validateValue=function(t,e){},e.prototype.trim=function(t){return String.prototype.trim?t.trim():t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")},e.prototype.getMessage=function(t){return void 0!==this.options.message?this.options.message:t},e.prototype.rowHasValue=function(t,e){if(void 0===e[t])return!1;if("boolean"==typeof e[t])return e[t];var o=this.trim(String(e[t]));return o.length>0},t.oc.table.validator.base=e}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.validator)throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");var e=t.oc.table.validator.base,o=e.prototype,i=function(t){e.call(this,t)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.validateValue=function(t,e){return t=this.trim(t),0===t.length?this.getMessage("The value should not be empty."):void 0},t.oc.table.validator.required=i}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.validator)throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");var e=t.oc.table.validator.base,o=e.prototype,i=function(t){e.call(this,t)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.doCommonChecks=function(t){if(void 0!==this.options.min||void 0!==this.options.max){if(void 0!==this.options.min){if(void 0===this.options.min.value)throw new Error("The min.value parameter is not defined in the table validator configuration");if(tthis.options.max.value)return void 0!==this.options.max.message?this.options.max.message:"The value should not be more than "+this.options.max.value}}},t.oc.table.validator.baseNumber=i}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.validator)throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");if(void 0===t.oc.table.validator.baseNumber)throw new Error("The $.oc.table.validator.baseNumber namespace is not defined. Make sure that the table.validator.baseNumber.js script is loaded.");var e=t.oc.table.validator.baseNumber,o=e.prototype,i=function(t){e.call(this,t)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.validateValue=function(t,e){if(t=this.trim(t),0!=t.length){var o=this.options.allowNegative?/^\-?[0-9]*$/.test(t):/^[0-9]*$/.test(t);if(!o){var i=this.options.allowNegative?"The value should be an integer.":"The value should be a positive integer";return this.getMessage(i)}return this.doCommonChecks(parseInt(t))}},t.oc.table.validator.integer=i}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.validator)throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");if(void 0===t.oc.table.validator.baseNumber)throw new Error("The $.oc.table.validator.baseNumber namespace is not defined. Make sure that the table.validator.baseNumber.js script is loaded.");var e=t.oc.table.validator.baseNumber,o=e.prototype,i=function(t){e.call(this,t)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.validateValue=function(t,e){if(t=this.trim(t),0!=t.length){var o=this.options.allowNegative?/^[-]?([0-9]+\.[0-9]+|[0-9]+)$/.test(t):/^([0-9]+\.[0-9]+|[0-9]+)$/.test(t);if(!o){var i=this.options.allowNegative?"The value should be a floating point number.":"The value should be a positive floating point number";return this.getMessage(i)}return this.doCommonChecks(parseFloat(t))}},t.oc.table.validator.float=i}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.validator)throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");var e=t.oc.table.validator.base,o=e.prototype,i=function(t){e.call(this,t)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.validateValue=function(t,e){if(t=this.trim(t),0!=t.length&&(void 0!==this.options.min||void 0!==this.options.max)){if(void 0!==this.options.min){if(void 0===this.options.min.value)throw new Error("The min.value parameter is not defined in the Length table validator configuration");if(t.lengththis.options.max.value)return void 0!==this.options.max.message?this.options.max.message:"The string should not be longer than "+this.options.max.value}}},t.oc.table.validator.length=i}(window.jQuery),+function(t){"use strict";if(void 0===t.oc.table)throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");if(void 0===t.oc.table.validator)throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");var e=t.oc.table.validator.base,o=e.prototype,i=function(t){e.call(this,t)};i.prototype=Object.create(o),i.prototype.constructor=i,i.prototype.validateValue=function(t,e){if(t=this.trim(t),0!=t.length){if(void 0===this.options.pattern)throw new Error("The pattern parameter is not defined in the Regex table validator configuration");var o=new RegExp(this.options.pattern,this.options.modifiers);return o.test(t)?void 0:this.getMessage("Invalid value format.")}},t.oc.table.validator.regex=i}(window.jQuery); -//# sourceMappingURL=./table-min.map \ No newline at end of file