UNPKG

tui-grid

Version:

TOAST UI Grid : Powerful data grid control supported by TOAST UI

237 lines (200 loc) 7.3 kB
/** * @fileoverview Controller class to handle actions from the painters * @author NHN. FE Development Lab <dl_javascript@nhn.com> */ 'use strict'; var $ = require('jquery'); var _ = require('underscore'); var snippet = require('tui-code-snippet'); var util = require('../common/util'); /** * Controller class to handle actions from the painters * @module painter/controller * @param {Object} options - options * @ignore */ var PainterController = snippet.defineClass(/** @lends module:painter/controller.prototype */{ init: function(options) { this.focusModel = options.focusModel; this.dataModel = options.dataModel; this.columnModel = options.columnModel; this.selectionModel = options.selectionModel; }, /** * Starts editing a cell identified by a given address, and returns the result. * @param {{rowKey:String, columnName:String}} address - cell address * @param {Boolean} force - if set to true, finish current editing before start. * @returns {Boolean} true if succeeded, false otherwise */ startEditing: function(address, force) { var result; if (force) { this.focusModel.finishEditing(); } result = this.focusModel.startEditing(address.rowKey, address.columnName); if (result) { this.selectionModel.end(); } return result; }, /** * Check if given column has 'maxLength' property and returns the substring limited by maxLength. * @param {string} columnName - columnName * @param {string} value - value * @returns {string} * @private */ _checkMaxLength: function(columnName, value) { var column = this.columnModel.getColumnModel(columnName); var maxLength = snippet.pick(column, 'editOptions', 'maxLength'); if (maxLength > 0 && value.length > maxLength) { return value.substring(0, maxLength); } return value; }, /** * Ends editing a cell identified by a given address, and returns the result. * @param {{rowKey:String, columnName:String}} address - cell address * @param {Boolean} shouldBlur - if set to true, make the current input lose focus. * @param {String} [value] - if exists, set the value of the data model to this value. * @returns {Boolean} - true if succeeded, false otherwise */ finishEditing: function(address, shouldBlur, value) { var focusModel = this.focusModel; var row, currentValue; if (!focusModel.isEditingCell(address.rowKey, address.columnName)) { return false; } this.selectionModel.enable(); if (!_.isUndefined(value)) { row = this.dataModel.get(address.rowKey); currentValue = row.get(address.columnName); if (!(util.isBlank(value) && util.isBlank(currentValue))) { this.setValue(address, this._checkMaxLength(address.columnName, value)); } } focusModel.finishEditing(); if (shouldBlur) { focusModel.focusClipboard(); } else { _.defer(function() { focusModel.refreshState(); }); } return true; }, /** * Moves focus to the next cell, and starts editing the cell. * @param {Boolean} reverse - if set to true, find the previous cell instead of next cell */ focusInToNextCell: function(reverse) { var focusModel = this.focusModel; var address = reverse ? focusModel.prevAddress() : focusModel.nextAddress(); focusModel.focusIn(address.rowKey, address.columnName, true); }, /** * Moves focus to the first cell of the given row, and starts editing the cell. * @param {number} rowKey - rowKey */ focusInToRow: function(rowKey) { var focusModel = this.focusModel; focusModel.focusIn(rowKey, focusModel.firstColumnName(), true); }, /** * Executes the custom handler (defined by user) of the input events. * @param {Event} event - DOM Event object * @param {{rowKey:String, columnName:String}} address - cell address */ executeCustomInputEventHandler: function(event, address) { var columnModel = this.columnModel.getColumnModel(address.columnName); var eventType, editOptions, handler; if (!columnModel) { return; } eventType = event.type; editOptions = columnModel.editOptions || {}; handler = editOptions[getEventHandlerName(eventType)]; if (_.isFunction(handler)) { handler.call(event.target, event, address); } }, /** * Sets the value of the given cell. * @param {{rowKey:String, columnName:String}} address - cell address * @param {(Number|String|Boolean)} value - value */ setValue: function(address, value) { var columnModel = this.columnModel.getColumnModel(address.columnName); if (_.isString(value)) { value = $.trim(value); } if (columnModel.validation && columnModel.validation.dataType === 'number') { value = convertToNumber(value); } if (columnModel.name === '_button') { if (value) { this.dataModel.check(address.rowKey); } else { this.dataModel.uncheck(address.rowKey); } } else { this.dataModel.setValue(address.rowKey, address.columnName, value); } }, /** * Sets the value of the given cell, if the given column is not using view-mode. * @param {{rowKey:String, columnName:String}} address - cell address * @param {(Number|String|Boolean)} value - value */ setValueIfNotUsingViewMode: function(address, value) { var columnModel = this.columnModel.getColumnModel(address.columnName); if (!snippet.pick(columnModel, 'editOptions', 'useViewMode')) { this.setValue(address, value); } }, /** * Change tree expanded state * @param {string} rowKey - Row key * @param {boolean} state - State of expanded */ changeTreeExpanded: function(rowKey, state) { if (state) { this.dataModel.treeCollapse(rowKey); } else { this.dataModel.treeExpand(rowKey); } } }); /** * Converts given value to a number type and returns it. * If the value is not a number type, returns the original value. * @param {*} value - value * @returns {*} */ function convertToNumber(value) { if (_.isString(value)) { value = value.replace(/,/g, ''); } if (_.isNumber(value) || isNaN(value) || util.isBlank(value)) { return value; } return Number(value); } /** * Returns a property name of a custom event handler matched to the given eventType * @param {string} eventType - event type * @returns {string} */ function getEventHandlerName(eventType) { switch (eventType) { case 'focusin': return 'onFocus'; case 'focusout': return 'onBlur'; case 'keydown': return 'onKeyDown'; default: return ''; } } module.exports = PainterController;