@codenameryuu/adonis-datatable
Version:
Package server side datatables on AdonisJS 6
175 lines (174 loc) • 6.44 kB
JavaScript
import collect, { Collection } from 'collect.js';
import lodash from 'lodash';
import { DataTableAbstract } from '../datatable_abstract.js';
import Helper from '../utils/helper.js';
export default class ObjectDataTable extends DataTableAbstract {
items;
$offset = 0;
constructor(items) {
super();
this.items = items;
this.$columns = collect(this.items).keys();
}
static canCreate(source) {
return typeof source === 'object' || source instanceof Collection;
}
resolveCallback() {
return this;
}
defaultOrdering() {
const self = this;
const orderable = this.request.orderableColumns();
if (orderable.length) {
this.items = collect(this.items)
.map((data) => Helper.dot(data))
.sort((a, b) => {
for (const value of Object.values(orderable)) {
const column = self.getColumnName(value['column']);
const direction = value['direction'];
let first;
let second;
let cmp = 0;
if (direction === 'desc') {
first = b;
second = a;
}
else {
first = a;
second = b;
}
if (Number.isInteger(first[column] ?? null) &&
Number.isInteger(second[column] ?? null)) {
if (first[column] < second[column]) {
cmp = -1;
}
else if (first[column] > second[column]) {
cmp = 1;
}
}
else if (self.config.isCaseInsensitive()) {
const collator = new Intl.Collator(undefined, { sensitivity: 'base', numeric: true });
cmp = collator.compare(first[column], second[column]);
}
else {
const collator = new Intl.Collator(undefined, {
sensitivity: 'variant',
numeric: true,
});
cmp = collator.compare(first[column], second[column]);
}
return cmp;
}
return 0;
})
.map((data) => {
for (const [index, value] of Object.entries(data)) {
lodash.unset(data, index);
lodash.set(data, index, value);
}
return data;
})
.all();
}
}
revertIndexColumn() {
if (this.$columnDef['index']) {
const indexColumn = this.config.get('datatables.index_column', 'DT_RowIndex');
const index = this.$dataObject ? indexColumn : 0;
let start = this.request.start();
collect(this.items).transform((data) => {
data[index] = ++start;
return data;
});
}
}
async count() {
return collect(this.items).count();
}
async results() {
try {
this.prepareContext();
this.totalRecords = await this.totalCount();
if (this.totalRecords) {
const results = this.dataResults();
const processed = this.processResults(results);
const output = lodash.transform(processed, (result, value, key) => {
if (value) {
result[key] = value;
}
});
this.items = collect(output).all();
this.ordering();
await this.filterRecords();
this.paginate();
this.revertIndexColumn();
}
return this.render(collect(this.items).all());
}
catch (error) {
return this.errorResponse(error);
}
}
dataResults() {
return collect(this.items).all();
}
setOffset(offset) {
this.$offset = offset;
return this;
}
columnSearch() {
const self = this;
for (let i = 0, c = this.request.columns().length; i < c; i++) {
const column = this.getColumnName(i);
if (column === null) {
continue;
}
if (!this.request.isColumnSearchable(i) || this.isBlacklisted(column)) {
continue;
}
const regex = this.request.isRegex(i);
const keyword = this.request.columnKeyword(i);
this.items = collect(this.items)
.filter((row) => {
const value = lodash.get(row, column);
if (self.config.isCaseInsensitive()) {
if (regex) {
return new RegExp(keyword, 'i').test(value);
}
return Helper.contains(value.toLowerCase(), keyword.toLowerCase());
}
if (regex) {
return new RegExp(keyword).test(value);
}
return Helper.contains(value, keyword);
})
.all();
}
}
paging() {
const offset = this.request.start() - this.$offset;
const length = this.request.length() > 0 ? this.request.length() : 10;
this.items = collect(this.items).slice(offset, length).all();
}
globalSearch(keyword) {
keyword = this.config.isCaseInsensitive() ? keyword.toLowerCase() : keyword;
this.items = collect(this.items)
.filter((row) => {
for (const index of Object.values(this.request.searchableColumnIndex())) {
const column = this.getColumnName(index);
let value = lodash.get(row, column);
if (typeof value !== 'string') {
continue;
}
else {
value = this.config.isCaseInsensitive() ? value.toLowerCase() : value;
}
if (Helper.contains(value, keyword)) {
return true;
}
}
return false;
})
.all();
}
}