Fixed variables in main class

This commit is contained in:
MaxOvs 2023-01-12 16:23:49 +03:00
parent f72084e44e
commit 994a1e972d
3 changed files with 122 additions and 107 deletions

View File

@ -44,6 +44,7 @@ const dropdn = new CGSelect({
// searchMode: true, // searchMode: true,
// nativeSelectMode: true // nativeSelectMode: true
// event: 'mouseenter', // event: 'mouseenter',
// buttonControl
multiselect: true, multiselect: true,
multiselectTag: true, multiselectTag: true,
}); });

View File

@ -26,6 +26,7 @@ import { ILanguage } from './interfaces/language.interface';
import './main.scss'; import './main.scss';
export class CGSelect implements ICgSelect { export class CGSelect implements ICgSelect {
// Настройки селекта
selector: string; selector: string;
selected?: string; selected?: string;
placeholder?: string; placeholder?: string;
@ -43,6 +44,7 @@ export class CGSelect implements ICgSelect {
multiselect?: boolean; multiselect?: boolean;
multiselectTag?: boolean; multiselectTag?: boolean;
// Переменные и комплектующие селекта
private element: Element | null; private element: Element | null;
private list: Element | null | undefined; private list: Element | null | undefined;
private options: ICgSelect; private options: ICgSelect;
@ -50,8 +52,8 @@ export class CGSelect implements ICgSelect {
private caret: Element | null | undefined; private caret: Element | null | undefined;
private category: string; private category: string;
private selectedItems: string[] | string; private selectedItems: string[] | string;
private itemsSelect: IItems[] | string[] | any;
private indexes: number[] = []; private indexes: number[] = [];
private btnCntr: Element | null;
constructor(setting: ICgSelect) { constructor(setting: ICgSelect) {
this.init(setting); this.init(setting);
@ -88,11 +90,43 @@ export class CGSelect implements ICgSelect {
} }
*/ */
private init(setting: ICgSelect): void { private init(setting: ICgSelect): void {
const { items, multiselect, url, selector } = setting; const {
items,
multiselect,
multiselectTag,
url,
selector,
listDisplayMode,
nativeSelectMode,
searchMode,
darkTheme,
language,
styles,
lable,
event,
selected,
placeholder,
} = setting;
this.options = setting; this.options = setting;
const elem = document.querySelector(selector); 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;
const elem = document.querySelector(this.selector);
this.element = elem; this.element = elem;
this.element?.addEventListener('click', (e) => { this.element?.addEventListener('click', (e) => {
@ -100,9 +134,9 @@ export class CGSelect implements ICgSelect {
this.open(); this.open();
}); });
this.itemsSelect = []; this.items = [];
if (!items && url) { if (!this.items && this.url) {
this.renderUrl(); this.renderUrl();
return; return;
} }
@ -116,12 +150,12 @@ export class CGSelect implements ICgSelect {
if (dataItem.category && dataItem.categoryItems) { if (dataItem.category && dataItem.categoryItems) {
this.category = dataItem.category!; this.category = dataItem.category!;
this.itemsSelect.push(this.category); this.items.push(this.category);
dataItem.categoryItems.forEach((categoryItem, indexCategory) => { dataItem.categoryItems.forEach((categoryItem, indexCategory: number) => {
this.itemsSelect.push(getFormatItem(categoryItem, indexCategory)); this.items.push(getFormatItem(categoryItem, indexCategory));
}); });
} else { } else {
this.itemsSelect.push(getFormatItem(itemInputs.ItemValue, index)); this.items.push(getFormatItem(itemInputs.ItemValue, index));
} }
}); });
} }
@ -134,16 +168,7 @@ export class CGSelect implements ICgSelect {
* @description Рендер елементов в селекте. * @description Рендер елементов в селекте.
*/ */
private render(select?: string): void { private render(select?: string): void {
const { const { styles } = this.options;
styles,
multiselect,
searchMode,
multiselectTag,
darkTheme,
language,
nativeSelectMode,
listDisplayMode,
} = this.options;
const random = Math.random().toString(36).substring(2, 10); const random = Math.random().toString(36).substring(2, 10);
@ -169,8 +194,8 @@ export class CGSelect implements ICgSelect {
customStylesFormat(list!, ulList); customStylesFormat(list!, ulList);
} }
if (searchMode) { if (this.searchMode) {
if (language === 'ru') { if (this.language === 'ru') {
inputSearch = createInputSearch(random, ru.placeholder); inputSearch = createInputSearch(random, ru.placeholder);
} else { } else {
inputSearch = createInputSearch(random, en.placeholder); inputSearch = createInputSearch(random, en.placeholder);
@ -183,7 +208,7 @@ export class CGSelect implements ICgSelect {
this.element?.appendChild(ulList); this.element?.appendChild(ulList);
this.itemsSelect.forEach((dataItem: IItems | any) => { this.items.forEach((dataItem: IItems | any) => {
this.element?.appendChild(nativeSelect); this.element?.appendChild(nativeSelect);
const liItem = document.createElement('li'); const liItem = document.createElement('li');
@ -193,13 +218,13 @@ export class CGSelect implements ICgSelect {
liItem.classList.add('list__item'); liItem.classList.add('list__item');
strongItem.classList.add('category'); strongItem.classList.add('category');
if (multiselect) { if (this.multiselect) {
const checkBox = document.createElement('input'); const checkBox = document.createElement('input');
checkBox.type = 'checkbox'; checkBox.type = 'checkbox';
checkBox.setAttribute('id', `chbox-${dataItem.id}`); checkBox.setAttribute('id', `chbox-${dataItem.id}`);
liItem.appendChild(checkBox); liItem.appendChild(checkBox);
if (multiselectTag) { if (this.multiselectTag) {
checkBox.classList.add('displayHide'); checkBox.classList.add('displayHide');
} }
@ -222,9 +247,9 @@ export class CGSelect implements ICgSelect {
} }
}); });
this.itemsSelect.filter((item, index) => { this.items.filter((item, index) => {
if (typeof item !== 'object') { if (typeof item !== 'object') {
this.itemsSelect.splice(index, 1); this.items.splice(index, 1);
} }
return item; return item;
}); });
@ -232,16 +257,16 @@ export class CGSelect implements ICgSelect {
this.list = this.element!.querySelector('.list'); this.list = this.element!.querySelector('.list');
this.caret = this.element!.querySelector('.caret'); this.caret = this.element!.querySelector('.caret');
if (darkTheme == false) { if (this.darkTheme == false) {
this.checkTheme(); this.checkTheme();
} }
if (nativeSelectMode === true) { if (this.nativeSelectMode === true) {
this.selectMode(nativeSelectMode); this.selectMode(this.nativeSelectMode);
} }
if (listDisplayMode) { if (this.listDisplayMode) {
this.displayMode(listDisplayMode); this.displayMode(this.listDisplayMode);
} }
this.addOptionsBehaviour(); this.addOptionsBehaviour();
@ -254,17 +279,11 @@ export class CGSelect implements ICgSelect {
* @description Рендер елементов в селекте переданных с URL и их настойка * @description Рендер елементов в селекте переданных с URL и их настойка
*/ */
private async renderUrl() { private async renderUrl() {
const { url, items, multiselect, multiselectTag } = this.options; if (this.items || !this.url) {
if (items) {
return; return;
} }
if (!url) { const response = await fetch(this.url);
return;
}
const response = await fetch(url);
const dataUrl = await response.json(); const dataUrl = await response.json();
const nativeSelect = createNativeSelect(); const nativeSelect = createNativeSelect();
@ -282,11 +301,11 @@ export class CGSelect implements ICgSelect {
const liUrl = document.createElement('li'); const liUrl = document.createElement('li');
const textUrl = document.createTextNode(item.title); const textUrl = document.createTextNode(item.title);
if (multiselect) { if (this.multiselect) {
const checkBox = document.createElement('input'); const checkBox = document.createElement('input');
checkBox.type = 'checkbox'; checkBox.type = 'checkbox';
if (multiselectTag) { if (this.multiselectTag) {
checkBox.classList.add('displayHide'); checkBox.classList.add('displayHide');
} }
@ -304,14 +323,14 @@ export class CGSelect implements ICgSelect {
liUrl.appendChild(textUrl); liUrl.appendChild(textUrl);
ulUrl!.appendChild(liUrl); ulUrl!.appendChild(liUrl);
this.itemsSelect.push(item); this.items.push(item);
}); });
this.element!.appendChild(nativeSelect); this.element!.appendChild(nativeSelect);
this.itemsSelect.filter((item, index) => { this.items.filter((item, index) => {
if (typeof item !== 'object') { if (typeof item !== 'object') {
this.itemsSelect.splice(index, 1); this.items.splice(index, 1);
} }
return item; return item;
}); });
@ -328,17 +347,17 @@ export class CGSelect implements ICgSelect {
* @protected * @protected
*/ */
private initSelected(select?: string): void { private initSelected(select?: string): void {
const { styles, selected, placeholder, lable, language } = this.options; const { styles } = this.options;
if (selected) { if (this.selected) {
createSelected(this.element, selected); createSelected(this.element, this.selected);
} else if (placeholder) { } else if (this.placeholder) {
createSelected(this.element, placeholder); createSelected(this.element, this.placeholder);
} else { } else {
if (language && language === 'ru') { if (this.language && this.language === 'ru') {
// createSelected(this.#element, ru.selectPlaceholder); createSelected(this.element, ru.selectPlaceholder);
} else { } else {
// createSelected(this.#element, en.selectPlaceholder); createSelected(this.element, en.selectPlaceholder);
} }
} }
@ -346,9 +365,9 @@ export class CGSelect implements ICgSelect {
createSelected(this.element, select, styles); createSelected(this.element, select, styles);
} }
if (lable) { if (this.lable) {
const lableItem = document.createElement('h1'); const lableItem = document.createElement('h1');
const textLable = document.createTextNode(lable); const textLable = document.createTextNode(this.lable);
lableItem.appendChild(textLable); lableItem.appendChild(textLable);
lableItem.classList.add('label'); lableItem.classList.add('label');
@ -368,14 +387,13 @@ export class CGSelect implements ICgSelect {
* @method initEvent * @method initEvent
*/ */
private initEvent() { private initEvent() {
const { event } = this.options; if (!this.event) {
if (!event) {
return; return;
} }
if (event) { if (this.event) {
if (event === 'mouseenter') { if (this.event === 'mouseenter') {
this.element!.addEventListener(event, () => { this.element!.addEventListener(this.event, () => {
this.open(); this.open();
}); });
this.element!.addEventListener('mouseleave', () => { this.element!.addEventListener('mouseleave', () => {
@ -394,11 +412,11 @@ export class CGSelect implements ICgSelect {
*/ */
private open(oneClick?: boolean): void { private open(oneClick?: boolean): void {
if (oneClick === true) { if (oneClick === true) {
this.list?.classList.add('open'); this.list!.classList.add('open');
this.caret?.classList.add('caret_rotate'); this.caret!.classList.add('caret_rotate');
} else { } else {
this.list?.classList.toggle('open'); this.list!.classList.toggle('open');
this.caret?.classList.toggle('caret_rotate'); this.caret!.classList.toggle('caret_rotate');
} }
} }
@ -425,12 +443,11 @@ export class CGSelect implements ICgSelect {
document.addEventListener('click', (e) => { document.addEventListener('click', (e) => {
const withinBoundaries = e.composedPath().includes(dropdown!); const withinBoundaries = e.composedPath().includes(dropdown!);
if (!withinBoundaries) { if (!withinBoundaries) {
// if (this.btn) { if (this.btnCntr) {
// return; return;
// } else { } else {
// this.#close(); this.close();
// } }
this.close();
} }
}); });
} }
@ -442,16 +459,6 @@ export class CGSelect implements ICgSelect {
* @method addOptionsBehaviour * @method addOptionsBehaviour
*/ */
private addOptionsBehaviour() { private addOptionsBehaviour() {
const {
multiselect,
placeholder,
selected,
multiselectTag,
searchMode,
closeOnSelect,
darkTheme,
} = this.options;
const options = this.element?.querySelectorAll('.list__item'); const options = this.element?.querySelectorAll('.list__item');
const select: HTMLElement | null | undefined = this.element?.querySelector('.selected'); const select: HTMLElement | null | undefined = this.element?.querySelector('.selected');
const nativeOption = this.element!.querySelectorAll('.nativeSelect__nativeOption'); const nativeOption = this.element!.querySelectorAll('.nativeSelect__nativeOption');
@ -460,13 +467,13 @@ export class CGSelect implements ICgSelect {
const ulMultipul = document.createElement('ul'); const ulMultipul = document.createElement('ul');
if (multiselect) { if (this.multiselect) {
this.selectedItems = []; this.selectedItems = [];
ulMultipul.classList.add('multiselect-tag'); ulMultipul.classList.add('multiselect-tag');
select?.classList.add('overflow-hidden'); select?.classList.add('overflow-hidden');
} }
if (searchMode) { if (this.searchMode) {
this.searchModeSelect(this.randomId); this.searchModeSelect(this.randomId);
} }
@ -474,25 +481,25 @@ export class CGSelect implements ICgSelect {
option.addEventListener('click', (event) => { option.addEventListener('click', (event) => {
if (Array.isArray(this.selectedItems)) { if (Array.isArray(this.selectedItems)) {
selectedItemsClear = { selectedItemsClear = {
placeholder: placeholder!, placeholder: this.placeholder!,
selected: selected!, selected: this.selected!,
selectedItems: this.selectedItems, selectedItems: this.selectedItems,
indexes: this.indexes, indexes: this.indexes,
darkTheme: darkTheme, darkTheme: this.darkTheme,
multiselectTag: multiselectTag, multiselectTag: this.multiselectTag,
}; };
} }
const item: IItems = this.itemsSelect[index]; const item: IItems = this.items[index];
const checkIndex = this.indexes.indexOf(index); const checkIndex = this.indexes.indexOf(index);
if (closeOnSelect == false || multiselect) { if (this.closeOnSelect == false || this.multiselect) {
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
} }
if (multiselect) { if (this.multiselect) {
option.classList.toggle('active'); option.classList.toggle('active');
const checkBox: HTMLInputElement | null = option.querySelector('input[type="checkbox"]'); const checkBox: HTMLInputElement | null = option.querySelector('input[type="checkbox"]');
@ -507,7 +514,7 @@ export class CGSelect implements ICgSelect {
nativeOptionMultiple(nativeOption, item.title, true); nativeOptionMultiple(nativeOption, item.title, true);
select!.textContent = ''; select!.textContent = '';
if (multiselectTag) { if (this.multiselectTag) {
if (Array.isArray(this.selectedItems)) { if (Array.isArray(this.selectedItems)) {
const dataBreadCrumb: ICreateBreadCrumb = { const dataBreadCrumb: ICreateBreadCrumb = {
option: this.options, option: this.options,
@ -529,7 +536,7 @@ export class CGSelect implements ICgSelect {
} }
} }
} else { } else {
if (multiselectTag) { if (this.multiselectTag) {
const tagItem = document.getElementById(`tag-${index}-${item.id}`); const tagItem = document.getElementById(`tag-${index}-${item.id}`);
ulMultipul.removeChild<Element>(tagItem!); ulMultipul.removeChild<Element>(tagItem!);
} }
@ -544,7 +551,7 @@ export class CGSelect implements ICgSelect {
if (!this.selectedItems.length) { if (!this.selectedItems.length) {
getSelectText(selectedItemsClear, select); getSelectText(selectedItemsClear, select);
} else { } else {
if (multiselectTag) { if (this.multiselectTag) {
select!.appendChild(ulMultipul); select!.appendChild(ulMultipul);
} else { } else {
if (Array.isArray(this.selectedItems)) { if (Array.isArray(this.selectedItems)) {
@ -577,22 +584,20 @@ export class CGSelect implements ICgSelect {
* @description Изменяет цветовую схему с темной на светлую. * @description Изменяет цветовую схему с темной на светлую.
*/ */
private checkTheme(): void { private checkTheme(): void {
const { darkTheme, searchMode } = this.options;
const select = this.element!.querySelector('.cg-select'); const select = this.element!.querySelector('.cg-select');
const caret = this.element!.querySelector('.caret'); const caret = this.element!.querySelector('.caret');
const list = this.element!.querySelector('ul.list'); const list = this.element!.querySelector('ul.list');
const search = this.element!.querySelector('.inputSearch'); const search = this.element!.querySelector('.inputSearch');
if (darkTheme == false) { if (this.darkTheme == false) {
select!.classList.add('selectWhite'); select!.classList.add('selectWhite');
caret!.classList.add('caretWhite'); caret!.classList.add('caretWhite');
list!.classList.add('listWhite'); list!.classList.add('listWhite');
if (searchMode == true) { if (this.searchMode == true) {
search!.classList.add('inputWhite'); search!.classList.add('inputWhite');
} }
} else if (darkTheme == true || !darkTheme) { } else if (this.darkTheme == true) {
return; return;
} else { } else {
throw new Error('Styles error or invalid value entered!'); throw new Error('Styles error or invalid value entered!');
@ -636,14 +641,12 @@ export class CGSelect implements ICgSelect {
* @method searchMode * @method searchMode
*/ */
private searchModeSelect(random: string) { private searchModeSelect(random: string) {
const { language } = this.options;
const input = this.element!.querySelector(`#searchSelect-${random}`) as HTMLInputElement; const input = this.element!.querySelector(`#searchSelect-${random}`) as HTMLInputElement;
const searchSelect = this.element!.querySelectorAll('.list__item'); const searchSelect = this.element!.querySelectorAll('.list__item');
const result = document.createElement('p'); const result = document.createElement('p');
let textNode: Text; let textNode: Text;
if (language && language === 'ru') { if (this.language && this.language === 'ru') {
textNode = document.createTextNode(`${ru.textInListSearch}`); textNode = document.createTextNode(`${ru.textInListSearch}`);
} else { } else {
textNode = document.createTextNode(`${en.textInListSearch}`); textNode = document.createTextNode(`${en.textInListSearch}`);
@ -713,6 +716,20 @@ export class CGSelect implements ICgSelect {
} }
// Public methods // Public methods
/**
* Метод экземпляра класса DropDown
* @param {number} numberItem номер возвращаемого элемента
* @returns {HTMLElement} возвращает ссылку на выбранный HTML элемент
* @method getElement
*/
public getElement(numberItem: number) {
if (numberItem > this.items.length) {
return;
}
return this.items[numberItem];
}
/** /**
* Метод экземпляра класса DropDown * Метод экземпляра класса DropDown
* @param {object} language объект в котором находятся поля для подключения языка имеет два обязательных поля placeholder, textInListSearch * @param {object} language объект в котором находятся поля для подключения языка имеет два обязательных поля placeholder, textInListSearch
@ -721,13 +738,12 @@ export class CGSelect implements ICgSelect {
*/ */
public addLanguage(language: ILanguage) { public addLanguage(language: ILanguage) {
const { placeholder, textInListSearch, selectPlaceholder } = language; const { placeholder, textInListSearch, selectPlaceholder } = language;
const { searchMode } = this.options;
const select = this.element!.querySelector('.selected'); const select = this.element!.querySelector('.selected');
const textNodeSelect = document.createTextNode(selectPlaceholder); const textNodeSelect = document.createTextNode(selectPlaceholder);
select!.appendChild(textNodeSelect); select!.appendChild(textNodeSelect);
if (searchMode) { if (this.searchMode) {
const search = this.element!.querySelector('.inputSearch'); const search = this.element!.querySelector('.inputSearch');
const textNoRezult = this.element!.querySelector('.noRezult'); const textNoRezult = this.element!.querySelector('.noRezult');
const textNode = document.createTextNode(textInListSearch); const textNode = document.createTextNode(textInListSearch);
@ -747,14 +763,12 @@ export class CGSelect implements ICgSelect {
* @description Метод позволяющий открывать/закрывать селект с помощью кнопок * @description Метод позволяющий открывать/закрывать селект с помощью кнопок
* @method buttonControl * @method buttonControl
*/ */
public buttonControl(button, method: string) { public buttonControl(button: Element, method: string) {
const { listDisplayMode } = this.options; if (this.listDisplayMode) {
if (listDisplayMode === true) {
return; return;
} }
// this.btn = button; this.btnCntr = button!;
button.addEventListener('click', () => { button.addEventListener('click', () => {
if (method.toLowerCase() === 'open') { if (method.toLowerCase() === 'open') {
this.open(true); this.open(true);

View File

@ -84,7 +84,7 @@ export function createSelected(element: Element | null, content?: string, styles
selected.appendChild(text); selected.appendChild(text);
element?.appendChild(select); element?.appendChild(select);
} else if (styles) { } else if (styles) {
// customStyles(element, styles); customStyles(element!, styles);
select.setAttribute('style', `${styles}`); select.setAttribute('style', `${styles}`);
selected.setAttribute('style', `${styles}`); selected.setAttribute('style', `${styles}`);
caret.setAttribute('style', `${styles}`); caret.setAttribute('style', `${styles}`);