ng-pure-datatable
Version:
This is a Angular datatable for tables which is not dependent on jquery. This is fully written with typescript and it uses observables to communicate events across the user defined table. This is inspired by previous libraries I wrote for `Larang-Paginato
1,056 lines (1,020 loc) • 36.9 kB
JavaScript
import { Component, Injectable, Input, NgModule } from '@angular/core';
import { Subject as Subject$1 } from 'rxjs/Subject';
import { Observable as Observable$1 } from 'rxjs/Observable';
import 'rxjs/add/observable/from';
import { CommonModule } from '@angular/common';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/switch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/map';
import { ReplaySubject as ReplaySubject$1 } from 'rxjs/ReplaySubject';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
let NgSearchTypesEnum = {};
NgSearchTypesEnum.ON_TABLE = 0;
NgSearchTypesEnum.ON_BACKEND = 1;
NgSearchTypesEnum.EMPTY_TABLE_APPLY_BACKEND = 2;
NgSearchTypesEnum[NgSearchTypesEnum.ON_TABLE] = "ON_TABLE";
NgSearchTypesEnum[NgSearchTypesEnum.ON_BACKEND] = "ON_BACKEND";
NgSearchTypesEnum[NgSearchTypesEnum.EMPTY_TABLE_APPLY_BACKEND] = "EMPTY_TABLE_APPLY_BACKEND";
class NgPureDataTableEventService {
constructor() {
this.listeners = {};
this.eventsSubject = new Subject$1();
this.events = Observable$1.from(this.eventsSubject);
this.events.subscribe(({ name, args }) => {
if (this.listeners[name]) {
for (const listener of this.listeners[name]) {
listener(...args);
}
}
});
}
/**
* @param {?} name
* @param {?} listener
* @return {?}
*/
on(name, listener) {
if (!this.listeners[name]) {
this.listeners[name] = [];
this.listeners[name].push(listener);
}
if (this.listeners[name]) {
this.listeners[name][0] = listener;
}
}
/**
* @param {?} name
* @param {...?} args
* @return {?}
*/
broadcast(name, ...args) {
// console.log('name=', name);
this.eventsSubject.next({
name,
args
});
}
}
NgPureDataTableEventService.decorators = [
{ type: Injectable },
];
/**
* @nocollapse
*/
NgPureDataTableEventService.ctorParameters = () => [];
class NgPureDatatableComponent {
/**
* @param {?} ngPureDataTableEventService
*/
constructor(ngPureDataTableEventService) {
this.ngPureDataTableEventService = ngPureDataTableEventService;
this.key = '';
this.id = '';
this.disableSearch = false;
this.disablePaging = false;
this.paginateSettings = {
data: {},
path: '',
limit: 50,
from: '',
perNav: 5,
viewPage: 'page',
paginate: 'paginate',
textColor: '#000'
};
this.searchSettings = {
path: null,
placeholder: 'What are you looking for?',
data: [],
searchKeys: [],
position: 'right',
positionStyle: {
right: null,
top: null,
},
width: 40,
from: null,
queryField: 'search',
borderColor: '#eee000',
buttonColor: '#83e6bc',
searchType: NgSearchTypesEnum.EMPTY_TABLE_APPLY_BACKEND
};
this.top = 0;
this.style = { position: 'absolute', 'margin-bottom': '100px' };
this.ranges = [];
}
/**
* @return {?}
*/
ngOnInit() {
this.paginateSettings['viewPage'] = (!this.paginateSettings['viewPage']) ? 'page' : this.paginateSettings['viewPage'];
this.paginateSettings['paginate'] = (!this.paginateSettings['paginate']) ? 'paginate' : this.paginateSettings['paginate'];
this.paginateSettings['from'] = this.key;
this.searchSettings['from'] = this.key;
this.searchSettings['position'] = (this.searchSettings['position']) ? this.searchSettings['position'] : 'right';
this.searchSettings['positionStyle'] = (this.searchSettings['positionStyle']) ? this.searchSettings['positionStyle'] : null;
this.searchSettings['width'] = (this.searchSettings['width']) ? this.searchSettings['width'] : 40;
this.paginateSettings['textColor'] = (this.paginateSettings['textColor']) ? this.paginateSettings['textColor'] : '#000';
this.style['width'] = this.searchSettings['width'] + '%';
this.limitStyle = JSON.parse(JSON.stringify(this.style));
this.limitStyle['width'] = '200px';
// console.log('width', this.searchSettings['width'], this.searchSettings['position']);
this.configSearchDisplay();
this.processLimit();
}
/**
* This is used to generate limit range.
* @return {?}
*/
processLimit() {
const /** @type {?} */ div = Math.floor(+this.paginateSettings.limit / 2);
this.ranges = [];
let /** @type {?} */ range = 0;
// console.log('div=', div);
if ((div % 2) === 0) {
range = 10;
}
else {
range = 15;
}
const /** @type {?} */ ranges = (range === 10) ? 101 : 106;
for (let /** @type {?} */ i = range; i < ranges; i += range) {
if (i > this.paginateSettings.data['total']) {
break;
}
this.ranges.push(i);
}
}
/**
* This is used to update limit
* @param {?} limit
* @return {?}
*/
updateLimit(limit) {
this.paginateSettings.limit = +limit;
// console.log('this.paginateSettings.limit', this.paginateSettings.limit);
this.ngPureDataTableEventService.broadcast('resetLimitCalled', this.paginateSettings.limit);
}
/**
* This is used to set the border color for the div
* @return {?}
*/
setBorderColor() {
this.searchSettings.borderColor = (this.searchSettings.borderColor) ? this.searchSettings.borderColor : '#eee000';
return { 'border-bottom': '3px solid ' + this.searchSettings.borderColor };
}
/**
* This is used to configure search and limit position
* @return {?}
*/
configSearchDisplay() {
this.id = (this.id.indexOf('#') > -1) ? this.id : '#' + this.id;
const /** @type {?} */ element = document.querySelector(this.id);
this.top = element.getBoundingClientRect().top;
if (this.top < 50) {
this.style['margin-top'] = '20px';
this.limitStyle['margin-top'] = this.style['margin-top'];
element['style'].marginTop = '80px';
}
const /** @type {?} */ right = (this.searchSettings['positionStyle'] && (this.searchSettings['positionStyle']['right'] <= -1 || this.searchSettings['positionStyle']['right'] >= 0)) ? this.searchSettings['positionStyle']['right'] : '10px';
const /** @type {?} */ top = (this.searchSettings['positionStyle'] && (this.searchSettings['positionStyle']['top'] >= 0 || this.searchSettings['positionStyle']['top'] <= -1)) ? this.searchSettings['positionStyle']['top'] : null;
if (this.searchSettings['position'].toLowerCase() === 'right') {
this.style['right'] = right + 'px';
this.limitStyle['left'] = this.style['right'];
}
else {
this.style['left'] = right + 'px';
this.limitStyle['right'] = this.style['left'];
}
this.top = (top) ? top : (this.top && this.top > 50) ? this.top - 50 : this.top;
this.style['top'] = this.top + 'px';
this.limitStyle['top'] = this.style['top'];
// console.log('element=', element.getBoundingClientRect().top);
}
}
NgPureDatatableComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-pure-datatable',
template: `
<div *ngIf="paginateSettings.data">
<div class="limit-style" *ngIf="limitStyle && !disablePaging" [ngStyle]="limitStyle">
<!--<label for="limit">Limit: </label>-->
<select id="limit" [ngStyle]="setBorderColor()" [(ngModel)]="paginateSettings.limit"
(change)="updateLimit(+limit.value)" #limit>
<option value="" disabled selected>Select Limit</option>
<option *ngFor="let num of ranges" value="{{num}}">{{num}}</option>
</select>
</div>
<div class="search-app" *ngIf="!disableSearch" [ngStyle]="style">
<ng-search [allSettings]="searchSettings"></ng-search>
<div style="clear: both;"></div>
</div>
<ng-paginate *ngIf="!disablePaging" [from]="paginateSettings.from" [data]="paginateSettings.data"
[path]="paginateSettings.path"
[limit]="paginateSettings.limit" [perNav]="paginateSettings.perNav"
[viewPage]="paginateSettings.viewPage" [paginate]="paginateSettings.paginate"
[textColor]="paginateSettings.textColor"></ng-paginate>
</div>
`,
styles: [`
select {
width: 100% !important;
height: 30px !important;
padding: 5px !important;
color: #000 !important;
border: 1px solid #ccc;
border-bottom: 3px solid #eee000;
}
select:visited, select:active, select:link, select:after, select:hover, select:focus, button:focus {
outline: none;
}
(max-width: 768px) {
.search-app {
width: 55% !important;
}
.limit-style {
width: 100px !important;
}
}
`]
},] },
];
/**
* @nocollapse
*/
NgPureDatatableComponent.ctorParameters = () => [
{ type: NgPureDataTableEventService, },
];
NgPureDatatableComponent.propDecorators = {
'key': [{ type: Input },],
'id': [{ type: Input },],
'disableSearch': [{ type: Input },],
'disablePaging': [{ type: Input },],
'paginateSettings': [{ type: Input },],
'searchSettings': [{ type: Input },],
};
class NgPaginateService {
/**
* @param {?} http
*/
constructor(http$$1) {
this.http = http$$1;
}
/**
* This is used to list all by paginator
* @param {?} url
* @return {?}
*/
listByPaginator(url) {
return this.http.get(url);
}
}
NgPaginateService.decorators = [
{ type: Injectable },
];
/**
* @nocollapse
*/
NgPaginateService.ctorParameters = () => [
{ type: HttpClient, },
];
class NgPaginateComponent {
/**
* @param {?} ngPaginateService
* @param {?} ngPureDataTableEventService
*/
constructor(ngPaginateService, ngPureDataTableEventService) {
this.ngPaginateService = ngPaginateService;
this.ngPureDataTableEventService = ngPureDataTableEventService;
this.path = '';
this.limit = 50;
this.from = '';
this.perNav = 5;
this.viewPage = 'page';
this.paginate = 'paginate';
this.textColor = '#000';
this.next_page = '';
this.prev_page = '';
this.showLoad = 0;
this.totalPages = [];
this.pages = [];
this.total = 0;
this.perNavCopy = {
nav: 5
};
this.ngPureDataTableEventService.on('getUrlPath', (path) => {
this.path = path;
});
this.ngPureDataTableEventService.on('resetLimitCalled', (limit) => {
setTimeout(() => {
const buildPage = this.viewPage + '=' + 1;
this.limit = limit;
this.loadData((buildPage + '&' + this.paginate + '=' + this.limit), buildPage);
}, 200);
});
}
/**
* This is used to get total pages array
* @return {?}
*/
getPages() {
for (let /** @type {?} */ i = 1; i <= this.data['last_page']; i++) {
this.totalPages.push(i);
}
const /** @type {?} */ perNav = JSON.parse(JSON.stringify(this.perNavCopy));
this.perNav = perNav.nav;
// console.log('thperVa=', this.perNav);
this.getPaging();
// console.log('pages=', this.totalPages, this.data['last_page'], this.data['current_page']);
}
/**
* This is used get list of page navigation
* @return {?}
*/
getPaging() {
this.perNav += this.pages.length;
this.pages = this.totalPages.slice(0, this.perNav);
}
/**
* This is used to load data
* @param {?} queryPath
* @param {?=} page
* @return {?}
*/
loadData(queryPath, page) {
// console.log('queryPath=', queryPath, page);
const /** @type {?} */ posQ = this.path.indexOf('?');
let /** @type {?} */ url = '';
if (posQ === -1) {
url = this.path + '?' + queryPath;
}
else {
url = this.path + '&' + queryPath;
}
this.showLoad = (typeof (page) === 'string') ? parseInt((page.substr(page.indexOf('=') + 1)), 10) : page;
// console.log('showLoad= ', this.showLoad, page);
this.ngPaginateService.listByPaginator(url).subscribe((res) => {
if (this.showLoad > this.pages.length) {
this.getPaging();
}
this.data = (res['last_page']) ? res : res.data || res.content || res.contents || res.resource || res.resources || res.list || res.items;
this.nextPrevPage();
res['type'] = 'paging';
this.ngPureDataTableEventService.broadcast(this.from, res);
this.showLoad = 0;
this.total = this.data['total'] || this.limit;
// console.log('data=>', data);
this.processPerNav();
}, err => {
err['type'] = 'paging';
this.ngPureDataTableEventService.broadcast(this.from, err);
this.showLoad = 0;
});
}
/**
* This is used to adjust content per nav display based on limit selected
* @return {?}
*/
processPerNav() {
const /** @type {?} */ page = Math.ceil(this.data['total'] / this.limit);
// console.log('page==>', page, 'perNav=', this.perNav );
if (this.perNav > page) {
setTimeout(() => {
this.totalPages = this.totalPages.slice(0, page);
this.pages = this.totalPages.slice(0, page);
}, 200);
}
else {
setTimeout(() => {
this.totalPages = [];
this.pages = [];
this.getPages();
// console.log('this.totalPages', this.totalPages.toString());
}, 200);
}
}
/**
* This is used to get next page number format from page url.
* @return {?}
*/
nextPrevPage() {
const /** @type {?} */ queryString = this.viewPage.trim() + '=';
if (Object.keys(this.data).length === 0) {
return null;
}
if (this.data['next_page_url']) {
const /** @type {?} */ nextPos = this.data['next_page_url'].indexOf(queryString);
this.next_page = this.data['next_page_url'].substr(nextPos).trim();
// console.log('pois=', nextPos, this.next_page);
}
if (this.data['prev_page_url']) {
const /** @type {?} */ prevPos = this.data['prev_page_url'].indexOf(queryString);
this.prev_page = this.data['prev_page_url'].substr(prevPos).trim();
// console.log('prpos=', prevPos, this.prev_page);
}
}
/**
* @return {?}
*/
ngOnInit() {
// console.log('this.data=', this.data);
this.nextPrevPage();
this.getPages();
this.perNavCopy = JSON.parse(JSON.stringify({ nav: this.perNav }));
this.total = this.data['total'] || this.limit;
}
/**
* @return {?}
*/
ngAfterViewInit() {
// console.log('this.data=', this.data);
}
}
NgPaginateComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-paginate',
template: `
<nav aria-label="..." style="position: relative" *ngIf="pages.length !== 0">
<div class="showing" [ngStyle]="{'text-color': textColor}">
Showing {{((data['current_page'] - 1) * (limit <= total ? limit : total) + 1)}} - {{(data['current_page']) * (limit <= total ? limit : total)}} of {{total}} entries
</div>
<ul *ngIf="limit <= data['total']" class="pagination justify-content-end">
<li class="page-item" [class.disabled]="data['prev_page_url'] === null" >
<a class="page-link" (click)="loadData((prev_page + '&' + paginate + '=' + limit), prev_page)" role="button" tabindex="-1">Previous</a>
</li>
<li [class.hide]="pages.length === 0" [class.show]="pages.length > 0" *ngFor="let page of pages" id="page_{{page}}" [class.active]="data['current_page'] === page" class="animated fadeInRight page-item">
<a class="page-link" (click)="loadData((viewPage + '=' + page + '&' + paginate + '=' + limit), page)" role="button">
<i *ngIf="page === showLoad" class="fa fa-spin fa-spinner"></i> {{page}}
</a>
</li>
<li *ngIf="totalPages.length > perNav">
<a (click)="getPaging()" title="Load More Navigation" role="button" class="page-link">...</a>
</li>
<li *ngIf="pages.length === 0">
<a role="button" class="page-link"><i class="fa fa-spin fa-spinner"></i></a>
</li>
<li class="page-item" [class.disabled]="data['next_page_url'] === null" >
<a class="page-link" (click)="loadData((next_page + '&' + paginate + '=' + limit), next_page)" role="button">Next</a>
</li>
</ul>
</nav>
`,
styles: [`
.showing {
color: #000 !important;
font-size: 0.95em;
line-height: 10px;
left: 10px;
top: 15px;
position: absolute;
}
(max-width: 768px) {
.showing {
position: relative;
margin: 10px;
text-align: center;
}
.justify-content-end {
-ms-flex-pack: center !important;
-webkit-box-pack: center !important;
justify-content: center !important;
padding-top: 20px;
}
}
.pagination {
display: -ms-flexbox;
display: -webkit-box;
display: flex;
padding-left: 0;
list-style: none;
border-radius: 0.25rem;
}
.page-item:first-child .page-link {
margin-left: 0;
border-top-left-radius: 0.25rem;
border-bottom-left-radius: 0.25rem;
}
.page-item:last-child .page-link {
border-top-right-radius: 0.25rem;
border-bottom-right-radius: 0.25rem;
}
.page-item.active .page-link {
z-index: 2;
color: #fff;
background-color: #007bff;
border-color: #007bff;
}
.page-item.disabled .page-link {
color: #868e96;
pointer-events: none;
background-color: #fff;
border-color: #ddd;
}
.page-link {
position: relative;
display: block;
padding: 0.5rem 0.75rem;
margin-left: -1px;
line-height: 1.25;
color: #007bff;
background-color: #fff;
border: 1px solid #ddd;
cursor: pointer;
}
.page-link:focus, .page-link:hover {
color: #0056b3;
text-decoration: none;
background-color: #e9ecef;
border-color: #ddd;
}
.pagination-lg .page-link {
padding: 0.75rem 1.5rem;
font-size: 1.25rem;
line-height: 1.5;
}
.pagination-lg .page-item:first-child .page-link {
border-top-left-radius: 0.3rem;
border-bottom-left-radius: 0.3rem;
}
.pagination-lg .page-item:last-child .page-link {
border-top-right-radius: 0.3rem;
border-bottom-right-radius: 0.3rem;
}
.pagination-sm .page-link {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
line-height: 1.5;
}
.pagination-sm .page-item:first-child .page-link {
border-top-left-radius: 0.2rem;
border-bottom-left-radius: 0.2rem;
}
.pagination-sm .page-item:last-child .page-link {
border-top-right-radius: 0.2rem;
border-bottom-right-radius: 0.2rem;
}
.justify-content-end {
-ms-flex-pack: end;
-webkit-box-pack: end;
justify-content: flex-end;
}
.justify-content-start {
-ms-flex-pack: start !important;
-webkit-box-pack: start !important;
justify-content: flex-start !important;
}
.justify-content-center {
-ms-flex-pack: center !important;
-webkit-box-pack: center !important;
justify-content: center !important;
}
`]
},] },
];
/**
* @nocollapse
*/
NgPaginateComponent.ctorParameters = () => [
{ type: NgPaginateService, },
{ type: NgPureDataTableEventService, },
];
NgPaginateComponent.propDecorators = {
'data': [{ type: Input },],
'path': [{ type: Input },],
'limit': [{ type: Input },],
'from': [{ type: Input },],
'perNav': [{ type: Input },],
'viewPage': [{ type: Input },],
'paginate': [{ type: Input },],
'textColor': [{ type: Input },],
};
class NgSearchService {
/**
* @param {?} http
*/
constructor(http$$1) {
this.http = http$$1;
this.searched = [];
}
/**
* This is used to initialize searching of data from the object passed.
* @param {?} values
* @param {?=} toFind
* @param {?=} keys
* @return {?}
*/
initSearch(values, toFind = '', keys) {
this.searched = [];
// console.log('keys= ', keys);
if (keys && keys.length > 0) {
keys.forEach((key) => {
// console.log('key=', key);
this.startSearching(values, toFind, key);
});
}
else {
this.startSearching(values, toFind);
}
// console.log('searched=', this.searched);
const /** @type {?} */ result = new ReplaySubject$1();
result.next(this.searched);
return Observable$1.from(result);
// return this.searched;
}
/**
* This is used to start the search after initialization has taken place.
* @param {?} values
* @param {?} toFind
* @param {?=} key
* @return {?}
*/
startSearching(values, toFind, key) {
// console.log('values=', values);
values.filter((value) => {
const /** @type {?} */ status = (key) ? this.processObject(value, toFind, key) : this.processObject(value, toFind);
if (status && this.searched.indexOf(value) === -1) {
this.searched.push(value);
// console.log('Finalsaerched=', status, this.searched);
}
return status;
});
// console.log('ReturnFinalsaerched=', this.searched);
}
/**
* This is used to start an object search for the input values toFind.
* @param {?} values
* @param {?} toFind
* @param {?=} key
* @return {?}
*/
processObject(values, toFind, key) {
let /** @type {?} */ status = null;
for (const /** @type {?} */ valKey in values) {
if (status) {
// console.log('this is true');
break;
}
else {
const /** @type {?} */ value = values[valKey];
// console.log('value=', values[valKey], 'KeyVal=', valKey, 'key=', key);
if (!value || (key && key !== valKey)) {
status = false;
continue;
}
// console.log('key=', valKey, value);
switch (value.constructor) {
case Array:
status = (key) ? this.processArray(value, toFind, [key, valKey]) : this.processArray(value, toFind);
// console.log('status1=', status);
break;
case Object:
const /** @type {?} */ innerKeys = Object.keys(value);
if (key && innerKeys.indexOf(key) === -1) {
status = false;
continue;
}
status = (key) ? this.processObject(value, toFind, key) : this.processObject(value, toFind);
// console.log('status2=', status);
break;
case String:
status = (key) ? this.processValidation(value, toFind, [key, valKey]) : this.processValidation(value, toFind);
// console.log('status=', status);
break;
case Number:
status = (key) ? this.processValidation(value, toFind, [key, valKey]) : this.processValidation(value, toFind);
// console.log('status=', status);
break;
default:
status = false;
break;
}
}
}
return !!(status);
}
/**
* This is used to filter depth object having multiple level objects or arrays
* @param {?} values
* @param {?} toFind
* @param {?=} keys
* @return {?}
*/
processArray(values, toFind, keys) {
values.filter((value) => {
if (!value || (keys && keys[0] !== keys[1])) {
return false;
}
switch (value.constructor) {
case Array:
return !!((keys[0]) ? this.processArray(value, toFind, keys) : this.processArray(value, toFind));
case Object:
const /** @type {?} */ innerKeys = Object.keys(value);
if (keys[0] && innerKeys.indexOf(keys[0]) === -1) {
return false;
}
return (keys[0]) ? this.processObject(value, toFind, keys[0]) : this.processObject(value, toFind);
case String:
return (keys[0]) ? this.processValidation(value, toFind, keys) : this.processValidation(value, toFind);
case Number:
return (keys[0]) ? this.processValidation(value, toFind, keys) : this.processValidation(value, toFind);
default:
return false;
}
});
return (values && values.length > 0);
}
/**
* This is used to compare if data lookup is valid or not
* @param {?} value
* @param {?} toFind
* @param {?=} keys
* @return {?}
*/
processValidation(value, toFind, keys) {
value = String(value).toLowerCase().trim();
toFind = String(toFind).toLowerCase().trim();
// console.log('toFind=', toFind, 'Value=', value, keys.toString(), (keys[0] === keys[1] && value.indexOf(toFind) > -1));
return (keys) ? (keys[0] === keys[1] && value.indexOf(toFind) > -1) : (value.indexOf(toFind) > -1);
}
/**
* This is used to search backend if empty list is encountered.
* @param {?} url
* @return {?}
*/
searchResource(url) {
return this.http.get(url);
}
}
NgSearchService.decorators = [
{ type: Injectable },
];
/**
* @nocollapse
*/
NgSearchService.ctorParameters = () => [
{ type: HttpClient, },
];
class NgSearchComponent {
/**
* @param {?} ngSearchService
* @param {?} ngPureDataTableEventService
*/
constructor(ngSearchService, ngPureDataTableEventService) {
this.ngSearchService = ngSearchService;
this.ngPureDataTableEventService = ngPureDataTableEventService;
this.search$ = new Subject$1();
this.allSettings = {
path: null,
placeholder: 'What are you looking for?',
data: [],
searchKeys: [],
from: null,
position: 'right',
positionStyle: {
right: null,
top: null
},
width: 40,
queryField: 'search',
borderColor: '#eee000',
buttonColor: '#83e6bc',
searchType: NgSearchTypesEnum.EMPTY_TABLE_APPLY_BACKEND
};
this.searching = false;
this.copyData = [];
this.search$
.distinctUntilChanged()
.debounceTime(400)
.subscribe(res => {
if (res && res.length > 1) {
this.doSearch(res);
return;
}
if (res.length === 0) {
this.ngPureDataTableEventService.broadcast(this.allSettings.from, { type: 'search', result: this.copyData, data: this.copyData });
}
}, err => {
});
}
/**
* This is used to set the border color for the div
* @return {?}
*/
setBorderColor() {
return { 'border-bottom': '3px solid ' + this.allSettings.borderColor };
}
/**
* This is used to style the button background
* @return {?}
*/
setButtonColor() {
return { 'background': this.allSettings.buttonColor };
}
/**
* This is used to initialize searching on a table.
* @param {?} query
* @return {?}
*/
doSearch(query) {
this.copyData = JSON.parse(JSON.stringify(this.allSettings.data));
if (!query) {
return null;
}
this.searching = true;
setTimeout(() => {
switch (this.allSettings.searchType) {
case NgSearchTypesEnum.EMPTY_TABLE_APPLY_BACKEND:
this.processSearching(NgSearchTypesEnum.EMPTY_TABLE_APPLY_BACKEND, query);
break;
case NgSearchTypesEnum.ON_BACKEND:
this.doSearchBackend(query);
break;
case NgSearchTypesEnum.ON_TABLE:
this.processSearching(NgSearchTypesEnum.ON_TABLE, query);
break;
default:
Observable$1.throw('Unknown search type');
break;
}
}, 200);
}
/**
* This is used to search query strings
* @param {?} type
* @param {?} query
* @return {?}
*/
processSearching(type, query) {
this.ngSearchService.initSearch(this.allSettings.data, query, this.allSettings.searchKeys)
.subscribe((result) => {
// console.log('saerchResult=', result);
if (result.length === 0 && type === NgSearchTypesEnum.EMPTY_TABLE_APPLY_BACKEND) {
this.doSearchBackend(query);
return;
}
this.ngPureDataTableEventService.broadcast(this.allSettings.from, { type: 'search', result: result, data: this.copyData });
this.searching = false;
// console.log('searching=', this.searching);
}, (err) => {
this.searching = false;
this.ngPureDataTableEventService.broadcast(this.allSettings.from, { type: 'search', error: err, data: this.copyData });
});
}
/**
* This is used to make a request to a backend api for searching.
* @param {?} query
* @return {?}
*/
doSearchBackend(query) {
const /** @type {?} */ pos = this.allSettings.path.indexOf('?');
const /** @type {?} */ path = (pos > -1) ? this.allSettings.path + `&${this.allSettings.queryField}=${query}` : this.allSettings.path + `?${this.allSettings.queryField}=${query}`;
this.ngSearchService.searchResource(path)
.subscribe((res) => {
this.ngPureDataTableEventService.broadcast(this.allSettings.from, { type: 'search', result: res, data: this.copyData });
this.searching = false;
}, (err) => {
this.searching = false;
this.ngPureDataTableEventService.broadcast(this.allSettings.from, { type: 'search', error: err, data: this.copyData });
});
}
/**
* This is used to validate object passed down to table searcher.
* @return {?}
*/
ValidateSettings() {
for (const /** @type {?} */ key in this.allSettings) {
if (!this.allSettings[key]) {
this.allSettings[key] = NgSearchComponent.defaultAllSettings[key];
}
}
}
/**
* @return {?}
*/
ngOnInit() {
this.ValidateSettings();
this.copyData = JSON.parse(JSON.stringify(this.allSettings.data));
}
}
NgSearchComponent.defaultAllSettings = {
path: null,
placeholder: 'What are you looking for?',
data: [],
searchKeys: [],
from: null,
position: 'right',
width: 40,
positionStyle: {
right: null,
top: null
},
queryField: 'search',
borderColor: '#eee000',
buttonColor: '#83e6bc',
searchType: NgSearchTypesEnum.EMPTY_TABLE_APPLY_BACKEND
};
NgSearchComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-search',
template: `
<div class="ng-search" [ngStyle]="setBorderColor()" [class.disabled]="searching">
<input [disabled]="searching" (keyup)="search$.next(searchItem.value)" #searchItem type="text" placeholder="{{allSettings.placeholder}}">
<!--<i *ngIf="searching" class="fa fa-spin fa-spinner"></i>-->
<!-- <button [disabled]="searching" type="button" (click)="doSearch(searchItem.value)" class="button" [ngStyle]="setButtonColor()">
<i *ngIf="searching" class="fa fa-spin fa-spinner"></i> <i class="fa fa-search"></i>
</button>-->
</div>
<span class="clearOut"></span>
`,
styles: [`
input {
width: 80% !important;
border: 0 !important;
height: 20px !important;
padding: 5px !important;
}
input:visited, input:active, input:link, input:after, input:hover, input:focus, button:focus {
border: 0 !important;
outline: none;
}
.ng-search {
border-radius: 5px !important;
-moz-border-radius: 5px !important;
-webkit-border-radius: 5px !important;
width: 100% !important;
color: #000;
border: 1px solid #ccc;
border-bottom: 3px solid #eee000;
padding: 0 !important;
margin: 0 !important;
font-size: 11px !important;
}
.disabled {
background: rgb(235, 235, 228) !important;
}
.button {
background: #83e6bc;
padding: 9px !important;
color: #fff !important;
border: 0 !important;
cursor: pointer !important;
font-size: 11px;
float: right;
border-radius: 0 5px 5px 0 !important;
-moz-border-radius: 0 5px 5px 0 !important;
-webkit-border-radius: 0 5px 5px 0 !important;
}
.clearOut {
clear: both;
}
`],
},] },
];
/**
* @nocollapse
*/
NgSearchComponent.ctorParameters = () => [
{ type: NgSearchService, },
{ type: NgPureDataTableEventService, },
];
NgSearchComponent.propDecorators = {
'allSettings': [{ type: Input },],
};
class NgPureDatatableModule {
/**
* @return {?}
*/
static forRoot() {
return {
ngModule: NgPureDatatableModule,
providers: [NgPureDataTableEventService, NgSearchService, NgPaginateService]
};
}
}
NgPureDatatableModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule
],
declarations: [NgPureDatatableComponent, NgPaginateComponent, NgSearchComponent],
exports: [NgPureDatatableComponent, NgPaginateComponent, NgSearchComponent],
},] },
];
/**
* @nocollapse
*/
NgPureDatatableModule.ctorParameters = () => [];
/**
* Generated bundle index. Do not edit.
*/
export { NgSearchTypesEnum, NgPureDataTableEventService, NgPureDatatableModule, NgPaginateComponent as ɵb, NgPaginateService as ɵc, NgPureDatatableComponent as ɵa, NgSearchComponent as ɵd, NgSearchService as ɵe };
//# sourceMappingURL=ng-pure-datatable.js.map