bootstrangular-datatable
Version:
Este es un simple modulo de tabla interactiva al estilo de Angular, Bootstrap y Datatable. Necesita angular/core, bootstrap y sus dependencias (jquery y popper) para funcionar.
167 lines (162 loc) • 11.7 kB
JavaScript
import { Component, Input, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
class DatatableComponent {
constructor() {
this.pageSizeOptions = [];
this.pageIndex = 1;
this.showNumeration = false;
this.showSearcher = true;
this.showSizeOptions = true;
this.showPaginator = true;
}
ngOnInit() {
this.checkPageSize();
}
/** Obtener fuente de datos
* @description Devuelve los datos filtrados en caso de que `filterText` tenga
* valor, de lo contrario devuelve el total de datos. */
getDataSource() {
return this.filterText ? this.dataSourceFilter : this.dataSource;
}
/** Obtener datos por página
* @description Devuelve los datos por tamaño de página (número de renglones)
* dependiendo del índice de página del que se encuentre. */
getPageData() {
return this.getDataSource().slice(this.getPageRowStart() - 1, this.getPageRowEnd());
}
/** Obtener el renglón inicial por página
* @description Devuelve el numero del renglón inicial de la página actual. */
getPageRowStart() {
return (this.pageSize * this.pageIndex) - (this.pageSize - 1);
}
/** Obtener el renglón final por página
* @description Devuelve el numero del renglón final de la página actual. */
getPageRowEnd() {
if (this.pageIndex === this.getLastPage())
return this.getPageRowStart() + (this.getDataSource().length - this.getPageRowStart());
else
return this.pageSize * this.pageIndex;
}
/** Ir a la primer página */
goFirstPage() {
this.pageIndex = 1;
}
/** Ir a la página anterior */
goPreviousPage() {
this.pageIndex--;
}
/** Ir a la siguiente página */
goNextPage() {
this.pageIndex++;
}
/** Ir a la ultima página */
goLastPage() {
this.pageIndex = this.getLastPage();
}
/** Obtener ultima página
* @description Devuelve el índice de la ultima página de los datos disponibles
* calculado por el tamaño de datos por página. */
getLastPage() {
if (this.getDataSource().length % this.pageSize !== 0)
return Math.floor(this.getDataSource().length / this.pageSize) + 1;
else
return Math.floor(this.getDataSource().length / this.pageSize);
}
/** Cambiar tamaño de página
* @description Cambia el tamaño de renglones de la tabla por página vinculado
* con el índice de la página actual para no rebasar el total de datos por página.
* @param size Valor para el nuevo tamaño de página. */
changePageSize(size) {
const isInLastPage = this.pageIndex === this.getLastPage() ? true : false;
this.pageSize = size;
if (this.pageIndex >= this.getLastPage() || isInLastPage)
this.goLastPage();
}
/** Revisar tamaño de página
* @description Verifica si `pageSize` está vacío, en tal caso se le asignará
* el primer valor de la lista de opciones. En caso de que la lista de opciones
* también se encuentre vacía, agrega el total de los datos como valor único. */
checkPageSize() {
if (!this.pageSize) {
if (!this.pageSizeOptions.length)
this.pageSizeOptions.push(this.dataSource.length);
this.pageSize = this.pageSizeOptions[0];
}
else if (!this.pageSizeOptions.find((op) => op === this.pageSize)) {
this.addPageSizeToPageSizeOptions();
}
}
/** Añadir tamaño de página
* @description Añade a la lista de opciones de tamaño de pagina el tamaño
* de pagina `pageSize` que llegue como parámetro. */
addPageSizeToPageSizeOptions() {
this.pageSizeOptions.push(this.pageSize);
this.pageSizeOptions.sort((a, b) => a - b);
}
/** Obtener encabezados
* @description Obtiene los encabezados de la tabla, en caso de que no se
* definan como parámetro, devolverá una lista de las llaves de la primer fila. */
getHeaders() {
if (this.headers)
return Object.keys(this.headers).map((item) => {
return { id: item, value: this.headers[item] };
});
else
return Object.keys(this.dataSource[1]).map((item) => {
return { id: item, value: item };
});
}
/** Aplicar filtro
* @description Guarda en `filterText` lo escrito en la caja de búsqueda y
* guarda en `dataSourceFilter` el filtro aplicado en los datos.
* @param filter Texto escrito en la caja de búsqueda. */
applyFilter(filter) {
if (filter.trim()) {
this.filterText = filter.trim().toLowerCase();
this.dataSourceFilter = this.dataSource.filter((item) => {
return this.getHeaders().map((head) => item[head.id].trim().toLowerCase().includes(this.filterText)).some((element) => element);
});
if (this.pageIndex > this.getLastPage())
this.goLastPage();
}
else {
this.filterText = undefined;
this.goFirstPage();
}
}
}
DatatableComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable',
template: "<div class=\"row\">\n <div class=\"col-md-6\">\n <div *ngIf=\"tableBtnOptions\" class=\"btn-group btn-group-sm mr-2 mb-2\" role=\"group\">\n <button *ngFor=\"let btnTable of tableBtnOptions\"\n (click)=\"btnTable.action()\"\n type=\"button\"\n class=\"btn btn-secondary\"\n data-toggle=\"tooltip\"\n data-placement=\"bottom\"\n [title]=\"btnTable.title\">\n <div *ngIf=\"btnTable.icon; then btnTableIcon; else btnTableTitle\"></div>\n <ng-template #btnTableIcon>\n <i *ngIf=\"btnTable.icon.origin === 'bootstrap'\" [class]=\"btnTable.icon.icon\"></i>\n <img *ngIf=\"btnTable.icon.origin === 'img'\" [attr.src]=\"btnTable.icon.icon\" class=\"img-icon\">\n </ng-template>\n <ng-template #btnTableTitle>{{btnTable.title}}</ng-template>\n </button>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div *ngIf=\"showSearcher\" class=\"input-group input-group-sm mb-2\">\n <div class=\"input-group-prepend\">\n <div class=\"input-group-text\" id=\"btnGroupAddon\">\uD83D\uDD0E</div>\n </div>\n <input type=\"text\" class=\"form-control\"\n placeholder=\"Buscar en la tabla\" aria-label=\"Buscar en la tabla\"\n (keyup)=\"applyFilter($event.target.value)\">\n </div>\n </div>\n</div>\n\n<div class=\"table-responsive\">\n <table class=\"table table-bordered table-sm table-striped\">\n <thead>\n <tr>\n <th *ngIf=\"showNumeration\">#<!--span class=\"text-muted float-right\">\u2B07\uFE0F\u2B06\uFE0F</span--></th>\n <th *ngFor=\"let head of getHeaders()\">{{head.value}}</th>\n <th *ngIf=\"rowBtnOptions\">\u2699\uFE0F</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of getPageData(); let i = index\">\n <td *ngIf=\"showNumeration\">{{i + getPageRowStart()}}</td>\n <td *ngFor=\"let key of getHeaders()\">{{row[key.id]}}</td>\n <th *ngIf=\"rowBtnOptions\">\n <div class=\"row\" style=\"margin: auto;\">\n <div *ngFor=\"let btnRow of rowBtnOptions\"\n (click)=\"btnRow.action(row)\"\n class=\"btn-row\">\n <div *ngIf=\"btnRow.icon; then btnRowIcon; else btnRowTitle\"></div>\n <ng-template #btnRowIcon>\n <i *ngIf=\"btnRow.icon.origin === 'bootstrap'\" [class]=\"btnRow.icon.icon\"\n data-toggle=\"tooltip\" data-placement=\"bottom\" [title]=\"btnRow.title\"></i>\n <img *ngIf=\"btnRow.icon.origin === 'img'\" [attr.src]=\"btnRow.icon.icon\" class=\"img-icon\"\n data-toggle=\"tooltip\" data-placement=\"bottom\" [title]=\"btnRow.title\">\n </ng-template>\n <ng-template #btnRowTitle>\n <small>{{btnRow.title}}</small>\n </ng-template>\n </div>\n </div>\n </th>\n </tr>\n </tbody>\n </table>\n</div>\n\n<div class=\"row\">\n <div class=\"col-sm-6\">\n <div *ngIf=\"showSizeOptions\"\n class=\"input-group input-group-sm mr-2 mb-2 select-page-size\">\n <div class=\"input-group-prepend\">\n <label class=\"input-group-text\" for=\"\">Renglones por p\u00E1gina</label>\n </div>\n <select class=\"custom-select\" (change)=\"changePageSize($event.target.value)\">\n <option *ngFor=\"let option of pageSizeOptions\"\n [value]=\"option\"\n [selected]=\"option === pageSize? 'selected': null\">\n {{option}}\n </option>\n </select>\n </div>\n </div>\n <div class=\"col-sm-6\">\n <nav *ngIf=\"showPaginator\">\n <ul class=\"pagination pagination-sm justify-content-end\">\n <li class=\"page-item\">\n <span class=\"page-link paginator-label\">\n {{getPageRowStart()}} - {{getPageRowEnd()}} de {{this.getDataSource().length}}\n </span>\n </li>\n <li class=\"page-item\" [ngClass]=\"{'disabled': pageIndex === 1}\">\n <a class=\"page-link\" href=\"javascript:void(0);\" (click)=\"goFirstPage()\">\n <span aria-hidden=\"true\">[«</span>\n </a>\n </li>\n <li class=\"page-item\" [ngClass]=\"{'disabled': pageIndex === 1}\">\n <a class=\"page-link\" href=\"javascript:void(0);\" (click)=\"goPreviousPage()\">\n <span aria-hidden=\"true\">«</span>\n </a>\n </li>\n <li class=\"page-item\"><span class=\"page-link paginator-label\">{{pageIndex}}</span></li>\n <li class=\"page-item\" [ngClass]=\"{'disabled': pageIndex === getLastPage()}\">\n <a class=\"page-link\" href=\"javascript:void(0);\" (click)=\"goNextPage()\">\n <span aria-hidden=\"true\">»</span>\n </a>\n </li>\n <li class=\"page-item\" [ngClass]=\"{'disabled': pageIndex === getLastPage()}\">\n <a class=\"page-link\" href=\"javascript:void(0);\" (click)=\"goLastPage()\">\n <span aria-hidden=\"true\">»]</span>\n </a>\n </li>\n </ul>\n </nav>\n </div>\n</div>",
styles: [".select-page-size{width:250px}.paginator-label{background-color:#e9ecef!important;border:1px solid #ced4da!important}.page-link,.paginator-label{color:#495057!important}.img-icon{max-height:14px;max-width:14px}.btn-row>*{color:#535c68;cursor:pointer;margin-inline:4px}.btn-row>i{max-height:14px;max-width:14px}"]
},] }
];
DatatableComponent.ctorParameters = () => [];
DatatableComponent.propDecorators = {
dataSource: [{ type: Input }],
headers: [{ type: Input }],
pageSize: [{ type: Input }],
pageSizeOptions: [{ type: Input }],
pageIndex: [{ type: Input }],
tableBtnOptions: [{ type: Input }],
rowBtnOptions: [{ type: Input }],
showNumeration: [{ type: Input }],
showSearcher: [{ type: Input }],
showSizeOptions: [{ type: Input }],
showPaginator: [{ type: Input }]
};
class DatatableModule {
}
DatatableModule.decorators = [
{ type: NgModule, args: [{
declarations: [DatatableComponent],
imports: [CommonModule],
exports: [DatatableComponent]
},] }
];
/**
* Generated bundle index. Do not edit.
*/
export { DatatableComponent, DatatableModule };
//# sourceMappingURL=bootstrangular-datatable.js.map