angular-json-table
Version:
Angular JSON Table is an Angular 2+ module to populate tables from the JSON data provided
194 lines (193 loc) • 17.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, EventEmitter, Input, Output } from '@angular/core';
export class DataTableComponent {
constructor() {
this.deleteRow = new EventEmitter();
this.updateRow = new EventEmitter();
this.data = {};
this.displayed = [];
this.perpage = 10;
this.page = 1;
this.checked = [];
this.checkAll = false;
this.dialogue = false;
this.dialogeData = {};
}
/**
* @return {?}
*/
ngOnInit() {
this.processData();
}
/**
* @param {?} e
* @param {?} id
* @return {?}
*/
selected(e, id) {
if (e.target.checked) {
this.checked.push(id);
}
}
/**
* @return {?}
*/
deleteSelected() {
if (this.checked.length > 0) {
this.deleteRow.emit(this.checked);
this.dataSource = this.dataSource.filter((value, index, array) => {
return !this.checked.includes(value.id);
});
this.checked = [];
this.paginate(this.page);
}
}
/**
* @return {?}
*/
totalItems() {
if (this.total > this.perpage) {
return Math.ceil(this.total / this.perpage);
}
else {
return 1;
}
}
/**
* @param {?} page
* @return {?}
*/
paginate(page) {
/** @type {?} */
const start = (this.perpage * page) - this.perpage;
/** @type {?} */
const end = (this.perpage * page);
// console.log(start, end);
this.data['data'] = this.dataSource.slice(start, end);
// console.log(this.data);
}
/**
* @param {?} perPage
* @return {?}
*/
pageOnChange(perPage) {
this.perpage = perPage;
this.page = 1;
//console.log(perPage);
this.paginate(this.page);
}
/**
* @return {?}
*/
previousPage() {
if (this.page > 1) {
this.page--;
}
this.paginate(this.page);
}
/**
* @return {?}
*/
nextPage() {
if (this.page + 1 <= this.totalItems()) {
this.page++;
}
this.paginate(this.page);
}
/**
* @param {?} id
* @return {?}
*/
showUpdate(id) {
this.dialogue = true;
// console.log('Showing the updates');
this.data.data.forEach((value) => {
if (value.id === id) {
this.dialogeData = value;
}
});
}
/**
* @return {?}
*/
closeDialogue() {
this.dialogue ? this.dialogue = false : this.dialogue = true;
this.dialogeData = {};
}
/**
* @param {?} dialogeData
* @return {?}
*/
submitUpdateRow(dialogeData) {
this.updateRow.emit(dialogeData);
}
/**
* @return {?}
*/
processData() {
if (this.dataSource && this.dataSource.length > 0) {
this.total = this.dataSource.length;
if (this.headers.thead && this.headers.thead.length > 0) {
this.data['headers'] = this.headers.thead;
this.displayed = this.headers.displayed;
}
else {
console.warn('No headers data for table provided');
}
this.paginate(this.page);
}
else {
console.warn('No data for table provided');
}
}
}
DataTableComponent.decorators = [
{ type: Component, args: [{
selector: 'json-table',
template: "<div *ngIf=\"data\" class=\"data-table\">\n <div *ngIf=\"false\">\n <input type=\"text\" class=\"search\" placeholder=\"Search for details\">\n </div>\n <table>\n <thead>\n <tr>\n <th style=\"width: 4%\"> </th>\n <th style=\"width: 4%\">#</th>\n <th *ngFor=\"let header of data.headers\" style=\"text-align:left\">{{header}}</th>\n <th *ngIf=\"update\"> </th>\n </tr>\n </thead>\n <tbody>\n\n <tr *ngFor=\"let row of data.data; let i = index\">\n <td><input type=\"checkbox\" [checked]=\"checkAll\" (change)=\"selected($event,row.id)\"></td>\n <td>{{ i+1 }}</td>\n <td *ngFor=\"let attr of displayed\" >{{row[attr]}}</td>\n <td *ngIf=\"update\" style=\"text-align:center\">\n <span (click)=\"showUpdate(row.id)\">\uD83D\uDD89</span>\n </td>\n </tr>\n\n </tbody>\n <tfoot></tfoot>\n </table>\n\n <div class=\"footer\">\n <div class=\"delete\">\n <button (click)=\"deleteSelected()\">Delete {{checked.length}} rows</button>\n </div>\n\n <div class=\"spacer\">\n\n </div>\n\n <div class=\"data-pagination\">\n <select (change)=\"pageOnChange(device.value)\" #device>\n <option value=\"10\">10</option>\n <option value=\"15\">15</option>\n <option value=\"20\">20</option>\n <option value=\"100\">100</option>\n </select>\n | Showing {{page}} of {{totalItems()}} |\n <button class=\"link-button\" (click)=\"previousPage()\">Previous</button>\n -\n <button class=\"link-button\" (click)=\"nextPage()\">Next</button>\n </div>\n </div>\n\n\n <div *ngIf=\"update && dialogue\" class=\"update\" (click)=\"closeDialogue()\">\n\n <div class=\"update-box\" (click)=\"$event.stopPropagation()\">\n <h2>Edit the Row</h2>\n <form #customForm=\"ngForm\" novalidate (ngSubmit)=\"submitUpdateRow(dialogeData); closeDialogue()\">\n <div class=\"f-x\">\n <ng-container *ngFor=\"let attr of displayed; let i = index\">\n <div *ngIf=\"attr!='id' \" class=\"f-y\">\n <label>{{data.headers[i]}}</label>\n <input type=\"text\" [value]=\"dialogeData[attr]\" [placeholder]=\"attr\" [name]=\"attr\"\n [(ngModel)]=\"dialogeData[attr]\">\n </div>\n </ng-container>\n </div>\n <footer>\n <br>\n <button type=\"submit\">Update the row</button>\n <button type=\"button\" (click)=\"closeDialogue()\">Cancel</button>\n </footer>\n </form>\n </div>\n </div>\n\n</div>\n",
styles: [".data-table{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12);margin:10px;border-radius:8px;background:#fff;padding-top:8px}.data-table .search{width:100%;height:42px;border:none;outline:0;text-align:left;border-bottom:1px solid rgba(0,0,0,.12)}.data-table table{display:table;border-collapse:separate;border-spacing:2px;border-color:grey;width:100%;background:#fff}.data-table table tbody td:first-of-type,.data-table table tbody th:first-of-type,.data-table table thead td:first-of-type,.data-table table thead th:first-of-type{padding-left:24px!important;padding-right:24px!important}.data-table table thead{display:table-header-group;vertical-align:middle;border-color:inherit}.data-table table thead tr{height:56px}.data-table table tbody{display:table-row-group;vertical-align:middle;border-color:inherit}.data-table table tbody tr{height:48px;color:rgba(0,0,0,.87)}.data-table table th{padding:0;color:rgba(0,0,0,.54);border-bottom:1px solid rgba(0,0,0,.12)}.data-table table tfoot{display:table-footer-group;vertical-align:middle;border-color:inherit}.data-table .footer{display:flex;height:40px;border-top:1px solid rgba(0,0,0,.12)}.data-table .footer .spacer{flex-grow:1}.data-table .footer .delete{width:120px;background:0 0}.data-table .footer .delete button{height:80%;background:0 0;border:none;outline:0;cursor:pointer;transition:.25s linear;border-radius:4px;margin-left:5px;margin-top:4px}.data-table .footer .delete button:hover{background-color:#fbab33;color:#fff}.data-table .footer .data-pagination{padding-right:20px;padding-top:4px}.data-table .footer .data-pagination select{outline:0;background:0 0;padding:4px}.data-table .footer .data-pagination .link-button{border:none;outline:0;background:0 0}.data-table .footer .data-pagination .link-button:hover{text-decoration:underline}.data-table .update{transition:.5s linear;position:fixed;height:100vh;width:100vw;background:rgba(212,212,212,.51);top:0;left:0;display:flex;align-items:center;justify-content:center}.data-table .update .update-box{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12);background:#fff;padding:8px;border-radius:4px;width:250px}.data-table .update .f-x{display:flex;flex-direction:column}.data-table .update .f-y{display:flex;flex-direction:column;margin-top:6px}.data-table .update input[type=text]{margin-right:4px;padding:4px}"]
}] }
];
/** @nocollapse */
DataTableComponent.ctorParameters = () => [];
DataTableComponent.propDecorators = {
dataSource: [{ type: Input }],
headers: [{ type: Input }],
update: [{ type: Input }],
deleteRow: [{ type: Output }],
updateRow: [{ type: Output }]
};
if (false) {
/** @type {?} */
DataTableComponent.prototype.dataSource;
/** @type {?} */
DataTableComponent.prototype.headers;
/** @type {?} */
DataTableComponent.prototype.update;
/** @type {?} */
DataTableComponent.prototype.deleteRow;
/** @type {?} */
DataTableComponent.prototype.updateRow;
/** @type {?} */
DataTableComponent.prototype.data;
/** @type {?} */
DataTableComponent.prototype.displayed;
/** @type {?} */
DataTableComponent.prototype.perpage;
/** @type {?} */
DataTableComponent.prototype.total;
/** @type {?} */
DataTableComponent.prototype.page;
/** @type {?} */
DataTableComponent.prototype.checked;
/** @type {?} */
DataTableComponent.prototype.checkAll;
/** @type {?} */
DataTableComponent.prototype.dialogue;
/** @type {?} */
DataTableComponent.prototype.dialogeData;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS10YWJsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9hbmd1bGFyLWpzb24tdGFibGUvIiwic291cmNlcyI6WyJzcmMvYXBwL21vZHVsZXMvZGF0YS10YWJsZS9kYXRhLXRhYmxlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBQyxNQUFNLGVBQWUsQ0FBQztBQU83RSxNQUFNO0lBcUJKO3lCQWZ5QyxJQUFJLFlBQVksRUFBTzt5QkFDdkIsSUFBSSxZQUFZLEVBQU87b0JBRXBELEVBQUU7eUJBRUYsRUFBRTt1QkFDSixFQUFFO29CQUVMLENBQUM7dUJBRU8sRUFBRTt3QkFDTixLQUFLO3dCQUNMLEtBQUs7MkJBQ0csRUFBRTtLQUdwQjs7OztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7S0FDcEI7Ozs7OztJQUVELFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRTtRQUNaLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7WUFDcEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDdkI7S0FDRjs7OztJQUVELGNBQWM7UUFDWixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUMzQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQy9ELE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDekMsQ0FBQyxDQUFDO1lB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SSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQzthQUN6QztpQkFBTTtnQkFDTCxPQUFPLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxDQUFDLENBQUM7YUFDcEQ7WUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUMxQjthQUFNO1lBQ0wsT0FBTyxDQUFDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1NBQzVDOzs7O1lBM0hKLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsWUFBWTtnQkFDdEIsNmhGQUEwQzs7YUFFM0M7Ozs7O3lCQUdFLEtBQUs7c0JBQ0wsS0FBSztxQkFDTCxLQUFLO3dCQUVMLE1BQU07d0JBQ04sTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2pzb24tdGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vZGF0YS10YWJsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2RhdGEtdGFibGUuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBEYXRhVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIEBJbnB1dCgpIGRhdGFTb3VyY2U6IGFueTtcbiAgQElucHV0KCkgaGVhZGVyczogYW55O1xuICBASW5wdXQoKSB1cGRhdGU6IGJvb2xlYW47XG5cbiAgQE91dHB1dCgpIGRlbGV0ZVJvdzogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIHVwZGF0ZVJvdzogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBkYXRhOiBhbnkgPSB7fTtcblxuICBkaXNwbGF5ZWQgPSBbXTtcbiAgcGVycGFnZSA9IDEwO1xuICB0b3RhbDogbnVtYmVyO1xuICBwYWdlID0gMTtcblxuICBjaGVja2VkOiBhbnkgPSBbXTtcbiAgY2hlY2tBbGwgPSBmYWxzZTtcbiAgZGlhbG9ndWUgPSBmYWxzZTtcbiAgZGlhbG9nZURhdGE6IGFueSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5wcm9jZXNzRGF0YSgpO1xuICB9XG5cbiAgc2VsZWN0ZWQoZSwgaWQpIHtcbiAgICBpZiAoZS50YXJnZXQuY2hlY2tlZCkge1xuICAgICAgdGhpcy5jaGVja2VkLnB1c2goaWQpO1xuICAgIH1cbiAgfVxuXG4gIGRlbGV0ZVNlbGVjdGVkKCkge1xuICAgIGlmICh0aGlzLmNoZWNrZWQubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5kZWxldGVSb3cuZW1pdCh0aGlzLmNoZWNrZWQpO1xuICAgICAgdGhpcy5kYXRhU291cmNlID0gdGhpcy5kYXRhU291cmNlLmZpbHRlcigodmFsdWUsIGluZGV4LCBhcnJheSkgPT4ge1xuICAgICAgICByZXR1cm4gIXRoaXMuY2hlY2tlZC5pbmNsdWRlcyh2YWx1ZS5pZCk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2hlY2tlZCA9IFtdO1xuICAgICAgdGhpcy5wYWdpbmF0ZSh0aGlzLnBhZ2UpO1xuICAgIH1cbiAgfVxuXG4gIHRvdGFsSXRlbXMoKSB7XG4gICAgaWYgKHRoaXMudG90YWwgPiB0aGlzLnBlcnBhZ2UpIHtcbiAgICAgIHJldHVybiBNYXRoLmNlaWwodGhpcy50b3RhbCAvIHRoaXMucGVycGFnZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIHBhZ2luYXRlKHBhZ2UpIHtcbiAgICBjb25zdCBzdGFydCA9ICh0aGlzLnBlcnBhZ2UgKiBwYWdlKSAtIHRoaXMucGVycGFnZTtcbiAgICBjb25zdCBlbmQgPSAodGhpcy5wZXJwYWdlICogcGFnZSk7XG4gICAgLy8gY29uc29sZS5sb2coc3RhcnQsIGVuZCk7XG4gICAgdGhpcy5kYXRhWydkYXRhJ10gPSB0aGlzLmRhdGFTb3VyY2Uuc2xpY2Uoc3RhcnQsIGVuZCk7XG4gICAgLy8gY29uc29sZS5sb2codGhpcy5kYXRhKTtcbiAgfVxuXG4gIHBhZ2VPbkNoYW5nZShwZXJQYWdlKSB7XG4gICAgdGhpcy5wZXJwYWdlID0gcGVyUGFnZTtcbiAgICB0aGlzLnBhZ2UgPSAxO1xuICAgIC8vY29uc29sZS5sb2cocGVyUGFnZSk7XG4gICAgdGhpcy5wYWdpbmF0ZSh0aGlzLnBhZ2UpO1xuICB9XG5cbiAgcHJldmlvdXNQYWdlKCkge1xuICAgIGlmICh0aGlzLnBhZ2UgPiAxKSB7XG4gICAgICB0aGlzLnBhZ2UtLTtcbiAgICB9XG5cbiAgICB0aGlzLnBhZ2luYXRlKHRoaXMucGFnZSk7XG4gIH1cblxuICBuZXh0UGFnZSgpIHtcbiAgICBpZiAodGhpcy5wYWdlICsgMSA8PSB0aGlzLnRvdGFsSXRlbXMoKSkge1xuICAgICAgdGhpcy5wYWdlKys7XG4gICAgfVxuXG4gICAgdGhpcy5wYWdpbmF0ZSh0aGlzLnBhZ2UpO1xuICB9XG5cbiAgc2hvd1VwZGF0ZShpZDogYW55KSB7XG4gICAgdGhpcy5kaWFsb2d1ZSA9IHRydWU7XG4gICAgLy8gY29uc29sZS5sb2coJ1Nob3dpbmcgdGhlIHVwZGF0ZXMnKTtcbiAgICB0aGlzLmRhdGEuZGF0YS5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKHZhbHVlLmlkID09PSBpZCkge1xuICAgICAgICB0aGlzLmRpYWxvZ2VEYXRhID0gdmFsdWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgfVxuXG4gIGNsb3NlRGlhbG9ndWUoKSB7XG4gICAgdGhpcy5kaWFsb2d1ZSA/IHRoaXMuZGlhbG9ndWUgPSBmYWxzZSA6IHRoaXMuZGlhbG9ndWUgPSB0cnVlO1xuICAgIHRoaXMuZGlhbG9nZURhdGEgPSB7fTtcbiAgfVxuXG4gIHN1Ym1pdFVwZGF0ZVJvdyhkaWFsb2dlRGF0YTogYW55KSB7XG4gICAgdGhpcy51cGRhdGVSb3cuZW1pdChkaWFsb2dlRGF0YSk7XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NEYXRhKCkge1xuICAgIGlmICh0aGlzLmRhdGFTb3VyY2UgJiYgdGhpcy5kYXRhU291cmNlLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMudG90YWwgPSB0aGlzLmRhdGFTb3VyY2UubGVuZ3RoO1xuXG4gICAgICBpZiAodGhpcy5oZWFkZXJzLnRoZWFkICYmIHRoaXMuaGVhZGVycy50aGVhZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuZGF0YVsnaGVhZGVycyddID0gdGhpcy5oZWFkZXJzLnRoZWFkO1xuICAgICAgICB0aGlzLmRpc3BsYXllZCA9IHRoaXMuaGVhZGVycy5kaXNwbGF5ZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oJ05vIGhlYWRlcnMgZGF0YSBmb3IgdGFibGUgcHJvdmlkZWQnKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5wYWdpbmF0ZSh0aGlzLnBhZ2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLndhcm4oJ05vIGRhdGEgZm9yIHRhYmxlIHByb3ZpZGVkJyk7XG4gICAgfVxuXG5cbiAgfVxufVxuXG4iXX0=