summaryrefslogtreecommitdiffstats
path: root/grid/src
diff options
context:
space:
mode:
authorivarlovlie <git@ivarlovlie.no>2020-11-17 21:53:08 +0100
committerivarlovlie <git@ivarlovlie.no>2020-11-17 21:53:08 +0100
commit95ab7c19fff815de0007be3268e2fb00132980e7 (patch)
tree32b7c5d8aff80fbafc72a02af401b96b14eddf71 /grid/src
parent9b6223d35ce090af1f8ea5d7ee63a629bb2a023f (diff)
downloadweb-components-95ab7c19fff815de0007be3268e2fb00132980e7.tar.xz
web-components-95ab7c19fff815de0007be3268e2fb00132980e7.zip
add support for nested props on dataIds
custom table classes don't render paginator if the data count is less than pagesize
Diffstat (limited to 'grid/src')
-rw-r--r--grid/src/grid.ts63
1 files changed, 49 insertions, 14 deletions
diff --git a/grid/src/grid.ts b/grid/src/grid.ts
index 4623dda..3f59614 100644
--- a/grid/src/grid.ts
+++ b/grid/src/grid.ts
@@ -7,6 +7,7 @@ interface GridProps {
columns: Array<GridColumn>;
pageSize?: number;
search?: SearchConfiguration;
+ tableClassName?: string;
}
interface GridConfiguration {
@@ -16,13 +17,15 @@ interface GridConfiguration {
columns: Array<GridColumn>;
pageSize: number;
search: SearchConfiguration;
+ tableClassName: string;
}
interface SearchConfiguration {
- dataIds: Array<string>;
+ dataIds: Array<string | Array<string>>;
}
+
interface GridColumn {
- dataId?: string;
+ dataId?: string | Array<string>;
columnName: string | Function;
cellValue?: string | Function | Element;
width?: string;
@@ -34,18 +37,19 @@ export default class Grid {
private readonly canRender: boolean;
private readonly defaultOptions: GridConfiguration = {
id: "id",
- debug: true,
+ debug: false,
columns: [],
data: [],
pageSize: 0,
+ tableClassName: "table",
search: {
dataIds: [],
},
};
private configuration: GridConfiguration;
private domElement: Element;
- public currentPage: number = 0;
private searchIndex: JsSearch.Search;
+ public currentPage: number = 0;
constructor(props: GridProps) {
this.setOptions(props);
@@ -67,6 +71,7 @@ export default class Grid {
this.configuration.id = props.id ?? this.defaultOptions.id;
this.configuration.debug = props.debug ?? this.defaultOptions.debug;
this.configuration.pageSize = props.pageSize ?? this.defaultOptions.pageSize;
+ this.configuration.tableClassName = props.tableClassName ?? this.defaultOptions.tableClassName;
this.configuration.search = props.search ?? this.defaultOptions.search;
}
@@ -88,7 +93,7 @@ export default class Grid {
}
private renderPaginator(): void {
- if (this.configuration.pageSize === 0) return;
+ if (this.configuration.pageSize === 0 || this.configuration.data.length < this.configuration.pageSize) return;
const nav = document.createElement("nav");
nav.className = "float-right user-select-none";
const ul = document.createElement("ul");
@@ -134,7 +139,7 @@ export default class Grid {
const wrapper = document.createElement("table");
const thead = document.createElement("thead");
const tbody = document.createElement("tbody");
- wrapper.className = "table";
+ wrapper.className = this.configuration.tableClassName;
wrapper.appendChild(thead);
wrapper.appendChild(tbody);
this.domElement.appendChild(wrapper);
@@ -152,8 +157,26 @@ export default class Grid {
wrapper.appendChild(row);
}
+ // https://github.com/bvaughn/js-search/blob/master/source/getNestedFieldValue.js
+ private getNestedFieldValue<T>(object: Object, path: Array<string>): T {
+ path = path || [];
+ object = object || {};
+
+ let value = object;
+
+ // walk down the property path
+ for (let i = 0; i < path.length; i++) {
+ value = value[path[i]];
+ if (value == null) {
+ return null;
+ }
+ }
+
+ return value as T;
+ }
+
private renderBody(data: Array<Object> = null, isSearchResult: boolean = false): void {
- let wrapper = this.domElement.querySelector("table tbody");
+ let wrapper: Element;
if (isSearchResult) {
this.domElement.querySelector("table tbody:not(.search-results)").classList.add("d-none");
this.domElement.querySelector("table tbody.search-results").classList.remove("d-none");
@@ -170,14 +193,22 @@ export default class Grid {
}
for (const item of items) {
const row = document.createElement("tr");
+ // @ts-ignore
row.dataset.id = item[this.configuration.id];
for (const val of this.configuration.columns) {
const cell = document.createElement("td");
if (val.width) cell.style.width = val.width;
if (val.maxWidth) cell.style.maxWidth = val.maxWidth;
if (val.minWidth) cell.style.minWidth = val.minWidth;
- if (typeof val.dataId === "string" && val.dataId.length > 0) {
- val.cellValue = item[val.dataId];
+ if (val.dataId !== undefined && val.dataId.length > 0) {
+ if (Array.isArray(val.dataId)) {
+ // @ts-ignore
+ val.cellValue = val.dataId;
+ this.log(val.dataId);
+ } else {
+ // @ts-ignore
+ val.cellValue = item[val.dataId];
+ }
}
cell.className = "text-break";
@@ -189,6 +220,8 @@ export default class Grid {
const computed = val.cellValue(item);
if (computed instanceof Element) cell.appendChild(computed);
else if (typeof computed === "string" || typeof computed === "number") cell.innerText = computed as string;
+ } else if (Array.isArray(val.cellValue)) {
+ cell.innerText = this.getNestedFieldValue(item, val.cellValue);
}
row.appendChild(cell);
}
@@ -234,11 +267,10 @@ export default class Grid {
private populateSearchIndex() {
if (this.configuration.search.dataIds.length < 1) return;
- this.searchIndex = new JsSearch.Search("id");
+ this.searchIndex = new JsSearch.Search(this.configuration.id);
this.searchIndex.indexStrategy = new JsSearch.ExactWordIndexStrategy();
this.configuration.search.dataIds.forEach((id) => this.searchIndex.addIndex(id));
this.searchIndex.addDocuments(this.configuration.data);
- console.log(this.searchIndex);
}
public search(query: string): void {
@@ -251,7 +283,7 @@ export default class Grid {
}
}
- public navigate(pageNumber): void {
+ public navigate(pageNumber: number): void {
const maxPage = Math.ceil(this.configuration.data.length / this.configuration.pageSize - 1);
if (this.configuration.pageSize <= 0 || pageNumber < 0 || pageNumber === this.currentPage || pageNumber > maxPage) return;
this.log("Navigating to page: " + pageNumber);
@@ -266,6 +298,7 @@ export default class Grid {
}
public removeByID(id: string): void {
+ // @ts-ignore
const itemIndex = this.configuration.data.findIndex((c) => c[this.configuration.id] === id);
if (itemIndex !== -1) {
delete this.configuration.data[itemIndex];
@@ -275,10 +308,12 @@ export default class Grid {
}
}
- public refreshData(data?: Array<Object>) {
+ public refresh(data?: Array<Object>) {
this.renderPaginator();
this.navigate(0);
- this.renderBody(data);
+ if (data !== undefined) this.configuration.data = data;
+ this.renderBody();
+ this.populateSearchIndex();
}
public render(el: Element): void {