@siberiaweb/components
Version:
272 lines (271 loc) • 9.65 kB
JavaScript
import CustomGrid from "../custom-grid/CustomGrid";
import * as moment from "moment";
/**
* Сетка.
*
* @template TRecord Тип записи.
*/
export default class Grid extends CustomGrid {
/**
* Конструктор.
*/
constructor() {
super();
/**
* Изначальный порядок записей в наборе данных для восстановления сортировки по умолчанию.
*/
this.dataSetInitialOrder = new Map();
/**
* Обработчик сортировки набора данных.
*/
this.onSortDataSet = null;
}
/**
* Функция обратного вызова для сортировки неопределенных значений.
*
* @param a Первое значение.
* @param b Второе значение.
* @param sortOrder Порядок сортировки.
*/
sortNullsCallback(a, b, sortOrder) {
if ((a === null) && (b !== null)) {
return sortOrder === "asc" ? -1 : 1;
}
if ((a !== null) && (b === null)) {
return sortOrder === "asc" ? 1 : -1;
}
return 0;
}
/**
* Функция обратного вызова для восстановления порядка следования записей.
*
* @param a Первая запись.
* @param b Вторая запись.
*/
sortDefaultCallback(a, b) {
let indexA = this.dataSetInitialOrder.get(a);
let indexB = this.dataSetInitialOrder.get(b);
if ((indexA !== undefined) && (indexB !== undefined)) {
return indexA - indexB;
}
return 0;
}
/**
* Функция обратного вызова для сортировки логических значений.
*
* @param a Первая запись.
* @param b Вторая запись.
* @param col Столбец.
*/
sortBooleanCallback(a, b, col) {
if (col.sortOrder === "none") {
return this.sortDefaultCallback(a, b);
}
let booleanA = this.getFieldValue(col, a);
let booleanB = this.getFieldValue(col, b);
if ((booleanA === null) || (booleanB === null)) {
return this.sortNullsCallback(booleanA, booleanB, col.sortOrder);
}
if (booleanA === booleanB) {
return 0;
}
if (booleanA) {
return col.sortOrder === "asc" ? 1 : -1;
}
return col.sortOrder === "desc" ? -1 : 1;
}
/**
* Функция обратного вызова для сортировки чисел.
*
* @param a Первая запись.
* @param b Вторая запись.
* @param col Столбец.
*/
sortNumberCallback(a, b, col) {
if (col.sortOrder === "none") {
return this.sortDefaultCallback(a, b);
}
let numberA = this.getFieldValue(col, a);
let numberB = this.getFieldValue(col, b);
if ((numberA === null) || (numberB === null)) {
return this.sortNullsCallback(numberA, numberB, col.sortOrder);
}
return col.sortOrder === "asc" ? numberA - numberB : numberB - numberA;
}
/**
* Функция обратного вызова для сортировки дат.
*
* @param a Первая запись.
* @param b Вторая запись.
* @param col Столбец.
*/
sortDateCallback(a, b, col) {
if (col.sortOrder === "none") {
return this.sortDefaultCallback(a, b);
}
let dateA = this.getFieldValue(col, a);
let dateB = this.getFieldValue(col, b);
if ((dateA === null) || (dateB === null)) {
return this.sortNullsCallback(dateA, dateB, col.sortOrder);
}
return col.sortOrder === "asc" ? dateA.getTime() - dateB.getTime() : dateB.getTime() - dateA.getTime();
}
/**
* Функция обратного вызова для сортировки дат, представленных в виде строки.
*
* @param a Первая запись.
* @param b Вторая запись.
* @param col Столбец.
* @param pattern Шаблон даты.
*/
sortDateStringCallback(a, b, col, pattern) {
if (col.sortOrder === "none") {
return this.sortDefaultCallback(a, b);
}
let dateA = this.getFieldValue(col, a);
let dateB = this.getFieldValue(col, b);
if ((dateA === null) || (dateB === null)) {
return this.sortNullsCallback(dateA, dateB, col.sortOrder);
}
let momentA = moment(dateA, pattern);
let momentB = moment(dateB, pattern);
return col.sortOrder === "asc" ? momentA.toDate().getTime() - momentB.toDate().getTime() :
momentB.toDate().getTime() - momentA.toDate().getTime();
}
/**
* Функция обратного вызова для сортировки текста.
*
* @param a Первая запись.
* @param b Вторая запись.
* @param col Столбец.
*/
sortTextCallback(a, b, col) {
if (col.sortOrder === "none") {
return this.sortDefaultCallback(a, b);
}
let valueA = this.getFieldValue(col, a);
let valueB = this.getFieldValue(col, b);
if ((valueA === null) || (valueB === null)) {
return this.sortNullsCallback(valueA, valueB, col.sortOrder);
}
if (valueA < valueB) {
return col.sortOrder === "asc" ? -1 : 1;
}
if (valueA > valueB) {
return col.sortOrder === "asc" ? 1 : -1;
}
return 0;
}
/**
* Сортировка набора данных.
*
* @param col Столбец.
*/
sortDataSet(col) {
if ((this.onSortDataSet !== null) && this.onSortDataSet(this.getDataSet(), col)) {
return;
}
switch (col.fieldType) {
case "boolean":
this.getDataSet().sort((a, b) => {
return this.sortBooleanCallback(a, b, col);
});
break;
case "date":
this.getDataSet().sort((a, b) => {
return this.sortDateCallback(a, b, col);
});
break;
case "date-string":
let pattern = col.pattern;
this.getDataSet().sort((a, b) => {
return pattern === null ? this.sortTextCallback(a, b, col) :
this.sortDateStringCallback(a, b, col, pattern);
});
break;
case "number":
this.getDataSet().sort((a, b) => {
return this.sortNumberCallback(a, b, col);
});
break;
default:
this.getDataSet().sort((a, b) => {
return this.sortTextCallback(a, b, col);
});
break;
}
}
/**
* @override
*/
sort(col) {
super.sort(col);
if (col.sortDisabled) {
return;
}
this.sortDataSet(col);
if (!this.scrollTopAfterSortDisabled) {
this.scrollTop = 0;
}
this.renderBody(true);
}
/**
* @override
*/
setDataSet(dataSet) {
super.setDataSet(dataSet);
this.dataSetInitialOrder.clear();
for (let i = 0; i < this.getDataSet().length; i++) {
this.dataSetInitialOrder.set(this.getDataSet()[i], i);
}
if (this.sortCol !== null) {
this.sort(this.sortCol);
}
}
/**
* @override
*/
addDataSet(dataSet) {
let length = this.getDataSet().length;
super.addDataSet(dataSet);
for (let i = length; i < this.getDataSet().length; i++) {
this.dataSetInitialOrder.set(this.getDataSet()[i], i);
}
}
/**
* @override
*/
addRecord(record) {
super.addRecord(record);
this.dataSetInitialOrder.set(record, this.getDataSet().length - 1);
}
/**
* @override
*/
removeRecord(record) {
super.removeRecord(record);
this.dataSetInitialOrder.delete(record);
}
/**
* Получение признака отключения прокрутки в начало сетки после сортировки.
*/
get scrollTopAfterSortDisabled() {
return this.hasAttribute(Grid.ATTR_SCROLL_TOP_AFTER_SORT_DISABLED);
}
/**
* Установка признака отключения прокрутки в начало сетки после сортировки.
*
* @param value Значение.
*/
set scrollTopAfterSortDisabled(value) {
this.toggleAttribute(Grid.ATTR_SCROLL_TOP_AFTER_SORT_DISABLED, value);
}
}
/**
* Наименование компонента.
*/
Grid.COMPONENT_NAME = "sw-grid";
/**
* Отключение прокрутки в начало таблицы после сортировки.
*/
Grid.ATTR_SCROLL_TOP_AFTER_SORT_DISABLED = "scroll-top-after-sort-disabled";