UNPKG

angular4-material-table

Version:

Angular 4 table based on @angular/cdk table structure, to allow row insertion, edition, validation and deletion.

279 lines 11.8 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import { DataSource } from '@angular/cdk/collections'; import { BehaviorSubject, Subject } from 'rxjs'; import { TableElementFactory } from './table-element.factory'; import { DefaultValidatorService } from './default-validator.service'; var TableDataSource = /** @class */ (function (_super) { __extends(TableDataSource, _super); /** * Creates a new TableDataSource instance, that can be used as datasource of `@angular/cdk` data-table. * @param data Array containing the initial values for the TableDataSource. If not specified, then `dataType` must be specified. * @param dataType Type of data contained by the Table. If not specified, then `data` with at least one element must be specified. * @param validatorService Service that create instances of the FormGroup used to validate row fields. * @param config Additional configuration for table. */ function TableDataSource(data, dataType, validatorService, config) { if (config === void 0) { config = { prependNewElements: false, suppressErrors: false }; } var _this = _super.call(this) || this; _this.validatorService = validatorService; _this.config = config; if (!validatorService) _this.validatorService = new DefaultValidatorService(); if (dataType) { _this.dataConstructor = dataType; } else { if (data && data.length > 0) _this.dataKeys = Object.keys(data[0]); else throw new Error('You must define either a non empty array, or an associated class to build the table.'); } _this.checkValidatorFields(_this.validatorService); _this.rowsSubject = new BehaviorSubject(_this.getRowsFromData(data)); _this.datasourceSubject = new Subject(); return _this; } TableDataSource.prototype.checkValidatorFields = function (validatorService) { var _this = this; var formGroup = validatorService.getRowValidator(); if (formGroup != null) { var rowKeys_1 = Object.keys(this.createNewObject()); Object.keys(formGroup.controls).forEach(function (key) { if (rowKeys_1.some(function (x) { return x === key; })) { _this.logError('Validator form control keys must match row object keys.'); } }); } }; TableDataSource.prototype.logError = function (message) { if (!this.config.suppressErrors) console.error(message); }; /** * Start the creation of a new element, pushing an empty-data row in the table. */ TableDataSource.prototype.createNew = function () { var source = this.rowsSubject.getValue(); if (!this.existsNewElement(source)) { var newElement = TableElementFactory.createTableElement({ id: -1, editing: true, currentData: this.createNewObject(), source: this, validator: this.validatorService.getRowValidator(), }); if (this.config.prependNewElements) { this.rowsSubject.next([newElement].concat(source)); } else { source.push(newElement); this.rowsSubject.next(source); } } }; /** * Confirm creation of the row. Save changes and disable editing. * If validation active and row data is invalid, it doesn't confirm creation neither disable editing. * @param row Row to be confirmed. */ TableDataSource.prototype.confirmCreate = function (row) { if (!row.isValid()) { return false; } var source = this.rowsSubject.getValue(); row.id = source.length - 1; this.rowsSubject.next(source); row.editing = false; this.updateDatasourceFromRows(source); return true; }; /** * Confirm edition of the row. Save changes and disable editing. * If validation active and row data is invalid, it doesn't confirm editing neither disable editing. * @param row Row to be edited. */ TableDataSource.prototype.confirmEdit = function (row) { if (!row.isValid()) { return false; } var source = this.rowsSubject.getValue(); var index = this.getIndexFromRowId(row.id, source); source[index] = row; this.rowsSubject.next(source); row.originalData = undefined; row.editing = false; this.updateDatasourceFromRows(source); return true; }; /** * Delete the row with the index specified. */ TableDataSource.prototype.delete = function (id) { var source = this.rowsSubject.getValue(); var index = this.getIndexFromRowId(id, source); source.splice(index, 1); this.updateRowIds(index, source); this.rowsSubject.next(source); if (id != -1) this.updateDatasourceFromRows(source); }; /** * Get row from the table. * @param id Id of the row to retrieve, -1 returns the current new line. */ TableDataSource.prototype.getRow = function (id) { var source = this.rowsSubject.getValue(); var index = this.getIndexFromRowId(id, source); return (index >= 0 && index < source.length) ? source[index] : null; }; /** * Update the datasource with a new array of data. If the array reference * is the same as the previous one, it doesn't trigger an update. * @param data Data to update the table datasource. * @param options Specify options to update the datasource. * If emitEvent is true and the datasource is updated, it emits an event * from 'datasourceSubject' with the updated data. If false, it doesn't * emit an event. True by default. */ TableDataSource.prototype.updateDatasource = function (data, options) { if (options === void 0) { options = { emitEvent: true }; } if (this.currentData !== data) { this.currentData = data; this.rowsSubject.next(this.getRowsFromData(data)); if (options.emitEvent) this.datasourceSubject.next(data); } }; /** * Checks the existance of the a new row (not yet saved). * @param source */ TableDataSource.prototype.existsNewElement = function (source) { return !(source.length == 0 || source[this.getNewRowIndex(source)].id > -1); }; /** * Returns the possible index of the new row depending on the insertion type. * It doesn't imply that the new row is created, that must be checked. * @param source */ TableDataSource.prototype.getNewRowIndex = function (source) { if (this.config.prependNewElements) return 0; else return source.length - 1; }; /** * Returns the row id from the index specified. It does * not consider if the new row is present or not, assumes * that new row is not present. * @param index Index of the array. * @param count Quantity of elements in the array. */ TableDataSource.prototype.getRowIdFromIndex = function (index, count) { if (this.config.prependNewElements) return count - 1 - index; else return index; }; /** * Returns the index from the row id specified. * It takes into account if the new row exists or not. * @param id * @param source */ TableDataSource.prototype.getIndexFromRowId = function (id, source) { if (id == -1) { return this.existsNewElement(source) ? this.getNewRowIndex(source) : -1; } else { if (this.config.prependNewElements) return source.length - 1 - id; else return id; } }; /** * Update rows ids in the array specified, starting in the specified index * until the start/end of the array, depending on config.prependNewElements * configuration. * @param initialIndex Initial index of source to be updated. * @param source Array that contains the rows to be updated. */ TableDataSource.prototype.updateRowIds = function (initialIndex, source) { var delta = this.config.prependNewElements ? -1 : 1; for (var index = initialIndex; index < source.length && index >= 0; index += delta) { if (source[index].id != -1) source[index].id = this.getRowIdFromIndex(index, source.length); } }; /** * Get the data from the rows. * @param rows Rows to extract the data. */ TableDataSource.prototype.getDataFromRows = function (rows) { return rows .filter(function (row) { return row.id != -1; }) .map(function (row) { return row.originalData ? row.originalData : row.currentData; }); }; /** * Update the datasource with the data contained in the specified rows. * @param rows Rows that contains the datasource's new data. */ TableDataSource.prototype.updateDatasourceFromRows = function (rows) { this.currentData = this.getDataFromRows(rows); this.datasourceSubject.next(this.currentData); }; /** * From an array of data, it returns rows containing the original data. * @param arrayData Data from which create the rows. */ TableDataSource.prototype.getRowsFromData = function (arrayData) { var _this = this; return arrayData.map(function (data, index) { return TableElementFactory.createTableElement({ id: _this.getRowIdFromIndex(index, arrayData.length), editing: false, currentData: data, source: _this, validator: _this.validatorService.getRowValidator(), }); }); }; /** * Create a new object with identical structure than the table source data. * It uses the object's type contructor if available, otherwise it creates * an object with the same keys of the first element contained in the original * datasource (used in the constructor). */ TableDataSource.prototype.createNewObject = function () { if (this.dataConstructor) { return new this.dataConstructor(); } else { return this.dataKeys.reduce(function (obj, key) { obj[key] = undefined; return obj; }, {}); } }; /** Connect function called by the table to retrieve one stream containing * the data to render. */ TableDataSource.prototype.connect = function () { return this.rowsSubject.asObservable(); }; TableDataSource.prototype.disconnect = function () { }; return TableDataSource; }(DataSource)); export { TableDataSource }; //# sourceMappingURL=table-data-source.js.map