diff options
Diffstat (limited to 'app/common/components/table/table.js')
-rw-r--r-- | app/common/components/table/table.js | 170 |
1 files changed, 140 insertions, 30 deletions
diff --git a/app/common/components/table/table.js b/app/common/components/table/table.js index 5db05b6..2063555 100644 --- a/app/common/components/table/table.js +++ b/app/common/components/table/table.js @@ -18,9 +18,12 @@ window.angular && (function(angular) { * Each row object can optionally have an 'expandContent' property * that should be a string value and can contain valid HTML. To render * the expanded content, set 'expandable' attribute to true. + * Each row object can optionally have a 'selectable' property. Defaults + * to true if table is selectable. If a particular row should not + * be selectable, set to false. * * data = [ - * { uiData: ['root', 'Admin', 'enabled' ] }, + * { uiData: ['root', 'Admin', 'enabled' ], selectable: false }, * { uiData: ['user1', 'User', 'disabled' ] } * ] * @@ -47,6 +50,10 @@ window.angular && (function(angular) { * The 'expandable' attribute should be a boolean value. If true each * row object in data array should contain a 'expandContent' property * + * The 'selectable' attribute should be a boolean value. + * If 'selectable' is true, include 'batch-actions' property that should + * be an array of actions to provide <table-toolbar> component. + * * The 'size' attribute which can be set to 'small' which will * render a smaller font size in the table. * @@ -56,6 +63,11 @@ window.angular && (function(angular) { this.sortAscending = true; this.activeSort; this.expandedRows = new Set(); + this.selectedRows = new Set(); + this.selectHeaderCheckbox = false; + this.someSelected = false; + + let selectableRowCount = 0; /** * Sorts table data @@ -89,34 +101,99 @@ window.angular && (function(angular) { return column; }) } - if (this.rowActionsEnabled) { - // If table actions are enabled push an empty - // string to the header array to account for additional - // table actions cell - this.header.push({label: '', sortable: false}); - } - if (this.expandable) { - // If table is expandable, push an empty string to the - // header array to account for additional expansion cell - this.header.unshift({label: '', sortable: false}); + }; + + /** + * Prep data + * When data binding changes, make adjustments to account for + * optional configurations and undefined values + */ + const prepData = () => { + selectableRowCount = 0; + this.data.forEach((row) => { + if (row.uiData === undefined) { + // Check for undefined 'uiData' property for each item in data + // array + row.uiData = []; + } + if (this.selectable) { + // If table is selectable check row for 'selectable' property + row.selectable = row.selectable === undefined ? true : row.selectable; + if (row.selectable) { + selectableRowCount++; + row.selected = false; + } + } + }); + if (this.sortable) { + if (this.activeSort !== undefined || this.defaultSort !== undefined) { + // apply default or active sort if one is defined + this.activeSort = this.defaultSort !== undefined ? this.defaultSort : + this.activeSort; + sortData(); + } } }; /** + * Select all rows + * Sets each selectable row selected property to true + * and adds index to selectedRow Set + */ + const selectAllRows = () => { + this.selectHeaderCheckbox = true; + this.someSelected = false; + this.data.forEach((row, index) => { + if (!row.selected && row.selectable) { + row.selected = true; + this.selectedRows.add(index); + } + }) + }; + + /** + * Deselect all rows + * Sets each row selected property to false + * and clears selectedRow Set + */ + const deselectAllRows = () => { + this.selectHeaderCheckbox = false; + this.someSelected = false; + this.selectedRows.clear(); + this.data.forEach((row) => { + if (row.selectable) { + row.selected = false; + } + }) + }; + + /** * Callback when table row action clicked * Emits user desired action and associated row data to * parent controller * @param {string} action : action type * @param {any} row : user object */ - this.onEmitTableAction = (action, row) => { + this.onEmitRowAction = (action, row) => { if (action !== undefined && row !== undefined) { const value = {action, row}; - this.emitAction({value}); + this.emitRowAction({value}); } }; /** + * Callback when batch action clicked from toolbar + * Emits the action type and the selected row data to + * parent controller + * @param {string} action : action type + */ + this.onEmitBatchAction = (action) => { + const filteredRows = this.data.filter((row) => row.selected); + const value = {action, filteredRows}; + this.emitBatchAction({value}); + }; + + /** * Callback when sortable table header clicked * @param {number} index : index of header item */ @@ -146,6 +223,49 @@ window.angular && (function(angular) { }; /** + * Callback when select checkbox clicked + * @param {number} row : index of selected row + */ + this.onRowSelectChange = (row) => { + if (this.selectedRows.has(row)) { + this.selectedRows.delete(row); + } else { + this.selectedRows.add(row); + } + if (this.selectedRows.size === 0) { + this.someSelected = false; + this.selectHeaderCheckbox = false; + deselectAllRows(); + } else if (this.selectedRows.size === selectableRowCount) { + this.someSelected = false; + this.selectHeaderCheckbox = true; + selectAllRows(); + } else { + this.someSelected = true; + } + }; + + /** + * Callback when header select box value changes + */ + this.onHeaderSelectChange = (checked) => { + this.selectHeaderCheckbox = checked; + if (this.selectHeaderCheckbox) { + selectAllRows(); + } else { + deselectAllRows(); + } + }; + + /** + * Callback when cancel/close button closed + * from toolbar + */ + this.onToolbarClose = () => { + deselectAllRows(); + }; + + /** * onInit Component lifecycle hook * Checking for undefined values */ @@ -157,32 +277,19 @@ window.angular && (function(angular) { this.rowActionsEnabled === undefined ? false : this.rowActionsEnabled; this.size = this.size === undefined ? '' : this.size; this.expandable = this.expandable === undefined ? false : this.expandable; - - // Check for undefined 'uiData' property for each item in data array - this.data = this.data.map((row) => { - if (row.uiData === undefined) { - row.uiData = []; - } - return row; - }) + this.selectable = this.selectable === undefined ? false : this.selectable; prepTable(); }; /** * onChanges Component lifecycle hook - * Check for changes in the data array and apply - * default or active sort if one is defined */ this.$onChanges = (onChangesObj) => { const dataChange = onChangesObj.data; if (dataChange) { - if (this.activeSort !== undefined || this.defaultSort !== undefined) { - this.activeSort = this.defaultSort !== undefined ? this.defaultSort : - this.activeSort; - sortData(); - } + prepData(); } - } + }; }; /** @@ -199,7 +306,10 @@ window.angular && (function(angular) { sortable: '<', // boolean defaultSort: '<', // number (index of sort) expandable: '<', // boolean - emitAction: '&' + selectable: '<', // boolean + batchActions: '<', // Array + emitRowAction: '&', + emitBatchAction: '&' } }) })(window.angular); |