@siberiaweb/components
Version:
459 lines (458 loc) • 13.8 kB
JavaScript
import CSS from "./CSS";
import Icon from "../icon/Icon";
import WebComponent from "@siberiaweb/webcomponent/lib/WebComponent";
/**
* Столбец.
*/
export default class Col extends WebComponent {
/**
* Конструктор.
*/
constructor() {
super();
/**
* Минимальная ширина.
*/
this._minWidth = 0;
/**
* Порядок сортировки.
*/
this._sortOrder = "none";
/**
* Шаблон содержания ячейки.
*/
this.cellContentTemplate = document.createElement("template");
this.cell = this.createCell();
this.resizer = this.createResizer();
this.sortIndicator = this.createSortIndicator();
}
/**
* Наблюдаемые атрибуты.
*/
static get observedAttributes() {
return WebComponent.observedAttributes.concat([
Col.ATTR_CONTENT_ALIGN,
Col.ATTR_CLASS,
Col.ATTR_MIN_WIDTH,
Col.ATTR_RESIZE_DISABLED,
Col.ATTR_SORT_DISABLED
]);
}
/**
* Создание ячейки.
*/
createCell() {
return document.createElement("td");
}
/**
* Создание элемента для изменения ширины столбца.
*/
createResizer() {
let resizer = document.createElement("div");
resizer.classList.add(CSS.COL_RESIZER, CSS.COL_RESIZE_CURSOR);
return resizer;
}
/**
* Создание индикатора сортировки.
*/
createSortIndicator() {
let icon = document.createElement(Icon.COMPONENT_NAME);
icon.classList.add(CSS.SORT_INDICATOR);
return icon;
}
/**
* Обработка изменения атрибута "class".
*/
attrClassChange() {
this.cell.removeAttribute(Col.ATTR_CLASS);
for (let className of this.classList) {
this.cell.classList.add(className);
}
}
/**
* Обработка изменения атрибута "content-align".
*/
attrContentAlignChange() {
this.cell.classList.remove(CSS.CELL_CONTENT_ALIGN_CENTER, CSS.CELL_CONTENT_ALIGN_RIGHT);
switch (this.contentAlign) {
case "center":
this.cell.classList.add(CSS.CELL_CONTENT_ALIGN_CENTER);
break;
case "right":
this.cell.classList.add(CSS.CELL_CONTENT_ALIGN_RIGHT);
break;
}
}
/**
* Обработка изменения атрибута "min-width".
*
* @param newValue Новое значение.
*/
attrMinWidthChange(newValue) {
let value = newValue === null ? 0 : parseInt(newValue);
if (isNaN(value) || (value < 0)) {
value = 0;
}
this._minWidth = value;
if (this.offsetWidth < this.minWidth) {
this.setWidth(this.minWidth);
}
}
/**
* Обработка изменения атрибута "resize-disabled".
*/
attrResizeDisabledChange() {
if (this.resizeDisabled) {
this.resizer.remove();
}
else if (!this.cell.contains(this.resizer)) {
this.cell.appendChild(this.resizer);
}
}
/**
* Обработка изменения атрибута "sort-disabled".
*/
attrSortDisabledChange() {
if (this.sortDisabled) {
this.sortIndicator.remove();
}
else if (!this.cell.contains(this.sortIndicator)) {
this.cell.appendChild(this.sortIndicator);
}
}
/**
* @override
*/
attributeChangedCallback(name, oldValue, newValue) {
super.attributeChangedCallback(name, oldValue, newValue);
switch (name) {
case Col.ATTR_CLASS:
this.attrClassChange();
break;
case Col.ATTR_CONTENT_ALIGN:
this.attrContentAlignChange();
break;
case Col.ATTR_MIN_WIDTH:
this.attrMinWidthChange(newValue);
break;
case Col.ATTR_RESIZE_DISABLED:
this.attrResizeDisabledChange();
break;
case Col.ATTR_SORT_DISABLED:
this.attrSortDisabledChange();
break;
}
}
/**
* @override
*/
firstConnectedCallback() {
super.firstConnectedCallback();
let cellContentTemplate = this.querySelector("template");
if (cellContentTemplate !== null) {
this.cellContentTemplate.content.appendChild(cellContentTemplate.content);
}
else if (this.textContent) {
this.cellContentTemplate.content.append(this.textContent);
}
this.cell.appendChild(this.cellContentTemplate.content.cloneNode(true));
if (!this.resizeDisabled) {
this.cell.appendChild(this.resizer);
}
if (!this.sortDisabled) {
this.cell.appendChild(this.sortIndicator);
}
}
/**
* Получение заголовка.
*/
get caption() {
return this.getAttributeOrDefault(Col.ATTR_CAPTION, "");
}
/**
* Установка заголовка.
*
* @param value Значение.
*/
set caption(value) {
this.setAttribute(Col.ATTR_CAPTION, value);
}
/**
* Получение выравнивания содержания.
*/
get contentAlign() {
switch (this.getAttribute(Col.ATTR_CONTENT_ALIGN)) {
case "center":
return "center";
case "right":
return "right";
default:
return "left";
}
}
/**
* Установка выравнивания.
*/
set contentAlign(value) {
this.setAttribute(Col.ATTR_CONTENT_ALIGN, value);
}
/**
* Получение наименования поля в наборе данных.
*/
get fieldName() {
return this.getAttributeOrDefault(Col.ATTR_FIELD_NAME, "");
}
/**
* Установка наименования поля в наборе данных.
*
* @param value Значение.
*/
set fieldName(value) {
this.setAttribute(Col.ATTR_FIELD_NAME, value);
}
/**
* Получение типа данных поля в наборе данных.
*/
get fieldType() {
switch (this.getAttribute(Col.ATTR_FIELD_TYPE)) {
case "boolean":
return "boolean";
case "date":
return "date";
case "date-string":
return "date-string";
case "number":
return "number";
default:
return "text";
}
}
/**
* Установка типа данных поля в наборе данных.
*/
set fieldType(value) {
this.setAttribute(Col.ATTR_FIELD_TYPE, value);
}
/**
* Получение форматирования при выводе.
*/
get format() {
return this.getAttributeOrDefault(Col.ATTR_FORMAT, "");
}
/**
* Установка форматирования при выводе.
*
* @param value Значение.
*/
set format(value) {
this.setAttribute(Col.ATTR_FORMAT, value);
}
/**
* Получение минимальной ширины.
*/
get minWidth() {
return this._minWidth;
}
/**
* Установка минимальной ширины.
*
* @param value Значение.
*/
set minWidth(value) {
this.setAttribute(Col.ATTR_MIN_WIDTH, value.toString());
}
/**
* Получение наименования.
*/
get name() {
return this.getAttributeOrDefault(Col.ATTR_NAME, "");
}
/**
* Установка наименования.
*
* @param value Значение.
*/
set name(value) {
this.setAttribute(Col.ATTR_NAME, value);
}
/**
* Получение шаблона, описывающего формат данных в наборе данных.
*/
get pattern() {
return this.getAttributeOrDefault(Col.ATTR_PATTERN, "");
}
/**
* Установка шаблона, описывающего формат данных в наборе данных.
*
* @param value Значение.
*/
set pattern(value) {
this.setAttribute(Col.ATTR_PATTERN, value);
}
/**
* Получение признака отключения изменения ширины.
*/
get resizeDisabled() {
return this.hasAttribute(Col.ATTR_RESIZE_DISABLED);
}
/**
* Установка признака отключения изменения ширины.
*
* @param value Значение.
*/
set resizeDisabled(value) {
this.toggleAttribute(Col.ATTR_RESIZE_DISABLED, value);
}
/**
* Получение признака отключения сортировки.
*/
get sortDisabled() {
return this.hasAttribute(Col.ATTR_SORT_DISABLED);
}
/**
* Установка признака отключения сортировки.
*
* @param value Значение.
*/
set sortDisabled(value) {
this.toggleAttribute(Col.ATTR_SORT_DISABLED, value);
}
/**
* Получение порядка сортировки.
*/
get sortOrder() {
return this._sortOrder;
}
/**
* Установка порядка сортировки.
*
* @param value Значение.
*/
set sortOrder(value) {
this._sortOrder = value;
this.cell.classList.remove(CSS.SORT, CSS.SORT_ASC, CSS.SORT_DESC);
if (this._sortOrder === "asc") {
this.cell.classList.add(CSS.SORT, CSS.SORT_ASC);
}
else if (this._sortOrder === "desc") {
this.cell.classList.add(CSS.SORT, CSS.SORT_DESC);
}
}
/**
* Установка следующего порядка сортировки.
*/
setNextSortOrder() {
if (this.sortOrder === "asc") {
this.sortOrder = "desc";
}
else if (this.sortOrder === "desc") {
this.sortOrder = "none";
}
else {
this.sortOrder = "asc";
}
}
/**
* Получение ширины по умолчанию.
*/
getDefaultWidth() {
let defaultWidth = parseInt(this.getAttributeOrDefault(Col.ATTR_DEFAULT_WIDTH, "0"));
if (isNaN(defaultWidth) || (defaultWidth < 0)) {
defaultWidth = 0;
}
return defaultWidth;
}
/**
* Установка ширины столбца в пикселях.
*
* @param value Значение.
*/
setWidth(value) {
if (value < this.minWidth) {
value = this.minWidth;
}
this.cell.style.minWidth = value + "px";
this.cell.style.width = value + "px";
}
/**
* Получение шаблона содержания ячейки.
*/
getCellContentTemplate() {
let template = document.createElement("template");
template.content.appendChild(this.cellContentTemplate.content.cloneNode(true));
return template;
}
/**
* Получение ячейки.
*/
getCell() {
return this.cell;
}
/**
* Получение элемента для изменения размера столбца.
*/
getResizer() {
return this.resizer;
}
}
/**
* Наименование компонента.
*/
Col.COMPONENT_NAME = "sw-grid-col";
/**
* Заголовок.
*/
Col.ATTR_CAPTION = "caption";
/**
* Класс CSS.
*/
Col.ATTR_CLASS = "class";
/**
* Выравнивание содержания.
*/
Col.ATTR_CONTENT_ALIGN = "content-align";
/**
* Ширина по умолчанию.
*/
Col.ATTR_DEFAULT_WIDTH = "default-width";
/**
* Наименование поля в наборе данных.
*/
Col.ATTR_FIELD_NAME = "field-name";
/**
* Тип данных поля в наборе данных.
*/
Col.ATTR_FIELD_TYPE = "field-type";
/**
* Форматирование при выводе.
*/
Col.ATTR_FORMAT = "format";
/**
* Скрытый столбец.
*/
Col.ATTR_HIDDEN = "hidden";
/**
* Минимальная ширина.
*/
Col.ATTR_MIN_WIDTH = "min-width";
/**
* Наименование.
*/
Col.ATTR_NAME = "name";
/**
* Шаблон, описывающий формат данных в наборе данных.
*/
Col.ATTR_PATTERN = "pattern";
/**
* Изменение размера отключено.
*/
Col.ATTR_RESIZE_DISABLED = "resize-disabled";
/**
* Сортировка отключена.
*/
Col.ATTR_SORT_DISABLED = "sort-disabled";
/**
* Тип данных поля по умолчанию.
*/
Col.DEFAULT_FIELD_TYPE = "text";
Col.define(Icon);