diff --git a/.travis.yml b/.travis.yml
index 1afc66f..a9ef856 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
language: node_js
node_js:
-- '5'
+- '8'
before_install:
- npm install -g codeclimate-test-reporter
script: npm test -- --browsers PhantomJS
diff --git a/examples/systemjs/app/data-filter.pipe.ts b/examples/systemjs/app/data-filter.pipe.ts
index b165732..0469335 100644
--- a/examples/systemjs/app/data-filter.pipe.ts
+++ b/examples/systemjs/app/data-filter.pipe.ts
@@ -1,4 +1,3 @@
-import * as _ from "lodash";
import {Pipe, PipeTransform} from "@angular/core";
@Pipe({
@@ -8,7 +7,7 @@ export class DataFilterPipe implements PipeTransform {
transform(array: any[], query: string): any {
if (query) {
- return _.filter(array, row=>row.name.indexOf(query) > -1);
+ return array.filter(row=>row.name.indexOf(query) > -1);
}
return array;
}
diff --git a/karma.conf.js b/karma.conf.js
index 4ad00c8..ccd7f22 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -68,13 +68,6 @@ module.exports = function (config) {
watched: false
},
- // Lodash
- {
- pattern: 'node_modules/lodash/lodash.js',
- included: false,
- watched: false
- },
-
// The testing library
{
pattern: 'systemjs.config.js',
diff --git a/package.json b/package.json
index fe69d9f..a865ebc 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "angular2-datatable",
- "version": "0.6.0",
+ "version": "2.0.0",
"description": "DataTable component for Angular2 framework",
"main": "index.js",
"scripts": {
@@ -19,8 +19,7 @@
},
"keywords": [
"angular",
- "angularjs",
- "angular2",
+ "angular6",
"ng",
"ng2",
"table",
@@ -35,12 +34,13 @@
},
"homepage": "https://github.com/mariuszfoltak/angular2-datatable#readme",
"devDependencies": {
- "@angular/core": "^2.1.0",
- "@angular/compiler": "^2.1.0",
- "@angular/common": "^2.1.0",
- "@angular/platform-browser": "^2.1.0",
- "@angular/platform-browser-dynamic": "^2.1.0",
- "@angular/compiler-cli": "^2.1.0",
+ "@angular/common": "^6.0.0",
+ "@angular/compiler": "^6.0.0",
+ "@angular/compiler-cli": "^6.0.0",
+ "@angular/core": "^6.0.0",
+ "@angular/platform-browser": "^6.0.0",
+ "@angular/platform-browser-dynamic": "^6.0.0",
+ "@types/jasmine": "^2.5.35",
"core-js": "^2.4.1",
"http-server": "^0.9.0",
"jasmine-core": "^2.4.1",
@@ -49,24 +49,18 @@
"karma-coverage": "^1.1.1",
"karma-jasmine": "^1.0.2",
"karma-phantomjs-launcher": "^1.0.2",
- "lodash": "^4.0.0",
"phantomjs-prebuilt": "^2.1.7",
"remap-istanbul": "^0.7.0",
- "rxjs": "5.0.0-beta.12",
- "systemjs": "^0.19.39",
- "typescript": "~2.1.0",
- "zone.js": "^0.6.25",
"rimraf": "^2.5.4",
- "@types/lodash": "ts2.0",
- "@types/jasmine": "^2.5.35"
- },
- "dependencies": {
- "lodash": "^4.0.0"
+ "rxjs": "^6.0.0",
+ "systemjs": "^0.19.47",
+ "typescript": "~2.7.2",
+ "zone.js": "^0.6.25"
},
"peerDependencies": {
- "@angular/core": "^2.0.0",
- "@angular/common": "^2.0.0",
- "@angular/platform-browser": "^2.0.0",
- "rxjs": "^5.0.0-beta.12"
+ "@angular/core": "^6.0.0",
+ "@angular/common": "^6.0.0",
+ "@angular/platform-browser": "^6.0.0",
+ "rxjs": "^6.0.0"
}
}
diff --git a/src/BootstrapPaginator.ts b/src/BootstrapPaginator.ts
index 435ce0e..dccd42a 100644
--- a/src/BootstrapPaginator.ts
+++ b/src/BootstrapPaginator.ts
@@ -1,6 +1,5 @@
import {Component, Input, OnChanges} from "@angular/core";
import {DataTable} from "./DataTable";
-import * as _ from "lodash";
@Component({
selector: "mfBootstrapPaginator",
@@ -57,7 +56,7 @@ export class BootstrapPaginator implements OnChanges {
ngOnChanges(changes: any): any {
if (changes.rowsOnPageSet) {
- this.minRowsOnPage = _.min(this.rowsOnPageSet)
+ this.minRowsOnPage = this.rowsOnPageSet.reduce((previous, current) => current < previous ? current : previous);
}
}
}
\ No newline at end of file
diff --git a/src/DataTable.spec.ts b/src/DataTable.spec.ts
index b58a52d..3b00332 100644
--- a/src/DataTable.spec.ts
+++ b/src/DataTable.spec.ts
@@ -3,7 +3,8 @@ import {SimpleChange, Component} from "@angular/core";
import {DataTable, PageEvent, SortEvent} from "./DataTable";
import {TestBed, ComponentFixture} from "@angular/core/testing";
import {By} from "@angular/platform-browser";
-import * as _ from "lodash";
+import {switchMap} from 'rxjs/operators';
+import {range} from "rxjs";
@Component({
template: `
`
@@ -29,13 +30,13 @@ describe("DataTable directive tests", ()=> {
{id: 5, name: 'Ðrone'},
{id: 4, name: 'Ananas'}
];
- datatable.ngOnChanges({inputData: new SimpleChange(null, datatable.inputData)});
+ datatable.ngOnChanges({inputData: new SimpleChange(null, datatable.inputData, false)});
});
describe("initializing", ()=> {
it("data should be empty array if inputData is undefined or null", () => {
- datatable.ngOnChanges({inputData: new SimpleChange(null, null)});
+ datatable.ngOnChanges({inputData: new SimpleChange(null, null, false)});
datatable.ngDoCheck();
expect(datatable.data).toEqual([]);
});
@@ -108,12 +109,19 @@ describe("DataTable directive tests", ()=> {
});
datatable.rowsOnPage = 3;
- datatable.ngOnChanges({rowsOnPage: new SimpleChange(2, 3)});
+ datatable.ngOnChanges({rowsOnPage: new SimpleChange(2, 3, false)});
datatable.ngDoCheck();
expect(datatable.data).toEqual([{id: 3, name: 'banana'}, {id: 1, name: 'Duck'}, {id: 2, name: 'ącki'}]);
-
-
});
+
+ it("should emit a dataLength of 0 when inputData is null or undefined", (done) => {
+ datatable.onPageChange.subscribe((pageOptions: PageEvent)=> {
+ expect(pageOptions.dataLength).toEqual(0);
+ done();
+ });
+ datatable.inputData = null;
+ datatable.setPage(2, 3);
+ })
});
describe("sorting", ()=> {
@@ -128,8 +136,8 @@ describe("DataTable directive tests", ()=> {
datatable.sortBy = "id";
datatable.sortOrder = "asc";
datatable.ngOnChanges({
- sortBy: new SimpleChange(null, datatable.sortBy),
- sortOrder: new SimpleChange(null, datatable.sortOrder)
+ sortBy: new SimpleChange(null, datatable.sortBy, false),
+ sortOrder: new SimpleChange(null, datatable.sortOrder, false)
});
datatable.ngDoCheck();
expect(datatable.data).toEqual([
@@ -151,8 +159,8 @@ describe("DataTable directive tests", ()=> {
datatable.sortBy = "id";
datatable.sortOrder = "desc";
datatable.ngOnChanges({
- sortBy: new SimpleChange(null, datatable.sortBy),
- sortOrder: new SimpleChange(null, datatable.sortOrder)
+ sortBy: new SimpleChange(null, datatable.sortBy, false),
+ sortOrder: new SimpleChange(null, datatable.sortOrder, false)
});
datatable.ngDoCheck();
@@ -167,7 +175,7 @@ describe("DataTable directive tests", ()=> {
datatable.ngDoCheck();
datatable.sortBy = "id";
datatable.ngOnChanges({
- sortBy: new SimpleChange(null, datatable.sortBy)
+ sortBy: new SimpleChange(null, datatable.sortBy, false)
});
datatable.ngDoCheck();
expect(datatable.sortOrder).toEqual("asc");
@@ -181,10 +189,10 @@ describe("DataTable directive tests", ()=> {
});
datatable.ngDoCheck();
datatable.sortBy = "id";
- datatable.sortOrder = "bulb";
+ datatable.sortOrder = "bulb" as any;
datatable.ngOnChanges({
- sortBy: new SimpleChange(null, datatable.sortBy),
- sortOrder: new SimpleChange(null, datatable.sortOrder)
+ sortBy: new SimpleChange(null, datatable.sortBy, false),
+ sortOrder: new SimpleChange(null, datatable.sortOrder, false)
});
datatable.ngDoCheck();
expect(datatable.sortOrder).toEqual("asc");
@@ -197,6 +205,20 @@ describe("DataTable directive tests", ()=> {
]);
});
+ it("should set sortOrder to 'asc' if setSort is given something else than 'asc' or 'desc'", () => {
+ datatable.setSort("id", "bulb" as any);
+ expect(datatable.getSort()).toEqual({sortBy: "id", sortOrder: "asc"});
+ datatable.ngDoCheck();
+ expect(datatable.sortOrder).toEqual("asc");
+ expect(datatable.data).toEqual([
+ {id: 1, name: 'Duck'},
+ {id: 2, name: 'ącki'},
+ {id: 3, name: 'banana'},
+ {id: 4, name: 'Ananas'},
+ {id: 5, name: 'Ðrone'}
+ ]);
+ });
+
it("shouldn't change order when only order provided", (done)=> {
done();
datatable.onSortChange.subscribe(()=> {
@@ -204,17 +226,19 @@ describe("DataTable directive tests", ()=> {
});
datatable.ngDoCheck();
datatable.sortOrder = "desc";
- datatable.ngOnChanges({sortOrder: new SimpleChange(null, datatable.sortOrder)});
+ datatable.ngOnChanges({sortOrder: new SimpleChange(null, datatable.sortOrder, false)});
datatable.ngDoCheck();
expect(datatable.data).toEqual(datatable.inputData);
});
it("should call output event when sorting changed", (done)=> {
datatable.ngDoCheck();
- datatable.sortByChange.switchMap((sortBy: string)=> {
- expect(sortBy).toEqual("id");
- return datatable.sortOrderChange;
- }).subscribe((sortOrder: string)=> {
+ datatable.sortByChange.pipe(
+ switchMap((sortBy: string)=> {
+ expect(sortBy).toEqual("id");
+ return datatable.sortOrderChange;
+ })
+ ).subscribe((sortOrder: string)=> {
expect(sortOrder).toEqual("desc");
done();
});
@@ -228,8 +252,8 @@ describe("DataTable directive tests", ()=> {
done.fail("Shouldn't call sortOrderChange");
});
done();
- datatable.sortOrder = "bulb";
- datatable.ngOnChanges({sortOrder: new SimpleChange(null, datatable.sortOrder)});
+ datatable.sortOrder = "bulb" as any;
+ datatable.ngOnChanges({sortOrder: new SimpleChange(null, datatable.sortOrder, false)});
datatable.ngDoCheck();
});
// Wywołanie outputa gdy zmiana z innej strony
@@ -272,14 +296,16 @@ describe("DataTable directive tests", ()=> {
{name: 'Claire', age: 9},
{name: 'Anna', age: 34},
{name: 'Claire', age: 16},
+ {name: 'Anna', age: 12},
{name: 'Claire', age: 7},
{name: 'Anna', age: 12}
];
- datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData)});
+ datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData, false)});
datatable.setSort(['name', 'age'], "asc");
datatable.ngDoCheck();
expect(datatable.data).toEqual([
+ {name: 'Anna', age: 12},
{name: 'Anna', age: 12},
{name: 'Anna', age: 34},
{name: 'Claire', age: 7},
@@ -297,7 +323,7 @@ describe("DataTable directive tests", ()=> {
{name: 'Claire', city: {zip: '11111'}},
{name: 'Anna', city: {zip: '21111'}}
];
- datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData)});
+ datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData, false)});
datatable.setSort("city.zip", "asc");
datatable.ngDoCheck();
@@ -315,7 +341,7 @@ describe("DataTable directive tests", ()=> {
describe("data change", ()=> {
it("should refresh data when inputData change", ()=> {
let newData = [{id: 5, name: 'Ðrone'}, {id: 4, name: 'Ananas'}];
- datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData)});
+ datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData, false)});
datatable.ngDoCheck();
expect(datatable.data).toEqual([{id: 5, name: 'Ðrone'}, {id: 4, name: 'Ananas'}]);
});
@@ -347,7 +373,7 @@ describe("DataTable directive tests", ()=> {
done();
});
let newData = [{id: 5, name: 'Ðrone'}, {id: 4, name: 'Ananas'}];
- datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData)});
+ datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData, false)});
datatable.ngDoCheck();
});
@@ -375,7 +401,7 @@ describe("DataTable directive tests", ()=> {
expect(opt.rowsOnPage).toEqual(2);
done();
});
- _.times(3, ()=>datatable.inputData.pop());
+ range(0, 3).forEach(()=>datatable.inputData.pop());
datatable.ngDoCheck();
});
@@ -384,7 +410,7 @@ describe("DataTable directive tests", ()=> {
datatable.ngDoCheck();
let newData = [{id: 5, name: 'Ðrone'}, {id: 4, name: 'Ananas'}];
- datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData)});
+ datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData, false)});
datatable.ngDoCheck();
expect(datatable.data).toEqual(newData);
});
@@ -406,7 +432,7 @@ describe("DataTable directive tests", ()=> {
datatable.ngDoCheck();
let newData = [{id: 5, name: 'Ðrone'}, {id: 1, name: 'Duck'}, {id: 4, name: 'Ananas'}];
- datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData)});
+ datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData, false)});
datatable.ngDoCheck();
expect(datatable.data).toEqual([{id: 1, name: 'Duck'}]);
});
@@ -436,7 +462,7 @@ describe("DataTable directive tests", ()=> {
datatable.ngDoCheck();
let newData = [];
- datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData)});
+ datatable.ngOnChanges({inputData: new SimpleChange(datatable.inputData, newData, false)});
datatable.ngDoCheck();
expect(datatable.activePage).toEqual(1);
});
@@ -445,7 +471,7 @@ describe("DataTable directive tests", ()=> {
datatable.setPage(2, 1);
datatable.ngDoCheck();
- _.times(5, ()=>datatable.inputData.pop());
+ range(0, 5).forEach(()=>datatable.inputData.pop());
datatable.ngDoCheck();
expect(datatable.inputData.length).toEqual(0);
expect(datatable.activePage).toEqual(1);
diff --git a/src/DataTable.ts b/src/DataTable.ts
index 1232241..3e8efc6 100644
--- a/src/DataTable.ts
+++ b/src/DataTable.ts
@@ -2,12 +2,11 @@ import {
Directive, Input, EventEmitter, SimpleChange, OnChanges, DoCheck, IterableDiffers,
IterableDiffer, Output
} from "@angular/core";
-import * as _ from "lodash";
-import {ReplaySubject} from "rxjs/Rx";
+import { ReplaySubject } from "rxjs";
export interface SortEvent {
sortBy: string|string[];
- sortOrder: string
+ sortOrder: SortOrder
}
export interface PageEvent {
@@ -20,17 +19,19 @@ export interface DataEvent {
length: number;
}
+export type SortOrder = "asc" | "desc";
+
@Directive({
- selector: 'table[mfData]',
- exportAs: 'mfDataTable'
+ selector: "table[mfData]",
+ exportAs: "mfDataTable"
})
export class DataTable implements OnChanges, DoCheck {
- private diff: IterableDiffer;
+ private diff: IterableDiffer;
@Input("mfData") public inputData: any[] = [];
@Input("mfSortBy") public sortBy: string|string[] = "";
- @Input("mfSortOrder") public sortOrder = "asc";
+ @Input("mfSortOrder") public sortOrder: SortOrder = "asc";
@Output("mfSortByChange") public sortByChange = new EventEmitter();
@Output("mfSortOrderChange") public sortOrderChange = new EventEmitter();
@@ -52,12 +53,12 @@ export class DataTable implements OnChanges, DoCheck {
return {sortBy: this.sortBy, sortOrder: this.sortOrder};
}
- public setSort(sortBy: string|string[], sortOrder: string): void {
+ public setSort(sortBy: string|string[], sortOrder: SortOrder): void {
if (this.sortBy !== sortBy || this.sortOrder !== sortOrder) {
this.sortBy = sortBy;
- this.sortOrder = _.includes(["asc","desc"], sortOrder) ? sortOrder : "asc";
+ this.sortOrder = ["asc","desc"].indexOf(sortOrder) >= 0 ? sortOrder : "asc";
this.mustRecalculateData = true;
- this.onSortChange.next({sortBy: sortBy, sortOrder: sortOrder});
+ this.onSortChange.next({sortBy: this.sortBy, sortOrder: this.sortOrder});
this.sortByChange.emit(this.sortBy);
this.sortOrderChange.emit(this.sortOrder);
}
@@ -81,13 +82,13 @@ export class DataTable implements OnChanges, DoCheck {
}
private calculateNewActivePage(previousRowsOnPage: number, currentRowsOnPage: number): number {
- let firstRowOnPage = (this.activePage - 1) * previousRowsOnPage + 1;
- let newActivePage = Math.ceil(firstRowOnPage / currentRowsOnPage);
+ const firstRowOnPage = (this.activePage - 1) * previousRowsOnPage + 1;
+ const newActivePage = Math.ceil(firstRowOnPage / currentRowsOnPage);
return newActivePage;
}
private recalculatePage() {
- let lastPage = Math.ceil(this.inputData.length / this.rowsOnPage);
+ const lastPage = Math.ceil(this.inputData.length / this.rowsOnPage);
this.activePage = lastPage < this.activePage ? lastPage : this.activePage;
this.activePage = this.activePage || 1;
@@ -105,7 +106,7 @@ export class DataTable implements OnChanges, DoCheck {
this.mustRecalculateData = true;
}
if (changes["sortBy"] || changes["sortOrder"]) {
- if (!_.includes(["asc", "desc"], this.sortOrder)) {
+ if (["asc", "desc"].indexOf(this.sortOrder) < 0) {
console.warn("angular2-datatable: value for input mfSortOrder must be one of ['asc', 'desc'], but is:", this.sortOrder);
this.sortOrder = "asc";
}
@@ -122,7 +123,7 @@ export class DataTable implements OnChanges, DoCheck {
}
public ngDoCheck(): any {
- let changes = this.diff.diff(this.inputData);
+ const changes = this.diff.diff(this.inputData);
if (changes) {
this.recalculatePage();
this.mustRecalculateData = true;
@@ -134,33 +135,51 @@ export class DataTable implements OnChanges, DoCheck {
}
private fillData(): void {
- this.activePage = this.activePage;
- this.rowsOnPage = this.rowsOnPage;
-
- let offset = (this.activePage - 1) * this.rowsOnPage;
+ const offset = (this.activePage - 1) * this.rowsOnPage;
let data = this.inputData;
- var sortBy = this.sortBy;
- if (typeof sortBy === 'string' || sortBy instanceof String) {
- data = _.orderBy(data, this.caseInsensitiveIteratee(sortBy), [this.sortOrder]);
- } else {
- data = _.orderBy(data, sortBy, [this.sortOrder]);
- }
- data = _.slice(data, offset, offset + this.rowsOnPage);
+ data = [...data].sort(this.sorter(this.sortBy, this.sortOrder));
+ data = data.slice(offset, offset + this.rowsOnPage);
this.data = data;
}
private caseInsensitiveIteratee(sortBy: string) {
return (row: any): any => {
- var value = row;
- for (let sortByProperty of sortBy.split('.')) {
- if(value) {
+ let value = row;
+ for (const sortByProperty of sortBy.split(".")) {
+ if (value) {
value = value[sortByProperty];
}
}
- if (value && typeof value === 'string' || value instanceof String) {
+ if (value && typeof value === "string" || value instanceof String) {
return value.toLowerCase();
}
return value;
};
}
+
+ private compare(left: any, right: any): number {
+ return left === right ? 0 : left == null || left > right ? 1 : -1;
+ }
+
+ private sorter(sortBy: string | string[], sortOrder: string): (left: T, right: T) => number {
+ const order = sortOrder === "desc" ? -1 : 1;
+ if (typeof sortBy === "string" || sortBy instanceof String) {
+ const iteratee = this.caseInsensitiveIteratee(sortBy as string);
+ return (left, right) => {
+ return this.compare(iteratee(left), iteratee(right)) * order;
+ };
+ } else {
+ const iteratees = sortBy.map(entry => this.caseInsensitiveIteratee(entry));
+ return (left, right) => {
+ for (const iteratee of iteratees) {
+ const comparison = this.compare(iteratee(left), iteratee(right)) * order;
+ if (comparison !== 0) {
+ return comparison;
+ }
+ }
+ return 0;
+ };
+ }
+ }
+
}
\ No newline at end of file
diff --git a/systemjs.config.js b/systemjs.config.js
index a9338a2..be9a292 100644
--- a/systemjs.config.js
+++ b/systemjs.config.js
@@ -22,7 +22,7 @@
// other libraries
'rxjs': 'npm:rxjs',
- 'lodash': 'npm:lodash/lodash.js'
+ 'rxjs/operators': 'npm:rxjs/operators',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
@@ -30,7 +30,12 @@
defaultExtension: 'js'
},
rxjs: {
- defaultExtension: 'js'
+ defaultExtension: 'js',
+ main: 'index.js'
+ },
+ 'rxjs/operators': {
+ defaultExtension: 'js',
+ main: 'index.js'
}
}
});