2023-01-06 13:40:18 +03:00
|
|
|
import {
|
2023-01-09 18:01:31 +03:00
|
|
|
createBreadCrumb,
|
2023-01-11 17:45:29 +03:00
|
|
|
createInputSearch,
|
2023-01-06 13:40:18 +03:00
|
|
|
createNativeSelect,
|
|
|
|
createNativeSelectOption,
|
2023-01-18 19:40:24 +03:00
|
|
|
} from './components/create-element/create-element';
|
2023-01-09 18:01:31 +03:00
|
|
|
import { ICreateBreadCrumb } from './components/create-element/create-element.interface';
|
2023-01-09 17:57:56 +03:00
|
|
|
|
2023-01-09 16:10:43 +03:00
|
|
|
import {
|
2023-01-10 14:33:09 +03:00
|
|
|
clearSelect,
|
2023-01-09 16:10:43 +03:00
|
|
|
createSelected,
|
2023-01-10 18:12:38 +03:00
|
|
|
customStyles,
|
|
|
|
customStylesFormat,
|
2023-01-09 16:10:43 +03:00
|
|
|
getFormatItem,
|
|
|
|
getSelectText,
|
|
|
|
nativeOptionMultiple,
|
|
|
|
nativeOptionOrdinary,
|
2023-01-18 19:40:24 +03:00
|
|
|
} from './components/utils/utils';
|
2023-01-10 14:33:09 +03:00
|
|
|
import { IDataItem, ISelectedItems } from './components/utils/urils.interface';
|
2023-01-09 17:57:56 +03:00
|
|
|
|
2023-01-10 18:12:38 +03:00
|
|
|
import { ICgSelect, IStyle } from './interfaces/cg-select.interface';
|
2023-01-05 18:21:10 +03:00
|
|
|
import { IItems } from './interfaces/items.interface';
|
2023-01-18 19:40:24 +03:00
|
|
|
import { ru, en } from './language/language';
|
2023-01-11 18:41:33 +03:00
|
|
|
import { ILanguage } from './interfaces/language.interface';
|
2023-01-09 18:01:31 +03:00
|
|
|
|
2023-01-05 18:21:10 +03:00
|
|
|
import './main.scss';
|
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @class Class Description ICgSelect
|
|
|
|
* @description This class implements the functionality of a custom select, with customization capabilities.
|
|
|
|
* @author Ovsyanikov Maxim
|
2023-01-13 15:26:35 +03:00
|
|
|
*/
|
2023-01-06 14:57:14 +03:00
|
|
|
export class CGSelect implements ICgSelect {
|
2023-01-20 18:50:53 +03:00
|
|
|
// Select settings
|
2023-01-13 15:40:11 +03:00
|
|
|
selector?: string;
|
2023-01-05 18:21:10 +03:00
|
|
|
selected?: string;
|
|
|
|
placeholder?: string;
|
|
|
|
items?: IItems[] | string[] | any;
|
|
|
|
darkTheme?: boolean;
|
2023-01-26 19:06:17 +03:00
|
|
|
theme?: string;
|
2023-01-05 18:21:10 +03:00
|
|
|
searchMode?: boolean;
|
|
|
|
closeOnSelect?: boolean;
|
|
|
|
nativeSelectMode?: boolean;
|
|
|
|
listDisplayMode?: boolean;
|
|
|
|
language?: string;
|
|
|
|
lable?: string;
|
2023-01-10 18:12:38 +03:00
|
|
|
styles?: IStyle;
|
2023-01-05 18:21:10 +03:00
|
|
|
event?: string;
|
|
|
|
url?: string;
|
|
|
|
multiselect?: boolean;
|
|
|
|
multiselectTag?: boolean;
|
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Created HTML element.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @type {Element | null}
|
|
|
|
*/
|
2023-01-13 15:40:11 +03:00
|
|
|
private element!: Element | null;
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Created list(ul), with class list.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @type {Element | null | undefined}
|
|
|
|
*/
|
2023-01-13 15:40:11 +03:00
|
|
|
private list!: Element | null;
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Select settings passed when creating an instance of the class.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @type {ICgSelect}
|
|
|
|
*/
|
2023-01-13 15:40:11 +03:00
|
|
|
private options!: ICgSelect;
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Unique Id for elements.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @type {string}
|
|
|
|
*/
|
2023-01-13 15:40:11 +03:00
|
|
|
private randomId!: string;
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Variable for carriage control.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @type {Element | null | undefined}
|
|
|
|
*/
|
2023-01-06 13:40:18 +03:00
|
|
|
private caret: Element | null | undefined;
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Transferred categories.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @type {string}
|
|
|
|
*/
|
2023-01-13 15:40:11 +03:00
|
|
|
private category?: string;
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Selected or an array of selected items from a list.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @type {string[] | string}
|
|
|
|
*/
|
2023-01-13 15:40:11 +03:00
|
|
|
private selectedItems!: string[] | string;
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Array of indexes of selected elements.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @type {number[]}
|
|
|
|
*/
|
2023-01-05 18:21:10 +03:00
|
|
|
private indexes: number[] = [];
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Button, to control the select.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @type {Element | null}
|
|
|
|
*/
|
2023-01-13 15:40:11 +03:00
|
|
|
private btnCntr?: Element | null;
|
2023-01-05 18:21:10 +03:00
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {ICgSelect} setting Object accepting select settings.
|
|
|
|
* @constructor ICgSelect class constructor.
|
|
|
|
* @description The constructor takes an object and renders the select.
|
2023-01-13 15:26:35 +03:00
|
|
|
* @example
|
|
|
|
* options = {
|
2023-01-20 18:50:53 +03:00
|
|
|
* selector: 'Unique selector',
|
|
|
|
selected: 'Selected item',
|
2023-01-13 15:26:35 +03:00
|
|
|
placeholder: '...',
|
|
|
|
lable: '...'
|
|
|
|
items: [string|number|object],
|
|
|
|
darkTheme: true/false,
|
|
|
|
searchMode: true/false,
|
|
|
|
closeOnSelect: true/false,
|
|
|
|
nativeSelectMode: true/false,
|
|
|
|
listDisplayMode: true/false,
|
|
|
|
language: 'ru/en',
|
|
|
|
styles: {
|
|
|
|
head: {
|
|
|
|
background: '...',
|
|
|
|
},
|
|
|
|
list: {...},
|
|
|
|
chips: {...},
|
|
|
|
caret: {...},
|
|
|
|
placeholder: {...},
|
|
|
|
lable: {..},
|
|
|
|
},
|
|
|
|
event: '...',
|
|
|
|
url: 'http/...',
|
|
|
|
multiselect: true/false,
|
|
|
|
multiselectTag: true/false,
|
|
|
|
* }
|
|
|
|
*/
|
2023-01-06 14:57:14 +03:00
|
|
|
constructor(setting: ICgSelect) {
|
2023-01-05 18:21:10 +03:00
|
|
|
this.init(setting);
|
2023-01-05 19:56:07 +03:00
|
|
|
this.render();
|
2023-01-06 14:07:37 +03:00
|
|
|
this.closeSelectClick();
|
2023-01-11 17:45:29 +03:00
|
|
|
this.initEvent();
|
2023-01-05 18:21:10 +03:00
|
|
|
}
|
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
//Getters
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @returns {string[] | string} Returns the selected element(s) as an array / element / null.
|
|
|
|
* @description Getter returning the selected element(s) of the select.
|
2023-01-13 15:26:35 +03:00
|
|
|
*/
|
|
|
|
get value(): string | string[] {
|
|
|
|
return this.selectedItems ?? null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @returns {number | number[]} Returns the indices of the selected element(s) as an array / empty array.
|
|
|
|
* @description A getter that returns the indexes of the selected element(s) of the select.
|
2023-01-13 15:26:35 +03:00
|
|
|
*/
|
|
|
|
get indexesOf(): number | number[] {
|
|
|
|
return this.indexes ?? [];
|
|
|
|
}
|
|
|
|
|
2023-01-06 13:40:18 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* Private method for initializing an instance of the ICgSelect class.
|
2023-01-06 14:07:37 +03:00
|
|
|
* @method init
|
2023-01-06 13:40:18 +03:00
|
|
|
* @member
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
|
|
|
* @param {ISgSelect} setting passed select settings.
|
|
|
|
* @description Private method. General initialization of the select. Obtaining tinctures and converting select elements.
|
2023-01-06 13:40:18 +03:00
|
|
|
* @example
|
|
|
|
* {
|
|
|
|
selector: '.cg-dropdown_one',
|
2023-01-20 18:50:53 +03:00
|
|
|
placeholder: 'Choose a car',
|
2023-01-06 13:40:18 +03:00
|
|
|
items: [
|
|
|
|
'BMW',
|
|
|
|
{
|
|
|
|
id: '213sade',
|
|
|
|
title: 'Opel',
|
|
|
|
value: 1,
|
|
|
|
},
|
|
|
|
'Mersedes',
|
|
|
|
'MAN',
|
|
|
|
'max',
|
|
|
|
],
|
|
|
|
darkTheme: true,
|
|
|
|
multiselect: true,
|
|
|
|
multiselectTag: true,
|
|
|
|
}
|
|
|
|
*/
|
2023-01-06 14:57:14 +03:00
|
|
|
private init(setting: ICgSelect): void {
|
2023-01-12 16:23:49 +03:00
|
|
|
const {
|
|
|
|
items,
|
|
|
|
multiselect,
|
|
|
|
multiselectTag,
|
|
|
|
url,
|
|
|
|
selector,
|
|
|
|
listDisplayMode,
|
|
|
|
nativeSelectMode,
|
|
|
|
searchMode,
|
|
|
|
darkTheme,
|
|
|
|
language,
|
|
|
|
styles,
|
|
|
|
lable,
|
|
|
|
event,
|
|
|
|
selected,
|
2023-01-26 19:06:17 +03:00
|
|
|
placeholder, theme
|
2023-01-12 16:23:49 +03:00
|
|
|
} = setting;
|
2023-01-05 19:56:07 +03:00
|
|
|
|
2023-01-05 18:21:10 +03:00
|
|
|
this.options = setting;
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
this.multiselect = multiselect;
|
|
|
|
this.multiselectTag = multiselectTag;
|
|
|
|
this.url = url;
|
|
|
|
this.selector = selector;
|
|
|
|
this.items = items;
|
|
|
|
this.searchMode = searchMode;
|
|
|
|
this.darkTheme = darkTheme;
|
|
|
|
this.language = language;
|
|
|
|
this.nativeSelectMode = nativeSelectMode;
|
|
|
|
this.listDisplayMode = listDisplayMode;
|
|
|
|
this.styles = styles;
|
|
|
|
this.lable = lable;
|
|
|
|
this.event = event;
|
|
|
|
this.selected = selected;
|
|
|
|
this.placeholder = placeholder;
|
2023-01-26 19:06:17 +03:00
|
|
|
this.theme = theme;
|
2023-01-12 16:23:49 +03:00
|
|
|
|
2023-01-13 15:40:11 +03:00
|
|
|
const elem = document.querySelector(this.selector!);
|
2023-01-05 18:21:10 +03:00
|
|
|
this.element = elem;
|
|
|
|
|
|
|
|
this.element?.addEventListener('click', (e) => {
|
|
|
|
e.preventDefault();
|
2023-01-06 13:40:18 +03:00
|
|
|
this.open();
|
2023-01-05 18:21:10 +03:00
|
|
|
});
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
this.items = [];
|
2023-01-06 13:40:18 +03:00
|
|
|
|
2023-01-17 20:21:43 +03:00
|
|
|
if (this.url && !items) {
|
2023-01-06 13:40:18 +03:00
|
|
|
this.renderUrl();
|
|
|
|
return;
|
2023-01-05 18:21:10 +03:00
|
|
|
}
|
2023-01-17 20:21:43 +03:00
|
|
|
|
2023-01-18 19:40:24 +03:00
|
|
|
if (this.lable) {
|
|
|
|
const lableItem = document.createElement('h1');
|
|
|
|
const textLable = document.createTextNode(this.lable);
|
|
|
|
|
|
|
|
lableItem.appendChild(textLable);
|
|
|
|
lableItem.classList.add('label');
|
|
|
|
|
|
|
|
this.element!.insertAdjacentElement('beforebegin', lableItem);
|
|
|
|
}
|
2023-01-05 18:21:10 +03:00
|
|
|
|
2023-01-06 13:40:18 +03:00
|
|
|
items.forEach((dataItem: any, index: number) => {
|
|
|
|
let itemInputs: IDataItem = {
|
|
|
|
ItemValue: dataItem,
|
2023-01-13 15:26:35 +03:00
|
|
|
category: dataItem.category,
|
|
|
|
categoryItems: dataItem.categoryItems,
|
2023-01-06 13:40:18 +03:00
|
|
|
};
|
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
if (itemInputs.category && itemInputs.categoryItems) {
|
|
|
|
this.category = itemInputs.category!;
|
2023-01-12 16:23:49 +03:00
|
|
|
this.items.push(this.category);
|
2023-01-13 15:40:11 +03:00
|
|
|
itemInputs.categoryItems.forEach(
|
|
|
|
(categoryItem: string | IItems | any, indexCategory: number) => {
|
|
|
|
this.items.push(getFormatItem(categoryItem, indexCategory));
|
|
|
|
},
|
|
|
|
);
|
2023-01-10 18:12:38 +03:00
|
|
|
} else {
|
2023-01-12 16:23:49 +03:00
|
|
|
this.items.push(getFormatItem(itemInputs.ItemValue, index));
|
2023-01-10 18:12:38 +03:00
|
|
|
}
|
2023-01-06 13:40:18 +03:00
|
|
|
});
|
2023-01-05 18:21:10 +03:00
|
|
|
}
|
|
|
|
|
2023-01-06 13:40:18 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
2023-01-06 14:07:37 +03:00
|
|
|
* @method render
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {string} select optional element. Passed to the initSelected.
|
|
|
|
* @description Render elements in select.
|
2023-01-06 13:40:18 +03:00
|
|
|
*/
|
|
|
|
private render(select?: string): void {
|
2023-01-05 19:56:07 +03:00
|
|
|
const random = Math.random().toString(36).substring(2, 10);
|
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
if (select || (select && this.styles)) {
|
2023-01-10 18:12:38 +03:00
|
|
|
this.initSelected(select);
|
2023-01-13 15:26:35 +03:00
|
|
|
customStyles(this.element!, this.styles!);
|
2023-01-10 18:12:38 +03:00
|
|
|
} else {
|
|
|
|
this.initSelected();
|
|
|
|
}
|
2023-01-06 13:40:18 +03:00
|
|
|
|
|
|
|
const ulList = document.createElement('ul');
|
|
|
|
const nativeSelect = createNativeSelect();
|
|
|
|
|
2023-01-11 17:45:29 +03:00
|
|
|
let inputSearch: HTMLInputElement;
|
2023-01-06 13:40:18 +03:00
|
|
|
let textNode: Text;
|
|
|
|
|
|
|
|
this.randomId = random;
|
|
|
|
|
|
|
|
ulList.classList.add('list');
|
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
if (this.styles) {
|
|
|
|
customStylesFormat(this.styles.list!, ulList);
|
2023-01-10 18:12:38 +03:00
|
|
|
}
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.searchMode) {
|
|
|
|
if (this.language === 'ru') {
|
2023-01-11 17:45:29 +03:00
|
|
|
inputSearch = createInputSearch(random, ru.placeholder);
|
|
|
|
} else {
|
|
|
|
inputSearch = createInputSearch(random, en.placeholder);
|
|
|
|
}
|
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
customStylesFormat(this.styles?.search!, inputSearch);
|
2023-01-11 17:45:29 +03:00
|
|
|
ulList.appendChild(inputSearch);
|
|
|
|
}
|
|
|
|
|
2023-01-06 13:40:18 +03:00
|
|
|
this.element?.appendChild(ulList);
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
this.items.forEach((dataItem: IItems | any) => {
|
2023-01-06 13:40:18 +03:00
|
|
|
this.element?.appendChild(nativeSelect);
|
|
|
|
|
|
|
|
const liItem = document.createElement('li');
|
|
|
|
const nativeOption = createNativeSelectOption();
|
|
|
|
const strongItem = document.createElement('strong');
|
|
|
|
|
|
|
|
liItem.classList.add('list__item');
|
|
|
|
strongItem.classList.add('category');
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.multiselect) {
|
2023-01-06 13:40:18 +03:00
|
|
|
const checkBox = document.createElement('input');
|
|
|
|
checkBox.type = 'checkbox';
|
|
|
|
checkBox.setAttribute('id', `chbox-${dataItem.id}`);
|
|
|
|
liItem.appendChild(checkBox);
|
2023-01-05 19:56:07 +03:00
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.multiselectTag) {
|
2023-01-06 13:40:18 +03:00
|
|
|
checkBox.classList.add('displayHide');
|
|
|
|
}
|
|
|
|
|
|
|
|
nativeSelect.setAttribute('multiple', 'multiple');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dataItem.title) {
|
|
|
|
nativeOption.text = dataItem.title;
|
|
|
|
nativeOption.value = dataItem.title;
|
|
|
|
textNode = document.createTextNode(dataItem.title);
|
|
|
|
|
|
|
|
nativeSelect.appendChild(nativeOption);
|
|
|
|
liItem.appendChild(textNode);
|
|
|
|
ulList.appendChild(liItem);
|
|
|
|
} else {
|
|
|
|
// Для отрисовки категорий
|
|
|
|
textNode = document.createTextNode(dataItem);
|
|
|
|
strongItem.appendChild(textNode);
|
|
|
|
ulList.appendChild(strongItem);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
this.items.filter((item: IItems | any, index: number) => {
|
2023-01-10 18:12:38 +03:00
|
|
|
if (typeof item !== 'object') {
|
2023-01-12 16:23:49 +03:00
|
|
|
this.items.splice(index, 1);
|
2023-01-10 18:12:38 +03:00
|
|
|
}
|
2023-01-13 15:26:35 +03:00
|
|
|
|
2023-01-10 18:12:38 +03:00
|
|
|
return item;
|
|
|
|
});
|
|
|
|
|
2023-01-11 17:45:29 +03:00
|
|
|
this.list = this.element!.querySelector('.list');
|
|
|
|
this.caret = this.element!.querySelector('.caret');
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.darkTheme == false) {
|
2023-01-10 18:12:38 +03:00
|
|
|
this.checkTheme();
|
|
|
|
}
|
2023-01-26 19:06:17 +03:00
|
|
|
this.themeCheck();
|
2023-01-10 18:12:38 +03:00
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.nativeSelectMode === true) {
|
|
|
|
this.selectMode(this.nativeSelectMode);
|
2023-01-10 18:12:38 +03:00
|
|
|
}
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.listDisplayMode) {
|
|
|
|
this.displayMode(this.listDisplayMode);
|
2023-01-11 17:45:29 +03:00
|
|
|
}
|
2023-01-06 13:40:18 +03:00
|
|
|
|
2023-01-06 14:07:37 +03:00
|
|
|
this.addOptionsBehaviour();
|
2023-01-05 19:56:07 +03:00
|
|
|
}
|
|
|
|
|
2023-01-10 18:12:38 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
2023-01-10 18:12:38 +03:00
|
|
|
* @method renderUrl
|
2023-01-20 18:50:53 +03:00
|
|
|
* @description Rendering elements in the select passed from the URL and setting them up.
|
2023-01-10 18:12:38 +03:00
|
|
|
*/
|
|
|
|
private async renderUrl() {
|
2023-01-17 20:21:43 +03:00
|
|
|
const response = await fetch(this.url!);
|
2023-01-10 18:12:38 +03:00
|
|
|
const dataUrl = await response.json();
|
|
|
|
|
|
|
|
const nativeSelect = createNativeSelect();
|
|
|
|
|
|
|
|
dataUrl.forEach((dataItem: IItems, index: number) => {
|
|
|
|
const item = {
|
|
|
|
id: dataItem.id,
|
|
|
|
title: dataItem.title,
|
|
|
|
value: index,
|
|
|
|
};
|
|
|
|
|
|
|
|
const ulUrl = this.element!.querySelector('.list');
|
|
|
|
|
|
|
|
const nativeOption = createNativeSelectOption();
|
|
|
|
const liUrl = document.createElement('li');
|
|
|
|
const textUrl = document.createTextNode(item.title);
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.multiselect) {
|
2023-01-10 18:12:38 +03:00
|
|
|
const checkBox = document.createElement('input');
|
|
|
|
checkBox.type = 'checkbox';
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.multiselectTag) {
|
2023-01-10 18:12:38 +03:00
|
|
|
checkBox.classList.add('displayHide');
|
|
|
|
}
|
|
|
|
|
|
|
|
checkBox.setAttribute('id', `chbox-${item.id}`);
|
|
|
|
nativeSelect.setAttribute('multiple', 'multiple');
|
|
|
|
|
|
|
|
liUrl.appendChild(checkBox);
|
|
|
|
}
|
|
|
|
|
|
|
|
liUrl.classList.add('list__item');
|
|
|
|
nativeOption.value = item.title;
|
|
|
|
nativeOption.text = item.title;
|
|
|
|
|
|
|
|
nativeSelect.appendChild(nativeOption);
|
|
|
|
liUrl.appendChild(textUrl);
|
|
|
|
ulUrl!.appendChild(liUrl);
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
this.items.push(item);
|
2023-01-10 18:12:38 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
this.element!.appendChild(nativeSelect);
|
|
|
|
|
2023-01-13 15:40:11 +03:00
|
|
|
this.items.filter((item: IItems | string | any, index: number) => {
|
2023-01-10 18:12:38 +03:00
|
|
|
if (typeof item !== 'object') {
|
2023-01-12 16:23:49 +03:00
|
|
|
this.items.splice(index, 1);
|
2023-01-10 18:12:38 +03:00
|
|
|
}
|
|
|
|
return item;
|
|
|
|
});
|
|
|
|
|
|
|
|
this.addOptionsBehaviour();
|
|
|
|
}
|
2023-01-05 19:56:07 +03:00
|
|
|
|
2023-01-06 13:40:18 +03:00
|
|
|
/**
|
2023-01-06 14:07:37 +03:00
|
|
|
* @method initSelected
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {string} select optional element. Used in the selectedIndex method.
|
|
|
|
* @description Renders and styles the select.
|
|
|
|
* @private
|
2023-01-06 13:40:18 +03:00
|
|
|
*/
|
|
|
|
private initSelected(select?: string): void {
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.selected) {
|
2023-01-13 15:26:35 +03:00
|
|
|
createSelected(this.element!, this.selected);
|
2023-01-12 16:23:49 +03:00
|
|
|
} else if (this.placeholder) {
|
2023-01-13 15:26:35 +03:00
|
|
|
createSelected(this.element!, this.placeholder);
|
2023-01-05 19:56:07 +03:00
|
|
|
} else {
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.language && this.language === 'ru') {
|
2023-01-13 15:26:35 +03:00
|
|
|
createSelected(this.element!, ru.selectPlaceholder);
|
2023-01-10 18:12:38 +03:00
|
|
|
} else {
|
2023-01-13 15:26:35 +03:00
|
|
|
createSelected(this.element!, en.selectPlaceholder);
|
2023-01-10 18:12:38 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (select) {
|
2023-01-13 15:26:35 +03:00
|
|
|
createSelected(this.element!, select, this.styles);
|
2023-01-10 18:12:38 +03:00
|
|
|
}
|
|
|
|
|
2023-01-13 15:26:35 +03:00
|
|
|
if (this.styles) {
|
|
|
|
customStyles(this.element!, this.styles);
|
2023-01-05 19:56:07 +03:00
|
|
|
}
|
|
|
|
}
|
2023-01-06 13:40:18 +03:00
|
|
|
|
2023-01-11 17:45:29 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
|
|
|
* @description Opens and closes the list by the passed event.
|
2023-01-11 17:45:29 +03:00
|
|
|
* @method initEvent
|
|
|
|
*/
|
|
|
|
private initEvent() {
|
2023-01-12 16:23:49 +03:00
|
|
|
if (!this.event) {
|
2023-01-11 17:45:29 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.event) {
|
|
|
|
if (this.event === 'mouseenter') {
|
|
|
|
this.element!.addEventListener(this.event, () => {
|
2023-01-11 17:45:29 +03:00
|
|
|
this.open();
|
|
|
|
});
|
|
|
|
this.element!.addEventListener('mouseleave', () => {
|
|
|
|
this.close();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-06 13:40:18 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
|
|
|
* @param {boolean} oneClick optional parameter passed from the buttonControl function.
|
|
|
|
* @description Opens a list to select an element.
|
2023-01-06 14:07:37 +03:00
|
|
|
* @method open
|
2023-01-06 13:40:18 +03:00
|
|
|
*/
|
|
|
|
private open(oneClick?: boolean): void {
|
|
|
|
if (oneClick === true) {
|
2023-01-12 16:23:49 +03:00
|
|
|
this.list!.classList.add('open');
|
|
|
|
this.caret!.classList.add('caret_rotate');
|
2023-01-06 13:40:18 +03:00
|
|
|
} else {
|
2023-01-12 16:23:49 +03:00
|
|
|
this.list!.classList.toggle('open');
|
|
|
|
this.caret!.classList.toggle('caret_rotate');
|
2023-01-06 13:40:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-06 14:07:37 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
|
|
|
* @description Closes the list.
|
2023-01-10 18:12:38 +03:00
|
|
|
* @method close
|
2023-01-06 14:07:37 +03:00
|
|
|
*/
|
2023-01-09 16:10:43 +03:00
|
|
|
private close(): void {
|
2023-01-06 14:07:37 +03:00
|
|
|
this.list?.classList.remove('open');
|
|
|
|
this.caret?.classList.remove('caret_rotate');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
|
|
|
* @description Closes the list on click outside of an element.
|
2023-01-06 14:57:14 +03:00
|
|
|
* @method closeSelectClick
|
2023-01-06 14:07:37 +03:00
|
|
|
*/
|
2023-01-09 16:10:43 +03:00
|
|
|
private closeSelectClick(): void {
|
2023-01-06 14:07:37 +03:00
|
|
|
const dropdown = document.querySelector(`${this.options.selector}`);
|
|
|
|
|
|
|
|
document.addEventListener('click', (e) => {
|
|
|
|
const withinBoundaries = e.composedPath().includes(dropdown!);
|
|
|
|
if (!withinBoundaries) {
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.btnCntr) {
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
this.close();
|
|
|
|
}
|
2023-01-06 14:07:37 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
|
|
|
* @description A method that implements the selection of elements in different modes.
|
2023-01-06 14:07:37 +03:00
|
|
|
* @method addOptionsBehaviour
|
|
|
|
*/
|
|
|
|
private addOptionsBehaviour() {
|
|
|
|
const options = this.element?.querySelectorAll('.list__item');
|
2023-01-06 21:14:16 +03:00
|
|
|
const select: HTMLElement | null | undefined = this.element?.querySelector('.selected');
|
2023-01-10 14:33:09 +03:00
|
|
|
const nativeOption = this.element!.querySelectorAll('.nativeSelect__nativeOption');
|
2023-01-06 14:07:37 +03:00
|
|
|
|
2023-01-17 20:21:43 +03:00
|
|
|
let selectedItemsClear: ISelectedItems = {
|
|
|
|
placeholder: this.placeholder!,
|
|
|
|
selected: this.selected!,
|
|
|
|
};
|
2023-01-09 16:10:43 +03:00
|
|
|
|
2023-01-06 14:07:37 +03:00
|
|
|
const ulMultipul = document.createElement('ul');
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.multiselect) {
|
2023-01-09 16:10:43 +03:00
|
|
|
this.selectedItems = [];
|
2023-01-06 14:07:37 +03:00
|
|
|
ulMultipul.classList.add('multiselect-tag');
|
|
|
|
select?.classList.add('overflow-hidden');
|
|
|
|
}
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.searchMode) {
|
2023-01-11 17:45:29 +03:00
|
|
|
this.searchModeSelect(this.randomId);
|
|
|
|
}
|
|
|
|
|
2023-01-06 14:07:37 +03:00
|
|
|
options?.forEach((option: Element, index: number) => {
|
|
|
|
option.addEventListener('click', (event) => {
|
2023-01-10 14:33:09 +03:00
|
|
|
if (Array.isArray(this.selectedItems)) {
|
|
|
|
selectedItemsClear = {
|
2023-01-12 16:23:49 +03:00
|
|
|
placeholder: this.placeholder!,
|
|
|
|
selected: this.selected!,
|
2023-01-10 14:33:09 +03:00
|
|
|
selectedItems: this.selectedItems,
|
|
|
|
indexes: this.indexes,
|
2023-01-12 16:23:49 +03:00
|
|
|
darkTheme: this.darkTheme,
|
|
|
|
multiselectTag: this.multiselectTag,
|
2023-01-10 14:33:09 +03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
const item: IItems = this.items[index];
|
2023-01-09 16:10:43 +03:00
|
|
|
|
2023-01-06 14:07:37 +03:00
|
|
|
const checkIndex = this.indexes.indexOf(index);
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.closeOnSelect == false || this.multiselect) {
|
2023-01-06 21:14:16 +03:00
|
|
|
event.stopPropagation();
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.multiselect) {
|
2023-01-09 16:10:43 +03:00
|
|
|
option.classList.toggle('active');
|
|
|
|
|
|
|
|
const checkBox: HTMLInputElement | null = option.querySelector('input[type="checkbox"]');
|
|
|
|
|
|
|
|
if (checkBox) {
|
|
|
|
if (!(event.target instanceof HTMLInputElement)) {
|
|
|
|
checkBox.checked = !checkBox.checked;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (checkIndex == -1) {
|
|
|
|
this.indexes.push(index);
|
|
|
|
nativeOptionMultiple(nativeOption, item.title, true);
|
|
|
|
select!.textContent = '';
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.multiselectTag) {
|
2023-01-09 17:57:56 +03:00
|
|
|
if (Array.isArray(this.selectedItems)) {
|
|
|
|
const dataBreadCrumb: ICreateBreadCrumb = {
|
|
|
|
option: this.options,
|
|
|
|
element: this.element,
|
|
|
|
indexes: this.indexes,
|
|
|
|
selectedItems: this.selectedItems,
|
|
|
|
};
|
|
|
|
|
|
|
|
this.selectedItems.push(item.title);
|
|
|
|
select!.appendChild(ulMultipul);
|
|
|
|
ulMultipul.appendChild(
|
2023-01-09 18:01:31 +03:00
|
|
|
createBreadCrumb(dataBreadCrumb, item.title, index, item.id),
|
2023-01-09 17:57:56 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (Array.isArray(this.selectedItems)) {
|
|
|
|
this.selectedItems.push(item.title);
|
|
|
|
select!.innerText = this.selectedItems.join(',');
|
|
|
|
}
|
2023-01-09 16:10:43 +03:00
|
|
|
}
|
|
|
|
} else {
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.multiselectTag) {
|
2023-01-09 17:57:56 +03:00
|
|
|
const tagItem = document.getElementById(`tag-${index}-${item.id}`);
|
|
|
|
ulMultipul.removeChild<Element>(tagItem!);
|
|
|
|
}
|
2023-01-09 16:10:43 +03:00
|
|
|
|
|
|
|
if (Array.isArray(this.selectedItems)) {
|
|
|
|
this.selectedItems.splice(checkIndex, 1);
|
2023-01-09 17:57:56 +03:00
|
|
|
this.indexes.splice(checkIndex, 1);
|
|
|
|
nativeOptionMultiple(nativeOption, item.title, false);
|
2023-01-09 16:10:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-09 17:57:56 +03:00
|
|
|
if (!this.selectedItems.length) {
|
2023-01-10 14:33:09 +03:00
|
|
|
getSelectText(selectedItemsClear, select);
|
2023-01-09 17:57:56 +03:00
|
|
|
} else {
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.multiselectTag) {
|
2023-01-09 17:57:56 +03:00
|
|
|
select!.appendChild(ulMultipul);
|
|
|
|
} else {
|
|
|
|
if (Array.isArray(this.selectedItems)) {
|
|
|
|
select!.innerText = this.selectedItems.join(',');
|
|
|
|
}
|
|
|
|
}
|
2023-01-09 16:10:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
select!.textContent = item.title;
|
|
|
|
this.selectedItems = item.title;
|
|
|
|
|
|
|
|
nativeOptionOrdinary(nativeOption, item.title);
|
|
|
|
|
|
|
|
options.forEach((option) => {
|
|
|
|
option.classList.remove('active');
|
|
|
|
});
|
|
|
|
option.classList.add('active');
|
|
|
|
}
|
2023-01-10 14:33:09 +03:00
|
|
|
|
|
|
|
clearSelect(select!, this.element!, selectedItemsClear);
|
2023-01-06 14:07:37 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2023-01-10 18:12:38 +03:00
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
|
|
|
* @method checkTheme
|
|
|
|
* @description Changes the color scheme from dark to light.
|
2023-01-10 18:12:38 +03:00
|
|
|
*/
|
|
|
|
private checkTheme(): void {
|
|
|
|
const select = this.element!.querySelector('.cg-select');
|
|
|
|
const caret = this.element!.querySelector('.caret');
|
|
|
|
const list = this.element!.querySelector('ul.list');
|
|
|
|
const search = this.element!.querySelector('.inputSearch');
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.darkTheme == false) {
|
2023-01-10 18:12:38 +03:00
|
|
|
select!.classList.add('selectWhite');
|
|
|
|
caret!.classList.add('caretWhite');
|
|
|
|
list!.classList.add('listWhite');
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.searchMode == true) {
|
2023-01-10 18:12:38 +03:00
|
|
|
search!.classList.add('inputWhite');
|
|
|
|
}
|
2023-01-12 16:23:49 +03:00
|
|
|
} else if (this.darkTheme == true) {
|
2023-01-10 18:12:38 +03:00
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
throw new Error('Styles error or invalid value entered!');
|
|
|
|
}
|
|
|
|
}
|
2023-01-11 17:45:29 +03:00
|
|
|
|
2023-01-26 19:06:17 +03:00
|
|
|
private themeCheck(): void{
|
|
|
|
const select = this.element!.querySelector('.cg-select');
|
|
|
|
const caret = this.element!.querySelector('.caret');
|
|
|
|
const list = this.element!.querySelector('ul.list');
|
|
|
|
const search = this.element!.querySelector('.inputSearch');
|
|
|
|
|
|
|
|
switch (this.theme) {
|
|
|
|
case 'classic':
|
|
|
|
console.log('sss');
|
|
|
|
break;
|
|
|
|
case 'dark':
|
|
|
|
console.log('dark');
|
|
|
|
break;
|
|
|
|
case 'white':
|
|
|
|
console.log('white');
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-11 17:45:29 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
|
|
|
* @param {boolean} nativeSelectMode parameter responsible for adding native select.
|
|
|
|
* @description Changes the display of the select on mobile devices.
|
2023-01-11 17:45:29 +03:00
|
|
|
* @method selectMode
|
|
|
|
*/
|
|
|
|
private selectMode(nativeSelectMode: boolean) {
|
|
|
|
let win = window.outerWidth;
|
|
|
|
|
|
|
|
if (nativeSelectMode === true) {
|
|
|
|
const select = this.element!.querySelector('.cg-select');
|
|
|
|
const list = this.element!.querySelector('.list');
|
|
|
|
const nativeSelect = this.element!.querySelector('.nativeSelect');
|
|
|
|
|
|
|
|
if (win < 576) {
|
|
|
|
select!.classList.add('displayHide');
|
|
|
|
list!.classList.add('displayHide');
|
|
|
|
nativeSelect!.classList.add('nativeSelectActive');
|
|
|
|
} else if (win > 576) {
|
|
|
|
select!.classList.remove('displayHide');
|
|
|
|
list!.classList.remove('displayHide');
|
|
|
|
nativeSelect!.classList.remove('nativeSelectActive');
|
|
|
|
nativeSelect!.classList.add('displayHide');
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @description The method that implements the search for elements in the select.
|
|
|
|
* @private
|
|
|
|
* @param {string} random unique value for input element.
|
2023-01-11 17:45:29 +03:00
|
|
|
* @method searchMode
|
|
|
|
*/
|
|
|
|
private searchModeSelect(random: string) {
|
|
|
|
const input = this.element!.querySelector(`#searchSelect-${random}`) as HTMLInputElement;
|
|
|
|
const searchSelect = this.element!.querySelectorAll('.list__item');
|
|
|
|
const result = document.createElement('p');
|
|
|
|
|
|
|
|
let textNode: Text;
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.language && this.language === 'ru') {
|
2023-01-11 17:45:29 +03:00
|
|
|
textNode = document.createTextNode(`${ru.textInListSearch}`);
|
|
|
|
} else {
|
|
|
|
textNode = document.createTextNode(`${en.textInListSearch}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
result.appendChild(textNode);
|
|
|
|
result.classList.add('displayHide');
|
|
|
|
result.classList.add('noRezult');
|
|
|
|
input!.parentElement!.appendChild(result);
|
|
|
|
|
|
|
|
input!.addEventListener('click', (e) => {
|
|
|
|
e.stopPropagation();
|
|
|
|
});
|
|
|
|
|
|
|
|
if (input instanceof HTMLInputElement) {
|
|
|
|
input!.oninput = function () {
|
|
|
|
let valueSearch: string = input.value.trim().toLowerCase();
|
|
|
|
let anyMatch = false;
|
|
|
|
|
|
|
|
if (valueSearch != '') {
|
|
|
|
searchSelect.forEach((elem) => {
|
|
|
|
let isMatching = new RegExp(valueSearch, 'gi').test(elem.textContent!);
|
|
|
|
anyMatch = anyMatch || isMatching;
|
|
|
|
|
|
|
|
if (elem.textContent!.toLowerCase().search(valueSearch) == -1) {
|
|
|
|
elem.classList.add('displayHide');
|
|
|
|
} else {
|
|
|
|
elem.classList.remove('displayHide');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
result.classList.toggle('displayHide', anyMatch);
|
|
|
|
} else {
|
|
|
|
searchSelect.forEach((elem) => {
|
|
|
|
elem.classList.remove('displayHide');
|
|
|
|
result.classList.add('displayHide');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2023-01-11 18:41:33 +03:00
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @private
|
|
|
|
* @param {boolean} listDisplayMode parameter responsible for displaying the selection in the form of a modal window.
|
|
|
|
* @description Changes the display of a sheet with a selection as a modal window.
|
2023-01-11 18:41:33 +03:00
|
|
|
* @method displayMode
|
|
|
|
*/
|
|
|
|
private displayMode(listDisplayMode: boolean): void {
|
|
|
|
if (listDisplayMode) {
|
|
|
|
const modal = document.createElement('div');
|
|
|
|
const body = document.querySelector('body');
|
|
|
|
const list = this.list!;
|
|
|
|
|
|
|
|
modal.appendChild(list);
|
|
|
|
this.element!.appendChild(modal);
|
|
|
|
|
|
|
|
this.element!.addEventListener('click', () => {
|
|
|
|
modal.classList.toggle('modal');
|
|
|
|
list.classList.toggle('listModal');
|
|
|
|
body!.classList.toggle('overflowHide');
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Public methods
|
2023-01-20 18:50:53 +03:00
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {number} numberItem returned element number.
|
|
|
|
* @returns {HTMLElement} returns a reference to the selected HTML element.
|
2023-01-12 16:23:49 +03:00
|
|
|
* @method getElement
|
|
|
|
*/
|
2023-01-13 15:26:35 +03:00
|
|
|
public getElement(numberItem: number): IItems[] | string[] | any {
|
2023-01-12 16:23:49 +03:00
|
|
|
if (numberItem > this.items.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.items[numberItem];
|
|
|
|
}
|
|
|
|
|
2023-01-11 18:41:33 +03:00
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {ILanguage} language the object in which the fields for connecting the language are located has two mandatory fields placeholder, textInListSearch, selectPlaceholder.
|
|
|
|
* @description a method that allows you to change the placeholder in the search and the text that is displayed if there is no result.
|
2023-01-11 18:41:33 +03:00
|
|
|
* @method addLanguage
|
|
|
|
*/
|
|
|
|
public addLanguage(language: ILanguage) {
|
|
|
|
const { placeholder, textInListSearch, selectPlaceholder } = language;
|
|
|
|
|
|
|
|
const select = this.element!.querySelector('.selected');
|
|
|
|
const textNodeSelect = document.createTextNode(selectPlaceholder);
|
|
|
|
select!.appendChild(textNodeSelect);
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
if (this.searchMode) {
|
2023-01-11 18:41:33 +03:00
|
|
|
const search = this.element!.querySelector('.inputSearch');
|
|
|
|
const textNoRezult = this.element!.querySelector('.noRezult');
|
|
|
|
const textNode = document.createTextNode(textInListSearch);
|
|
|
|
|
|
|
|
search!.setAttribute('placeholder', placeholder);
|
|
|
|
search!.setAttribute('placeholder', placeholder);
|
|
|
|
|
|
|
|
textNoRezult!.textContent = '';
|
|
|
|
textNoRezult!.appendChild(textNode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {HTMLInputElement} button - HTML button.
|
|
|
|
* @param {string} method - open/close method.
|
|
|
|
* @description A method that allows you to open / close the select using buttons.
|
2023-01-11 18:41:33 +03:00
|
|
|
* @method buttonControl
|
|
|
|
*/
|
2023-01-12 16:23:49 +03:00
|
|
|
public buttonControl(button: Element, method: string) {
|
|
|
|
if (this.listDisplayMode) {
|
2023-01-11 18:41:33 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-01-12 16:23:49 +03:00
|
|
|
this.btnCntr = button!;
|
2023-01-11 18:41:33 +03:00
|
|
|
button.addEventListener('click', () => {
|
|
|
|
if (method.toLowerCase() === 'open') {
|
|
|
|
this.open(true);
|
|
|
|
} else if (method.toLowerCase() === 'close') {
|
|
|
|
this.close();
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2023-01-12 19:02:00 +03:00
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {boolean} value - Passed parameter to add the disabled attribute.
|
|
|
|
* @description A method that allows you to toggle the state of the disabled select.
|
2023-01-12 19:02:00 +03:00
|
|
|
* @method disabled
|
|
|
|
*/
|
|
|
|
public disabled(value: boolean) {
|
|
|
|
const select = this.element!.querySelector('.cg-select');
|
|
|
|
const nativeSelect = this.element!.querySelector('.nativeSelect');
|
|
|
|
|
|
|
|
if (value === true) {
|
|
|
|
this.element!.setAttribute('disabled', 'true');
|
|
|
|
nativeSelect!.setAttribute('disabled', 'true');
|
|
|
|
select!.classList.add('disabled');
|
|
|
|
} else {
|
|
|
|
this.element!.removeAttribute('disabled');
|
|
|
|
nativeSelect!.removeAttribute('disabled');
|
|
|
|
select!.classList.remove('disabled');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {string | IItems} item added element.
|
|
|
|
* @description adds the given element to the end of the list and redraws the list. Cannot be used when passing elements with categories.
|
2023-01-12 19:02:00 +03:00
|
|
|
* @method addItem
|
|
|
|
*/
|
|
|
|
public addItem(item: IItems | string | number) {
|
|
|
|
if (this.category) {
|
|
|
|
console.log('can`t add item to category');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!item) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const index = this.items.length;
|
|
|
|
|
|
|
|
this.items.push(getFormatItem(item, index));
|
|
|
|
this.render();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {number} index the index of the element to be removed.
|
|
|
|
* @description removes the element by index from the list and redraws it. Cannot be used when passing elements with categories.
|
2023-01-12 19:02:00 +03:00
|
|
|
* @method deleteItem
|
|
|
|
*/
|
|
|
|
public deleteItem(index: number) {
|
|
|
|
if (this.category) {
|
|
|
|
console.log('can`t add item to category');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const item = this.items[index];
|
|
|
|
|
|
|
|
this.items.splice(index, 1);
|
|
|
|
this.render();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @description removes all elements from the list and redraws it.
|
2023-01-12 19:02:00 +03:00
|
|
|
* @method deleteItemAll
|
|
|
|
*/
|
|
|
|
public deleteItemAll() {
|
|
|
|
this.items.splice(0, this.items.length);
|
|
|
|
this.render();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-01-20 18:50:53 +03:00
|
|
|
* @param {number} index the index of the selected element.
|
|
|
|
* @description selects the element that will be initially rendered in the select.
|
2023-01-12 19:02:00 +03:00
|
|
|
* @method selectIndex
|
|
|
|
*/
|
|
|
|
public selectIndex(index: number) {
|
|
|
|
if (this.category) {
|
|
|
|
console.log('can`t add item to category');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const options = this.element!.querySelectorAll('.list__item') as NodeListOf<HTMLElement>;
|
|
|
|
|
|
|
|
if (index > options!.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const select: string = options[index].innerText;
|
|
|
|
this.render(select);
|
|
|
|
}
|
2023-01-05 18:21:10 +03:00
|
|
|
}
|