📄 cellselection.js
字号:
/*
* Isomorphic SmartClient
* Version 6.5 (2008-04-30)
* Copyright(c) 1998-2007 Isomorphic Software, Inc. All rights reserved.
* "SmartClient" is a trademark of Isomorphic Software, Inc.
*
* licensing@smartclient.com
*
* http://smartclient.com/license
*/
//> @class CellSelection//// Maintains a representation of selection over a 2-dimensional grid of objects.<br>// Automtatically created to manage cell-selection on +link{class:CubeGrid} widgets.//// @visibility Analytics// @treeLocation Client Reference/System/Selection//<// When you create a CellSelection object, set:// <ul>// <li>cellSelection.data - to an array of records referenced by this selection// <li>cellSelection.numCols - to the number of columns/fields covered by this selection// <li>cellSelection.selectionProperty - to an alternative name for the selection property,// if you need to access this property manually// </ul>// Implementation:// A uniquely-named selection property is added to each row/record of the data.// This property holds an array of numbers, one for each "chunk" of 32 columns,// whose bits (0-31) represent the selection state of the cell in the corresponding// column/field.// TODO:// * special case selectSingleCell/deselectSingleCell when we know only one cell can be selected// * convert 'select all' to not actually select all, but rather to set a bit?// * maybe also special case row/col selection for performance?// * hardcode COL_SELECTION_FLAGS table//// create the CellSelection class//isc.ClassFactory.defineClass("CellSelection");isc.CellSelection.addClassProperties({ _selectionID : 0, //> @classAttr isc.CellSelection._selectionID (number : 0 : IRWA) // number to generate a unique ID and selectionProperty for each selection // @group selection // @visibility internal //< COL_SELECTION_FLAGS : null // generate when the first cellSelection is instantiated});isc.CellSelection.addClassMethods({generateFlagTable : function () { isc.CellSelection.COL_SELECTION_FLAGS = []; for (var i = 0; i < 32; i++) isc.CellSelection.COL_SELECTION_FLAGS[i] = Math.pow(2,i);}});isc.CellSelection.addProperties( { data:null, numCols:0, selectionProperty:null, _dirty:true, _selectedCells:[], lastSelectedCell:[], changedCells:[] });isc.CellSelection.addMethods({//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~ Setup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//> @attr cellSelection.data (Array | List: null : IRW)// Array (or +link{class:List}) of records to be referenced by this cell selection// @visibility serverSelection// @group selection//<//> @attr cellSelection.numCols (number : null : IRW)// the number of columns/fields covered by this selection// @visibility internal// @group selection//<//> @attr cellSelection.selectionProperty (string : null : IRWA)// A name for the selection property. This property will be set on the records in this// selection's data, and used to determine whether records are selected or not.// Automatically generated if not specified.// @visibility serverSelection// @group selection//<//> @method cellSelection.init() (A)// Initialize this selection instance.<br>// Note: if the <code>data</code> property is not set at init time, it should be passed to// the selection using the <code>selection.setData</code> method//// @group selection//// @param [all arguments] (object) objects with properties to override from default// @visibility serverSelection//<init : function () { if (!isc.CellSelection.COL_SELECTION_FLAGS) isc.CellSelection.generateFlagTable(); // get unique ID and selection properties if (!this.selectionProperty) this.selectionProperty = "_cellSelection_"+isc.CellSelection._selectionID++; // set the data object so we get notification for add and delete, etc. // NOTE: if the data object wasn't set, use a new arrays this.setData((this.data ? this.data : []));},//> @method cellSelection.setData() (A)// Initialize selection data.<br><br>// Call this method to associate the selection with a different data object.<br>// <i>Note: No need to call this if the contents of the selection's data is modified</i>// @group selection// @param newData (array) new data to maintain selection in// @visibility serverSelection//<setData : function (newData) { // if we are currently pointing to data, stop observing it if (this.data != null) this.ignoreData(this.data); // remember the new data this.data = newData; // observe the new data so we will update automatically when it changes if (this.data != null) this.observeData(this.data);}, //> @method cellSelection.observeData() (A)// Observe methods on the data so we change our state.// Called automatically by cellSelection.setData().// @group selection//// @param data (array) new data to be observed// @visibility internal//<observeData : function (data) { this.observe(data, "dataChanged", "observer._dirty = true");},//> @method cellSelection.ignoreData() (A)// Stop observing methods on data when it goes out of scope.// Called automatically by setData// @group selection//// @param data (array) old data to be ignored// @visibility internal//<ignoreData : function (data) { this.ignore(data, "dataChanged");},//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~ Selection Tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//> @method cellSelection.cellIsSelected()// Return true if a particular item is selected// @group selection//// @param rowNum (number) row index of the cell to check// @param colNum (number) column index of the cell to check// @return (boolean) true == object is selected// false == object is not selected// @group selection// @visibility Analytics//<cellIsSelected : function (rowNum, colNum) { var row = this.data[rowNum], rowSelection = (row ? row[this.selectionProperty] : null), rowChunkSelection = (rowSelection ? rowSelection[Math.floor(colNum/32)] : null), colSelectionFlag = isc.CellSelection.COL_SELECTION_FLAGS[colNum%32]; return (rowChunkSelection != null && ((rowChunkSelection & colSelectionFlag) != 0));},rowHasSelection : function (rowNum) { var row = this.data[rowNum], rowSelection = (row ? row[this.selectionProperty] : null), numRowChunks = Math.ceil(this.numCols/32); // if row doesn't exist or row selection property is null/zero, return false if (!row || !row[this.selectionProperty]) return false; // otherwise check each chunk of the row for a selection (true == nonzero value) for (var i = 0; i < numRowChunks; i++) { if (rowSelection[i]) return true; } // made it through all row chunks with no selection, so return false return false;},colHasSelection : function (colNum) { if (colNum > this.numCols - 1) return false; var colSelectionFlag = isc.CellSelection.COL_SELECTION_FLAGS[colNum%32], rowChunkNum = Math.floor(colNum/32); // iterate through all rows of data var rows = this.data, numRows = rows.length; for (var i = 0; i < numRows; i++) { // get selection property for the current row var rowSelection = rows[i][this.selectionProperty]; // if selection property exists, selection chunk is nonzero, and the flag for this column is set, return true if (rowSelection && rowSelection[rowChunkNum] && ((rowSelection[rowChunkNum] & colSelectionFlag) != 0)) return true; } // made it through all rows with no selection, so return false return false;},//> @method cellSelection.anySelected()// Is anything in the list selected?// @group selection//// @return (boolean) true == at least one item is selected// false == nothing at all is selected// @visibility Analytics// @group selection//<anySelected : function () { var numRowChunks = Math.ceil(this.numCols/32); // iterate through all rows of data var rows = this.data, numRows = rows.length; for (var i = 0; i < numRows; i++) { // get selection property for the current row var rowSelection = rows[i][this.selectionProperty]; if (!rowSelection) continue; // check each chunk of the row for a selection (true == nonzero value) for (var j = 0; j < numRowChunks; j++) { if (rowSelection[j]) return true; } } // made it through all rows with no selection, so return false return false;},//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~ Selection Getters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//> @method cellSelection.getSelectedCells()// Returns an array of the currently selected cells. Each cell is returned as a 2 element// array in the form <code>[rowNum, colNum]</code>.// @group selection// @return (array) an array of the selected cells, as 2 element arrays // @visibility Analytics// @group selection//<getSelectedCells : function () { // first see if we already have a clean list of selected cells if (!this._dirty) return this._selectedCells; var selectedCells = [], colSelectionFlags = isc.CellSelection.COL_SELECTION_FLAGS, numRowChunks = Math.ceil(this.numCols/32), rows = this.data, numRows = rows.length, rowSelection; // iterate through all rows of data for (var i = 0; i < numRows; i++) { // get selection property for the current row rowSelection = rows[i][this.selectionProperty]; if (!rowSelection) continue; // iterate through all chunks in this row for (var j = 0, rowChunkSelection, numColsInChunk; j < numRowChunks; j++) { // get selection flags for this chunk rowChunkSelection = rowSelection[j]; if (!rowChunkSelection) continue; // how many columns in this chunk (32 for all but the last chunk) // NOTE: should use this.numCols%32 for non-chunked CellSelection too numColsInChunk = (j == numRowChunks - 1 && this.numCols%32 != 0) ? this.numCols%32 : 32; // iterate through the flags to find the selected cells in this chunk for (var k = 0; k < numColsInChunk; k++) { if ((rowChunkSelection & colSelectionFlags[k]) != 0) { selectedCells[selectedCells.length] = [i,j*32+k]; } } } } // cache and return the list of selected cells this._selectedCells = selectedCells; this._dirty = false; return selectedCells;},// returns an array containing the numbers of all rows that have at least one cell selectedgetSelectionRowNums : function () { var selectionRowNums = [], numRowChunks = Math.ceil(this.numCols/32), rows = this.data, numRows = rows.length, rowSelection; // iterate through all rows of data for (var i = 0; i < numRows; i++) { // get selection property for the current row rowSelection = rows[i][this.selectionProperty]; if (!rowSelection) continue; // iterate through chunks in this row for (var j = 0, numColsInChunk; j < numRowChunks; j++) { // if any selection flags are set, add the current row's number to the list we'll return if (rowSelection[j]) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -