tui-grid
Version:
TOAST UI Grid : Powerful data grid control supported by TOAST UI
1,185 lines (1,067 loc) • 60.6 kB
JavaScript
/**
* @fileoverview The Grid class for the external API.
* @author NHN. FE Development Lab <dl_javascript@nhn.com>
*/
'use strict';
var _ = require('underscore');
var snippet = require('tui-code-snippet');
var View = require('./base/view');
var ModelManager = require('./model/manager');
var ViewFactory = require('./view/factory');
var DomEventBus = require('./event/domEventBus');
var DomState = require('./domState');
var PublicEventEmitter = require('./publicEventEmitter');
var PainterManager = require('./painter/manager');
var PainterController = require('./painter/controller');
var NetAddOn = require('./addon/net');
var ComponentHolder = require('./componentHolder');
var util = require('./common/util');
var i18n = require('./common/i18n');
var themeManager = require('./theme/manager');
var themeNameConst = require('./common/constMap').themeName;
var instanceMap = {};
/**
* Grid public API
* @class Grid
* @param {Object} options
* @param {Array} [options.data] - Grid data for making rows.
* @param {Object} [options.header] - Options object for header.
* @param {number} [options.header.height=40] - The height of the header area.
* @param {Array} [options.header.complexColumns] - This options creates new parent headers of the multiple columns
* which includes the headers of spcified columns, and sets up the hierarchy.
* @param {boolean} [options.virtualScrolling=false] - If set to true, use virtual-scrolling so that large
* amount of data can be processed performantly. When using this option that sets true, the rowHeight option
* must set value.
* @param {string|number} [options.rowHeight] - The height of each rows. The default value is 'auto',
* the height of each rows expands to dom's height. If set to number, the height is fixed.
* @param {number} [options.minRowHeight=40] - The minimum height of each rows. When this value is larger than
* the row's height, it set to the row's height.
* @param {string|number} [options.bodyHeight] - The height of body area. The default value is 'auto',
* the height of body area expands to total height of rows. If set to 'fitToParent', the height of the grid
* will expand to fit the height of parent element. If set to number, the height is fixed.
* @param {number} [options.minBodyHeight=minRowHeight] - The minimum height of body area. When this value
* is larger than the body's height, it set to the body's height.
* @param {Object} [options.columnOptions] - Option object for all columns
* @param {number} [options.columnOptions.minWidth=50] - Minimum width of each columns
* @param {boolean} [options.columnOptions.resizable=true] - If set to true, resize-handles of each columns
* will be shown.
* @param {number} [options.columnOptions.frozenCount=0] - The number of frozen columns.
* The columns indexed from 0 to this value will always be shown on the left side.
* {@link Grid#setFrozenColumnCount} can be used for setting this value dynamically.
* @param {number} [options.columnOptions.frozenBorderWidth=1] - The value of frozen border width.
* When the frozen columns are created by "frozenCount" option, the frozen border width set.
* @param {Object} [options.treeColumnOptions] - Option object for the tree column.
* @param {string} [options.treeColumnOptions.name] - The name of column that makes tree column.
* @param {boolean} [options.treeColumnOptions.useIcon=true] - If set to true, the folder or file icon is created on
* the left side of the tree cell data.
* @param {boolean} [options.treeColumnOptions.useCascadingCheckbox] - If set to true, a cascading relationship is
* created in the checkbox between parent and child rows.
* @param {Object} [options.copyOptions] - Option object for clipboard copying
* @param {boolean} [options.copyOptions.useFormattedValue] - Whether to use formatted values or original values
* as a string to be copied to the clipboard
* @param {boolean} [options.useClientSort=true] - If set to true, sorting will be executed by client itself
* without server.
* @param {string} [options.editingEvent='dblclick'] - If set to 'click', editable cell in the view-mode will be
* changed to edit-mode by a single click.
* @param {boolean} [options.scrollX=true] - Specifies whether to show horizontal scrollbar.
* @param {boolean} [options.scrollY=true] - Specifies whether to show vertical scrollbar.
* @param {boolean} [options.showDummyRows=false] - If set to true, empty area will be filled with dummy rows.
* @param {?string} [options.keyColumnName=null] - The name of the column to be used to identify each rows.
* If not specified, unique value for each rows will be created internally.
* @param {boolean} [options.heightResizable=false] - If set to true, a handle for resizing height will be shown.
* @param {Object} [options.pagination=null] - Options for tui.Pagination.
* If set to null or false, pagination will not be used.
* @param {string} [options.selectionUnit='cell'] - The unit of selection on Grid. ('cell', 'row')
* @param {Array} [options.rowHeaders] - Options for making the row header. The row header content is number of
* each row or input element. The value of each item is enable to set string type. (ex: ['rowNum', 'checkbox'])
* @param {string} [options.rowHeaders.type] - The type of the row header. ('rowNum', 'checkbox', 'radio')
* @param {string} [options.rowHeaders.title] - The title of the row header on the grid header area.
* @param {number} [options.rowHeaders.width] - The width of the row header.
* @param {function} [options.rowHeaders.template] - Template function which returns the content(HTML) of
* the row header. This function takes a parameter an K-V object as a parameter to match template values.
* @param {Array} options.columns - The configuration of the grid columns.
* @param {string} options.columns.name - The name of the column.
* @param {boolean} [options.columns.ellipsis=false] - If set to true, ellipsis will be used
* for overflowing content.
* @param {string} [options.columns.align=left] - Horizontal alignment of the column content.
* Available values are 'left', 'center', 'right'.
* @param {string} [options.columns.valign=middle] - Vertical alignment of the column content.
* Available values are 'top', 'middle', 'bottom'.
* @param {string} [options.columns.className] - The name of the class to be used for all cells of
* the column.
* @param {string} [options.columns.title] - The title of the column to be shown on the header.
* @param {number} [options.columns.width] - The width of the column. The unit is pixel. If this value
* isn't set, the column's width is automatically resized.
* @param {number} [options.columns.minWidth=50] - The minimum width of the column. The unit is pixel.
* @param {boolean} [options.columns.hidden] - If set to true, the column will not be shown.
* @param {boolean} [options.columns.resizable] - If set to false, the width of the column
* will not be changed.
* @param {Object} [options.columns.validation] - The options to be used for validation.
* Validation is executed whenever data is changed or the {@link Grid#validate} is called.
* @param {boolean} [options.columns.validation.required=false] - If set to true, the data of the column
* will be checked to be not empty.
* @param {string} [options.columns.validation.dataType='string'] - Specifies the type of the cell value.
* Avilable types are 'string' and 'number'.
* @param {string} [options.columns.defaultValue] - The default value to be shown when the column
* doesn't have a value.
* @param {function} [options.columns.formatter] - The function that formats the value of the cell.
* The retrurn value of the function will be shown as the value of the cell.
* @param {boolean} [options.columns.useHtmlEntity=true] - If set to true, the value of the cell
* will be encoded as HTML entities.
* @param {boolean} [options.columns.ignored=false] - If set to true, the value of the column will be
* ignored when setting up the list of modified rows.
* @param {boolean} [options.columns.sortable=false] - If set to true, sort button will be shown on
* the right side of the column header, which executes the sort action when clicked.
* @param {function} [options.columns.onBeforeChange] - The function that will be
* called before changing the value of the cell. If stop() method in event object is called,
* the changing will be canceled.
* @param {function} [options.columns.onAfterChange] - The function that will be
* called after changing the value of the cell.
* @param {Object} [options.columns.editOptions] - The object for configuring editing UI.
* @param {string} [options.columns.editOptions.type='text'] - The string value that specifies
* the type of the editing UI.
* Available values are 'text', 'password', 'select', 'radio', 'checkbox'.
* @param {boolean} [options.columns.editOptions.useViewMode=true] - If set to true, default mode
* of the cell will be the 'view-mode'. The mode will be switched to 'edit-mode' only when user
* double click or press 'ENTER' key on the cell. If set to false, the cell will always show the
* input elements as a default.
* @param {Array} [options.columns.editOptions.listItems] - Specifies the option items for the
* 'select', 'radio', 'checkbox' type. The item of the array must contain properties named
* 'text' and 'value'. (e.g. [{text: 'option1', value: 1}, {...}])
* @param {function} [options.columns.editOptions.onFocus] - The function that will be
* called when a 'focus' event occurred on an input element
* @param {function} [options.columns.editOptions.onBlur] - The function that will be
* called when a 'blur' event occurred on an input element
* @param {function} [options.columns.editOptions.onKeyDown] - The function that will be
* called when a 'keydown' event occurred on an input element
* @param {(string|function)} [options.columns.editOptions.prefix] - The HTML string to be
* shown left to the input element. If it's a function, the return value will be used.
* @param {(string|function)} [options.columns.editOptions.postfix] - The HTML string to be
* shown right to the input element. If it's a function, the return value will be used.
* @param {function} [options.columns.editOptions.converter] - The function whose
* return value (HTML) represents the UI of the cell. If the return value is
* falsy(null|undefined|false), default UI will be shown.
* @param {Object} [options.columns.copyOptions] - Option object for clipboard copying.
* This option is column specific, and overrides the global copyOptions.
* @param {boolean} [options.columns.copyOptions.useFormattedValue] - Whether to use
* formatted values or original values as a string to be copied to the clipboard
* @param {boolean} [options.columns.copyOptions.useListItemText] - Whether to use
* concatenated text or original values as a string to be copied to the clipboard
* @param {function} [options.columns.copyOptions.customValue] - Whether to use
* customized value from "customValue" callback or original values as a string to be copied to the clipboard
* @param {Array} [options.columns.relations] - Specifies relation between this and other column.
* @param {Array} [options.columns.relations.targetNames] - Array of the names of target columns.
* @param {function} [options.columns.relations.disabled] - If returns true, target columns
* will be disabled.
* @param {function} [options.columns.relations.editable] - If returns true, target columns
* will be editable.
* @param {function} [options.columns.relations.listItems] - The function whose return
* value specifies the option list for the 'select', 'radio', 'checkbox' type.
* The options list of target columns will be replaced with the return value of this function.
* @param {string} [options.columns.whiteSpace='nowrap'] - If set to 'normal', the text line is broken
* by fitting to the column's width. If set to 'pre', spaces are preserved and the text is braken by
* new line characters. If set to 'pre-wrap', spaces are preserved, the text line is broken by
* fitting to the column's width and new line characters. If set to 'pre-line', spaces are merged,
* the text line is broken by fitting to the column's width and new line characters.
* @param {Object} [options.columns.component] - Option for using tui-component
* @param {string} [options.columns.component.name] - The name of the compnent to use
* for this column
* @param {Object} [options.columns.component.options] - The options object to be used for
* creating the component
* @param {Object} [options.summary] - The object for configuring summary area.
* @param {number} [options.summary.height] - The height of the summary area.
* @param {string} [options.summary.position='bottom'] - The position of the summary area. ('bottom', 'top')
* @param {(string|Object)} [options.summary.defaultContent]
* The configuring of summary cell for every column.
* This options can be overriden for each column by columnContent options.
* If type is string, the value is used as HTML of summary cell for every columns
* without auto-calculation.
* @param {boolean} [options.summary.defaultContent.useAutoSummary=true]
* If set to true, the summary value of every column is served as a paramater to the template
* function whenever data is changed.
* @param {function} [options.summary.defaultContent.template] - Template function which returns the
* content(HTML) of the column of the summary. This function takes an K-V object as a parameter
* which contains a summary values keyed by 'sum', 'avg', 'min', 'max' and 'cnt'.
* @param {Object} [options.summary.columnContent]
* The configuring of summary cell for each column.
* Sub options below are keyed by each column name.
* If type of value of this object is string, the value is used as HTML of summary cell for
* the column without auto-calculation.
* @param {boolean} [options.summary.columnContent.useAutoSummary=true]
* If set to true, the summary value of each column is served as a paramater to the template
* function whenever data is changed.
* @param {function} [options.summary.columnContent.template] - Template function which returns the
* content(HTML) of the column of the summary. This function takes an K-V object as a parameter
* which contains a summary values keyed by 'sum', 'avg', 'min', 'max' and 'cnt'.
* @param {boolean} [options.usageStatistics=true] Send the hostname to google analytics.
* If you do not want to send the hostname, this option set to false.
*/
var Grid = View.extend(/** @lends Grid.prototype */{
initialize: function(options) {
options = snippet.extend({
usageStatistics: true
}, options);
if (options.footer) {
util.warning('The "footer" option is deprecated since 2.5.0 and replaced by "summary" option.');
options.summary = options.footer;
}
this.id = util.getUniqueKey();
this.domState = new DomState(this.$el);
this.domEventBus = DomEventBus.create();
this.modelManager = this._createModelManager(options);
this.painterManager = this._createPainterManager();
this.componentHolder = this._createComponentHolder(options.pagination);
this.viewFactory = this._createViewFactory(options);
this.container = this.viewFactory.createContainer();
this.publicEventEmitter = this._createPublicEventEmitter();
this.container.render();
this.refreshLayout();
if (!themeManager.isApplied()) {
themeManager.apply(themeNameConst.DEFAULT);
}
this.addOn = {};
instanceMap[this.id] = this;
if (options.data) {
this.setData(options.data);
}
if (options.usageStatistics) {
snippet.sendHostname('grid', 'UA-129951906-1');
}
},
/**
* Creates core model and returns it.
* @param {Object} options - Options set by user
* @returns {module:model/manager} - New model manager object
* @private
*/
_createModelManager: function(options) {
var modelOptions = _.assign({}, options, {
gridId: this.id,
publicObject: this
});
_.omit(modelOptions, 'el');
return new ModelManager(modelOptions, this.domState, this.domEventBus);
},
/**
* Creates painter manager and returns it
* @returns {module:painter/manager}
* @private
*/
_createPainterManager: function() {
var controller = new PainterController({
focusModel: this.modelManager.focusModel,
dataModel: this.modelManager.dataModel,
columnModel: this.modelManager.columnModel,
selectionModel: this.modelManager.selectionModel
});
return new PainterManager({
gridId: this.id,
selectType: this.modelManager.columnModel.get('selectType'),
fixedRowHeight: this.modelManager.dimensionModel.get('fixedRowHeight'),
domEventBus: this.domEventBus,
controller: controller
});
},
/**
* Creates a view factory.
* @param {options} options - options
* @returns {module:view/factory}
* @private
*/
_createViewFactory: function(options) {
var viewOptions = _.pick(options, [
'heightResizable', 'summary'
]);
var dependencies = {
modelManager: this.modelManager,
painterManager: this.painterManager,
componentHolder: this.componentHolder,
domEventBus: this.domEventBus,
domState: this.domState
};
return new ViewFactory(_.assign(dependencies, viewOptions));
},
/**
* Creates a pagination component.
* @param {Object} pgOptions - pagination options
* @returns {module:component/pagination}
* @private
*/
_createComponentHolder: function(pgOptions) {
return new ComponentHolder({
pagination: pgOptions
});
},
/**
* Creates public event emitter and returns it.
* @returns {module:publicEventEmitter} - New public event emitter
* @private
*/
_createPublicEventEmitter: function() {
var emitter = new PublicEventEmitter(this);
emitter.listenToFocusModel(this.modelManager.focusModel);
emitter.listenToDomEventBus(this.domEventBus);
emitter.listenToDataModel(this.modelManager.dataModel);
emitter.listenToSelectionModel(this.modelManager.selectionModel);
return emitter;
},
/**
* Disables all rows.
*/
disable: function() {
this.modelManager.dataModel.setDisabled(true);
},
/**
* Enables all rows.
*/
enable: function() {
this.modelManager.dataModel.setDisabled(false);
},
/**
* Disables the row identified by the rowkey.
* @param {number|string} rowKey - The unique key of the target row
*/
disableRow: function(rowKey) {
this.modelManager.dataModel.disableRow(rowKey);
},
/**
* Enables the row identified by the rowKey.
* @param {number|string} rowKey - The unique key of the target row
*/
enableRow: function(rowKey) {
this.modelManager.dataModel.enableRow(rowKey);
},
/**
* Returns the value of the cell identified by the rowKey and columnName.
* @param {number|string} rowKey - The unique key of the target row.
* @param {string} columnName - The name of the column
* @param {boolean} [isOriginal] - It set to true, the original value will be return.
* @returns {number|string} - The value of the cell
*/
getValue: function(rowKey, columnName, isOriginal) {
return this.modelManager.dataModel.getValue(rowKey, columnName, isOriginal);
},
/**
* Returns a list of all values in the specified column.
* @param {string} columnName - The name of the column
* @param {boolean} [isJsonString=false] - It set to true, return value will be converted to JSON string.
* @returns {(Array|string)} - A List of all values in the specified column. (or JSON string of the list)
*/
getColumnValues: function(columnName, isJsonString) {
return this.modelManager.dataModel.getColumnValues(columnName, isJsonString);
},
/**
* Returns the object that contains all values in the specified row.
* @param {number|string} rowKey - The unique key of the target row
* @param {boolean} [isJsonString=false] - If set to true, return value will be converted to JSON string.
* @returns {Object|string} - The object that contains all values in the row. (or JSON string of the object)
*/
getRow: function(rowKey, isJsonString) {
return this.modelManager.dataModel.getRowData(rowKey, isJsonString);
},
/**
* Returns the object that contains all values in the row at specified index.
* @param {number} index - The index of the row
* @param {boolean} [isJsonString=false] - If set to true, return value will be converted to JSON string.
* @returns {Object|string} - The object that contains all values in the row. (or JSON string of the object)
*/
getRowAt: function(index, isJsonString) {
return this.modelManager.dataModel.getRowDataAt(index, isJsonString);
},
/**
* Returns the total number of the rows.
* @returns {number} - The total number of the rows
*/
getRowCount: function() {
return this.modelManager.dataModel.length;
},
/**
* Returns data of currently focused cell
* @returns {number} rowKey - The unique key of the row
* @returns {string} columnName - The name of the column
* @returns {string} value - The value of the cell
*/
getFocusedCell: function() {
var addr = this.modelManager.focusModel.which();
var value = this.getValue(addr.rowKey, addr.columnName);
return {
rowKey: addr.rowKey,
columnName: addr.columnName,
value: value
};
},
/**
* Returns the jquery object of the cell identified by the rowKey and columnName.
* @param {number|string} rowKey - The unique key of the row
* @param {string} columnName - The name of the column
* @returns {jQuery} - The jquery object of the cell element
*/
getElement: function(rowKey, columnName) {
return this.modelManager.dataModel.getElement(rowKey, columnName);
},
/**
* Sets the value of the cell identified by the specified rowKey and columnName.
* @param {number|string} rowKey - The unique key of the row
* @param {string} columnName - The name of the column
* @param {number|string} columnValue - The value to be set
*/
setValue: function(rowKey, columnName, columnValue) {
this.modelManager.dataModel.setValue(rowKey, columnName, columnValue);
},
/**
* Sets the all values in the specified column.
* @param {string} columnName - The name of the column
* @param {number|string} columnValue - The value to be set
* @param {boolean} [isCheckCellState=true] - If set to true, only editable and not disabled cells will be affected.
*/
setColumnValues: function(columnName, columnValue, isCheckCellState) {
this.modelManager.dataModel.setColumnValues(columnName, columnValue, isCheckCellState);
},
/**
* Replaces all rows with the specified list. This will not change the original data.
* @param {Array} data - A list of new rows
*/
resetData: function(data) {
this.modelManager.dataModel.resetData(data);
},
/**
* Replaces all rows with the specified list. This will change the original data.
* @param {Array} data - A list of new rows
* @param {function} callback - The function that will be called when done.
*/
setData: function(data, callback) {
this.modelManager.dataModel.setData(data, true, callback);
},
/**
* Sets the height of body-area.
* @param {number} value - The number of pixel
*/
setBodyHeight: function(value) {
this.modelManager.dimensionModel.set({
bodyHeight: value,
fixedHeight: value !== 'auto'
});
},
/**
* Sets focus on the cell identified by the specified rowKey and columnName.
* @param {number|string} rowKey - The unique key of the row
* @param {string} columnName - The name of the column
* @param {boolean} [isScrollable=false] - If set to true, the view will scroll to the cell element.
*/
focus: function(rowKey, columnName, isScrollable) {
this.modelManager.focusModel.focusClipboard();
this.modelManager.focusModel.focus(rowKey, columnName, isScrollable);
},
/**
* Sets focus on the cell at the specified index of row and column.
* @param {number|string} rowIndex - The index of the row
* @param {string} columnIndex - The index of the column
* @param {boolean} [isScrollable=false] - If set to true, the view will scroll to the cell element.
*/
focusAt: function(rowIndex, columnIndex, isScrollable) {
this.modelManager.focusModel.focusAt(rowIndex, columnIndex, isScrollable);
},
/**
* Sets focus on the cell at the specified index of row and column and starts to edit.
* @param {number|string} rowKey - The unique key of the row
* @param {string} columnName - The name of the column
* @param {boolean} [isScrollable=false] - If set to true, the view will scroll to the cell element.
*/
focusIn: function(rowKey, columnName, isScrollable) {
this.modelManager.focusModel.focusIn(rowKey, columnName, isScrollable);
},
/**
* Sets focus on the cell at the specified index of row and column and starts to edit.
* @param {number|string} rowIndex - The index of the row
* @param {string} columnIndex - The index of the column
* @param {boolean} [isScrollable=false] - If set to true, the view will scroll to the cell element.
*/
focusInAt: function(rowIndex, columnIndex, isScrollable) {
this.modelManager.focusModel.focusInAt(rowIndex, columnIndex, isScrollable);
},
/**
* Makes view ready to get keyboard input.
*/
activateFocus: function() {
this.modelManager.focusModel.focusClipboard();
},
/**
* Removes focus from the focused cell.
*/
blur: function() {
this.modelManager.focusModel.blur();
},
/**
* Checks all rows.
*/
checkAll: function() {
this.modelManager.dataModel.checkAll();
},
/**
* Checks the row identified by the specified rowKey.
* @param {number|string} rowKey - The unique key of the row
*/
check: function(rowKey) {
this.modelManager.dataModel.check(rowKey);
},
/**
* Unchecks all rows.
*/
uncheckAll: function() {
this.modelManager.dataModel.uncheckAll();
},
/**
* Unchecks the row identified by the specified rowKey.
* @param {number|string} rowKey - The unique key of the row
*/
uncheck: function(rowKey) {
this.modelManager.dataModel.uncheck(rowKey);
},
/**
* Removes all rows.
*/
clear: function() {
this.modelManager.dataModel.setData([]);
},
/**
* Removes the row identified by the specified rowKey.
* @param {number|string} rowKey - The unique key of the row
* @param {boolean|object} [options] - Options. If the type is boolean, this value is equivalent to
* options.removeOriginalData.
* @param {boolean} [options.removeOriginalData] - If set to true, the original data will be removed.
* @param {boolean} [options.keepRowSpanData] - If set to true, the value of the merged cells will not be
* removed although the target is first cell of them.
*/
removeRow: function(rowKey, options) {
if (snippet.isBoolean(options) && options) {
options = {
removeOriginalData: true
};
}
this.modelManager.dataModel.removeRow(rowKey, options);
},
/**
* Removes all checked rows.
* @param {boolean} showConfirm - If set to true, confirm message will be shown before remove.
* @returns {boolean} - True if there's at least one row removed.
*/
removeCheckedRows: function(showConfirm) {
var rowKeys = this.getCheckedRowKeys();
var confirmMessage = i18n.get('net.confirmDelete', {
count: rowKeys.length
});
if (rowKeys.length > 0 && (!showConfirm || confirm(confirmMessage))) {
_.each(rowKeys, function(rowKey) {
this.modelManager.dataModel.removeRow(rowKey);
}, this);
return true;
}
return false;
},
/**
* Enables the row identified by the rowKey to be able to check.
* @param {number|string} rowKey - The unique key of the row
*/
enableCheck: function(rowKey) {
this.modelManager.dataModel.enableCheck(rowKey);
},
/**
* Disables the row identified by the spcified rowKey to not be abled to check.
* @param {number|string} rowKey - The unique keyof the row.
*/
disableCheck: function(rowKey) {
this.modelManager.dataModel.disableCheck(rowKey);
},
/**
* Returns a list of the rowKey of checked rows.
* @param {boolean} [isJsonString=false] - If set to true, return value will be converted to JSON string.
* @returns {Array|string} - A list of the rowKey. (or JSON string of the list)
*/
getCheckedRowKeys: function(isJsonString) {
var checkedRowList = this.modelManager.dataModel.getRows(true);
var checkedRowKeyList = _.pluck(checkedRowList, 'rowKey');
return isJsonString ? JSON.stringify(checkedRowKeyList) : checkedRowKeyList;
},
/**
* Returns a list of the checked rows.
* @param {boolean} [useJson=false] - If set to true, return value will be converted to JSON string.
* @returns {Array|string} - A list of the checked rows. (or JSON string of the list)
*/
getCheckedRows: function(useJson) {
var checkedRowList = this.modelManager.dataModel.getRows(true);
return useJson ? JSON.stringify(checkedRowList) : checkedRowList;
},
/**
* Returns a list of the column model.
* @returns {Array} - A list of the column model.
*/
getColumns: function() {
return this.modelManager.columnModel.get('dataColumns');
},
/**
* Returns the object that contains the lists of changed data compared to the original data.
* The object has properties 'createdRows', 'updatedRows', 'deletedRows'.
* @param {Object} [options] Options
* @param {boolean} [options.checkedOnly=false] - If set to true, only checked rows will be considered.
* @param {boolean} [options.withRawData=false] - If set to true, the data will contains
* the row data for internal use.
* @param {boolean} [options.rowKeyOnly=false] - If set to true, only keys of the changed
* rows will be returned.
* @param {Array} [options.ignoredColumns] - A list of column name to be excluded.
* @returns {{createdRows: Array, updatedRows: Array, deletedRows: Array}} - Object that contains the result list.
*/
getModifiedRows: function(options) {
return this.modelManager.dataModel.getModifiedRows(options);
},
/**
* Inserts the new row with specified data to the end of table.
* @param {Object} [row] - The data for the new row
* @param {Object} [options] - Options
* @param {number} [options.at] - The index at which new row will be inserted
* @param {boolean} [options.extendPrevRowSpan] - If set to true and the previous row at target index
* has a rowspan data, the new row will extend the existing rowspan data.
* @param {boolean} [options.focus] - If set to true, move focus to the new row after appending
* @param {(Number|String)} [options.parentRowKey] - Tree row key of the parent which appends given rows
* @param {number} [options.offset] - Tree offset from first sibling
*/
appendRow: function(row, options) {
this.modelManager.dataModel.appendRow(row, options);
},
/**
* Inserts the new row with specified data to the beginning of table.
* @param {Object} [row] - The data for the new row
* @param {Object} [options] - Options
* @param {boolean} [options.focus] - If set to true, move focus to the new row after appending
*/
prependRow: function(row, options) {
this.modelManager.dataModel.prependRow(row, options);
},
/**
* Returns true if there are at least one row modified.
* @returns {boolean} - True if there are at least one row modified.
*/
isModified: function() {
return this.modelManager.dataModel.isModified();
},
/**
* Returns the instance of specified AddOn.
* @param {string} name - The name of the AddOn
* @returns {instance} addOn - The instance of the AddOn
*/
getAddOn: function(name) {
return name ? this.addOn[name] : this.addOn;
},
/**
* Restores the data to the original data.
* (Original data is set by {@link Grid#setData|setData}
*/
restore: function() {
this.modelManager.dataModel.restore();
},
/**
* Sets options for header.
* @param {Object} options - Options for header
* @param {number} [options.height] - The height value
* @param {Array} [options.complexColumns] - The complex columns info
*/
setHeader: function(options) {
if (options.height) {
this.modelManager.dimensionModel.set('headerHeight', options.height);
}
if (options.complexColumns) {
this.modelManager.columnModel.set({
complexHeaderColumns: options.complexColumns
});
}
},
/**
* Sets the count of frozen columns.
* @param {number} count - The count of columns to be frozen
*/
setFrozenColumnCount: function(count) {
this.modelManager.columnModel.set('frozenCount', count);
},
/**
* Sets the list of column model.
* @param {Array} columns - A new list of column model
* @example
* {
* columnName1: 'title1',
* columnName2: 'title2',
* columnName3: 'title3'
* }
*/
setColumns: function(columns) {
this.modelManager.columnModel.set('columns', columns);
},
/**
* Set columns title
* @param {string} columnsMap - columns map to be change
*/
setColumnTitles: function(columnsMap) {
this.modelManager.columnModel.setColumnTitles(columnsMap);
},
/**
* Creates an specified AddOn and use it on this instance.
* @param {string} name - The name of the AddOn to use.
* @param {Object} options - The option objects for configuring the AddON.
* @returns {Grid} - This instance.
*/
use: function(name, options) {
if (name === 'Net') {
options = _.assign({
domEventBus: this.domEventBus,
renderModel: this.modelManager.renderModel,
dataModel: this.modelManager.dataModel,
pagination: this.componentHolder.getInstance('pagination')
}, options);
this.addOn.Net = new NetAddOn(options);
this.publicEventEmitter.listenToNetAddon(this.addOn.Net);
}
return this;
},
/**
* Returns a list of all rows.
* @returns {Array} - A list of all rows
*/
getRows: function() {
return this.modelManager.dataModel.getRows();
},
/**
* Sorts all rows by the specified column.
* @param {string} columnName - The name of the column to be used to compare the rows
* @param {boolean} [ascending] - Whether the sort order is ascending.
* If not specified, use the negative value of the current order.
*/
sort: function(columnName, ascending) {
this.modelManager.dataModel.sortByField(columnName, ascending);
},
/**
* Unsorts all rows. (Sorts by rowKey).
*/
unSort: function() {
this.sort('rowKey');
},
/**
* Gets state of the sorted column in rows
* @returns {{columnName: string, ascending: boolean, useClient: boolean}} Sorted column's state
*/
getSortState: function() {
return this.modelManager.dataModel.sortOptions;
},
/**
* Adds the specified css class to cell element identified by the rowKey and className
* @param {number|string} rowKey - The unique key of the row
* @param {string} columnName - The name of the column
* @param {string} className - The css class name to add
*/
addCellClassName: function(rowKey, columnName, className) {
this.modelManager.dataModel.get(rowKey).addCellClassName(columnName, className);
},
/**
* Adds the specified css class to all cell elements in the row identified by the rowKey
* @param {number|string} rowKey - The unique key of the row
* @param {string} className - The css class name to add
*/
addRowClassName: function(rowKey, className) {
this.modelManager.dataModel.get(rowKey).addClassName(className);
},
/**
* Removes the specified css class from the cell element indentified by the rowKey and columnName.
* @param {number|string} rowKey - The unique key of the row
* @param {string} columnName - The name of the column
* @param {string} className - The css class name to be removed
*/
removeCellClassName: function(rowKey, columnName, className) {
this.modelManager.dataModel.get(rowKey).removeCellClassName(columnName, className);
},
/**
* Removes the specified css class from all cell elements in the row identified by the rowKey.
* @param {number|string} rowKey - The unique key of the row
* @param {string} className - The css class name to be removed
*/
removeRowClassName: function(rowKey, className) {
this.modelManager.dataModel.get(rowKey).removeClassName(className);
},
/**
* Returns the rowspan data of the cell identified by the rowKey and columnName.
* @param {number|string} rowKey - The unique key of the row
* @param {string} columnName - The name of the column
* @returns {Object} - Row span data
*/
getRowSpanData: function(rowKey, columnName) {
return this.modelManager.dataModel.getRowSpanData(rowKey, columnName);
},
/**
* Returns the index of the row indentified by the rowKey.
* @param {number|string} rowKey - The unique key of the row
* @returns {number} - The index of the row
*/
getIndexOfRow: function(rowKey) {
return this.modelManager.dataModel.indexOfRowKey(rowKey);
},
/**
* Returns the index of the column indentified by the column name.
* @param {string} columnName - The unique key of the column
* @returns {number} - The index of the column
*/
getIndexOfColumn: function(columnName) {
return this.modelManager.columnModel.indexOfColumnName(columnName);
},
/**
* Returns an instance of tui.Pagination.
* @returns {tui.Pagination}
*/
getPagination: function() {
return this.componentHolder.getInstance('pagination');
},
/**
* Sets the width of the dimension.
* @param {number} width - The width of the dimension
*/
setWidth: function(width) {
this.modelManager.dimensionModel.setWidth(width);
},
/**
* Sets the height of the dimension.
* @param {number} height - The height of the dimension
*/
setHeight: function(height) {
this.modelManager.dimensionModel.setHeight(height);
},
/**
* Refreshs the layout view. Use this method when the view was rendered while hidden.
*/
refreshLayout: function() {
this.modelManager.dimensionModel.refreshLayout();
},
/**
* Resets the width of each column by using initial setting of column models.
*/
resetColumnWidths: function() {
this.modelManager.coordColumnModel.resetColumnWidths();
},
/**
* Shows columns
* @param {...string} arguments - Column names to show
*/
showColumn: function() {
var args = snippet.toArray(arguments);
this.modelManager.columnModel.setHidden(args, false);
},
/**
* Hides columns
* @param {...string} arguments - Column names to hide
*/
hideColumn: function() {
var args = snippet.toArray(arguments);
this.modelManager.columnModel.setHidden(args, true);
},
/**
* Sets the HTML string of given column summary.
* The type of content is the same as the options.summary.columnContent of the constructor.
* @param {string} columnName - column name
* @param {string|object} content - HTML string or options object.
*/
setSummaryColumnContent: function(columnName, content) {
this.modelManager.summaryModel.setColumnContent(columnName, content, true);
},
/**
* Returns the values of given column summary.
* If the column name is not specified, all values of available columns are returned.
* The shape of returning object looks like the example below.
* @param {string} [columnName] - column name
* @returns {Object}
* @example
* {
* column1: {
* sum: 1000,
* avg: 200,
* max: 300,
* min: 50,
* cnt: 5
* },
* column2: {
* sum: 2000,
* avg: 300,
* max: 600,
* min: 80,
* cnt: 5
* }
* }
*/
getSummaryValues: function(columnName) {
if (this.modelManager.summaryModel) {
return this.modelManager.summaryModel.getValues(columnName);
}
return null;
},
/**
* Sets the HTML string of given column summary.
* @deprecated since version 2.5.0 and is replaced by "setSummaryColumnContent" API
* @param {string} columnName - column name
* @param {string} contents - HTML string
*/
setFooterColumnContent: function(columnName, contents) {
this.modelManager.columnModel.setSummaryContent(columnName, contents);
},
/**
* Validates all data and returns the result.
* Return value is an array which contains only rows which have invalid cell data.
* @returns {Array.<Object>} An array of error object
* @example
* // return value example
* [
* {
* rowKey: 1,
* errors: [
* {
* columnName: 'c1',
* errorCode: 'REQUIRED'
* },
* {
* columnName: 'c2',
* errorCode: 'REQUIRED'
* }
* ]
* },
* {
* rowKey: 3,
* errors: [
* {
* columnName: 'c2',
* errorCode: 'REQUIRED'
* }
* ]
* }
* ]
*/
validate: function() {
return this.modelManager.dataModel.validate();
},
/**
* Finds rows by conditions
* @param {Object|Function} conditions - object (key: column name, value: column value) or
* function that check the value and returns true/false result to find rows
* @returns {Array} Row list
* @example <caption>Conditions type is object.</caption>
* grid.findRows({
* artist: 'Birdy',
* price: 10000
* });
* @example <caption>Conditions type is function.</caption>
* grid.findRows(function(row) {
* return (/b/ig.test(row.artist) && row.price > 10000);
* });
*/
findRows: function(conditions) {
return this.modelManager.dataModel.findRows(conditions);
},
/**
* Copy to clipboard
*/
copyToClipboard: function() {
this.modelManager.clipboardModel.setClipboardText();
if (!window.clipboardData) { // Accessing the clipboard is a security concern on chrome
document.execCommand('copy');
}
},
/**
* Selects cells or rows by range
* @param {Object} range - Selection range
* @param {Array} [range.start] - Index info of start selection (ex: [rowIndex, columnIndex])
* @param {Array} [range.end] - Index info of end selection (ex: [rowIndex, columnIndex])
*/
selection: function(range) {
var selectionModel = this.modelManager.selectionModel;
var start = range.start;
var end = range.end;
var unit = selectionModel.getSelectionUnit();
selectionModel.start(start[0], start[1], unit);
selectionModel.update(end[0], end[1], unit);
},
/**
* Expands tree row
* @param {number|string} rowKey - row key
* @param {boolean} recursive - true for recursively expand all descendant
* @returns {Array.<number|string>} - children or descendant of given row
*/
expand: function(rowKey, recursive) {
return this.modelManager.dataModel.treeExpand(rowKey, recursive);
},
/**
* Expands all tree row
*/
expandAll: function() {
this.modelManager.dataModel.treeExpandAll();
},
/**
* Expands tree row
* @param {number|string} rowKey - row key
* @param {boolean} recursive - true for recursively expand all descendant
* @returns {Array.<number|string>} - children or descendant of given row
*/
collapse: function(rowKey, recursive) {
return this.modelManager.dataModel.treeCollapse(rowKey, recursive);
},
/**
* Collapses all tree row
*/
collapseAll: function() {
this.modelManager.dataModel.treeCollapseAll();
},
/**
* Gets the ancestors of the row which has the given row key
* @param {number|string} rowKey - row key
* @returns {Array.<TreeRow>} - the ancestor rows
*/
getAncestors: function(rowKey) {
return this.modelManager.dataModel.getTreeAncestors(rowKey);
},
/**
* Gets the descendants of the row which has the given row key
* @param {number|string} rowKey - row key
* @returns {Array.<TreeRow>} - the descendant rows
*/
getDescendants: function(rowKey) {
return this.modelManager.dataModel.getTreeDescendants(rowKey);
},
/**
* Gets the parent of the row which has the given row key
* @param {number|string} rowKey - row key
* @returns {TreeRow} - the parent row
*/
getParent: function(rowKey) {
return this.modelManager.dataModel.getTreeParent(rowKey);
},
/**
* Gets the children of the row which has the given row key
* @param {number|string} rowKey - row key
* @returns {Array.<TreeRow>} - the children rows
*/
getChildren: function(rowKey) {
return this.modelManager.dataModel.getTreeChildren(rowKey);
},
/**
* Gets the depth of the row which has the given row key
* @param {number|string} rowKey - row key to test
* @returns {number} - the depth
*/
getDepth: function(rowKey) {
return this.modelManager.dataModel.getTreeDepth(rowKey);
},
/**
* Destroys the instance.
*/
destroy: function() {
this.modelManager.destroy();
this.container.destroy();
this.modelManager = this.container = null;
}
});
/**
* Returns an instance of the grid associated to the id.
* @static
* @param {number} id - ID of the target grid
* @returns {Grid} - Grid instance
* var Grid = tui.Grid; // or re