From 48b175c18d19cf29cb0ed6529a0b7b7c413ec178 Mon Sep 17 00:00:00 2001 From: MaxOvs Date: Thu, 20 Oct 2022 17:47:50 +0300 Subject: [PATCH 1/2] Added native select and data push --- src/cg-dropdown.js | 21 +++++++ src/index.html | 9 ++- src/index.js | 114 ++++++++++++++++++------------------- src/style/nativSelect.scss | 13 +++++ 4 files changed, 95 insertions(+), 62 deletions(-) create mode 100644 src/style/nativSelect.scss diff --git a/src/cg-dropdown.js b/src/cg-dropdown.js index 67769df..af7f7c2 100644 --- a/src/cg-dropdown.js +++ b/src/cg-dropdown.js @@ -342,7 +342,11 @@ export class DropDown { } const ulList = document.createElement('ul'); + /// + const nativSelect = document.createElement('select'); + nativSelect.setAttribute('form', 'data'); + nativSelect.classList.add('nativSelect'); ulList.classList.add('list'); if (styles) { @@ -351,11 +355,15 @@ export class DropDown { } this.#element.appendChild(ulList); + /// + this.#element.appendChild(nativSelect); this.#items.forEach((dataItem) => { const liItem = document.createElement('li'); + const nativOption = document.createElement('option'); const strongItem = document.createElement('strong'); + nativOption.classList.add('nativSelect__nativOption'); liItem.classList.add('list__item'); strongItem.classList.add('category'); @@ -371,6 +379,13 @@ export class DropDown { if (dataItem.title) { textNode = document.createTextNode(dataItem.title); + /// + nativOption.text = dataItem.title; + nativOption.value = dataItem.title; + nativSelect.setAttribute('name', 'dataSelect'); + nativSelect.appendChild(nativOption); + + /// liItem.appendChild(textNode); ulList.appendChild(liItem); } else { @@ -488,6 +503,7 @@ export class DropDown { const options = this.#element.querySelectorAll('.list__item'); const select = this.#element.querySelector('.selected'); + const nativOption = this.#element.querySelectorAll('.nativSelect__nativOption'); const ul = document.createElement('ul'); @@ -562,6 +578,11 @@ export class DropDown { } else { select.innerText = item.title; this.#selectedItems = item; + nativOption.forEach((op) => { + if (op.textContent === item.title) { + op.setAttribute('selected', 'selected'); + } + }); options.forEach((option) => { option.classList.remove('active'); diff --git a/src/index.html b/src/index.html index 9d6e368..549a222 100644 --- a/src/index.html +++ b/src/index.html @@ -6,14 +6,17 @@ Cg-Select +
+
+ + +
diff --git a/src/index.js b/src/index.js index ed3c042..01044ae 100644 --- a/src/index.js +++ b/src/index.js @@ -15,70 +15,66 @@ const dropdown = new DropDown({ 'MAN', 'max', ], - multiselect: true, - multiselectTag: true, }); -dropdown.deleteItem(2); - // ------------------------------URL-------------------- -const dropdown3 = new DropDown({ - selector: '.cg-dropdown_three', - placeholder: 'URL', - url: 'http://jsonplaceholder.typicode.com/users', - styles: { - head: { - background: 'black', - width: '350px', - }, - }, - multiselect: true, - multiselectTag: true, -}); +// const dropdown3 = new DropDown({ +// selector: '.cg-dropdown_three', +// placeholder: 'URL', +// url: 'http://jsonplaceholder.typicode.com/users', +// styles: { +// head: { +// background: 'black', +// width: '350px', +// }, +// }, +// multiselect: true, +// multiselectTag: true, +// }); // --------------------------------Категории-------------------------- -const dropdown4 = new DropDown({ - selector: '.cg-dropdown_button', - placeholder: 'Выберите регион', - items: [ - { - category: 'Russia', - categoryItems: [ - { - id: '28qwds', - title: 'Москва', - value: 0, - }, - , - 'Ростов-на-дону', - 'Саратов', - 'Волгоград', - 'Донецк', - ], - }, - { - category: 'USA', - categoryItems: ['Alabama', 'Texas', 'Colorado', 'Klirens', 'Los-Angeles'], - }, - { - category: 'France', - categoryItems: ['Paris'], - }, - ], - styles: { - head: { - background: 'red', - }, - list: { - background: 'green', - }, - chips: { - background: 'blue', - }, - }, - multiselect: true, - multiselectTag: true, -}); +// const dropdown4 = new DropDown({ +// selector: '.cg-dropdown_button', +// placeholder: 'Выберите регион', +// items: [ +// { +// category: 'Russia', +// categoryItems: [ +// { +// id: '28qwds', +// title: 'Москва', +// value: 0, +// }, +// , +// 'Ростов-на-дону', +// 'Саратов', +// 'Волгоград', +// 'Донецк', +// ], +// }, +// { +// category: 'USA', +// categoryItems: ['Alabama', 'Texas', 'Colorado', 'Klirens', 'Los-Angeles'], +// }, +// { +// category: 'France', +// categoryItems: ['Paris'], +// }, +// ], +// styles: { +// head: { +// background: 'red', +// }, +// list: { +// background: 'green', +// }, +// chips: { +// background: 'blue', +// }, +// }, +// multiselect: true, +// multiselectTag: true, +// }); //----------------управление с помощью кнопок---------------------------------- /* const buttonOpen = document.querySelector('.button__open'); diff --git a/src/style/nativSelect.scss b/src/style/nativSelect.scss new file mode 100644 index 0000000..c864dd0 --- /dev/null +++ b/src/style/nativSelect.scss @@ -0,0 +1,13 @@ +.nativSelect { + border: none; + cursor: pointer; + display: none; + color: white; + background: #2a2f3b; + box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.5); + border-radius: 5px; + + &__nativOption { + border: 1px #0a0b0e solid; + } +} From be7c6e4d4b9cc1bef1bcc078f37eded614a6b6e5 Mon Sep 17 00:00:00 2001 From: MaxOvs Date: Fri, 21 Oct 2022 14:43:10 +0300 Subject: [PATCH 2/2] Nativ select/multiple is working! --- src/cg-dropdown.js | 33 ++++++++++++++++------------- src/components/create-element.js | 8 ++++--- src/components/utils.js | 36 ++++++++++++++++++++++++++++++++ src/index.html | 4 ++-- src/index.js | 3 +++ 5 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/cg-dropdown.js b/src/cg-dropdown.js index af7f7c2..b93d433 100644 --- a/src/cg-dropdown.js +++ b/src/cg-dropdown.js @@ -3,8 +3,10 @@ import { customStyles, getFormatItem, customStylesFormat, + nativOptionMultiple, + nativOptionOrdinary, } from './components/utils'; -import { createBreadcrumb } from './components/create-element'; +import { createBreadcrumb, createListSelect } from './components/create-element'; /** * @class Описание класса DropDown @@ -342,8 +344,8 @@ export class DropDown { } const ulList = document.createElement('ul'); - /// const nativSelect = document.createElement('select'); + nativSelect.setAttribute('form', 'data'); nativSelect.classList.add('nativSelect'); @@ -373,7 +375,10 @@ export class DropDown { checkBox.setAttribute('id', `chbox-${dataItem.id}`); liItem.appendChild(checkBox); + + nativSelect.setAttribute('multiple', 'multiple'); } + nativSelect.setAttribute('name', 'dataSelect'); let textNode = ''; @@ -382,7 +387,6 @@ export class DropDown { /// nativOption.text = dataItem.title; nativOption.value = dataItem.title; - nativSelect.setAttribute('name', 'dataSelect'); nativSelect.appendChild(nativOption); /// @@ -505,16 +509,17 @@ export class DropDown { const select = this.#element.querySelector('.selected'); const nativOption = this.#element.querySelectorAll('.nativSelect__nativOption'); - const ul = document.createElement('ul'); + const ulMultipul = document.createElement('ul'); if (multiselect) { - ul.classList.add('multiselect-tag'); + ulMultipul.classList.add('multiselect-tag'); select.classList.add('overflow-hidden'); } options.forEach((option, index) => { option.addEventListener('click', (event) => { const item = this.#items[index]; + if (multiselect) { event.stopPropagation(); option.classList.toggle('active'); @@ -529,13 +534,15 @@ export class DropDown { const checkIndex = this.#indexes.indexOf(index); if (checkIndex === -1) { + nativOptionMultiple(nativOption, item.title, true); + this.#indexes.push(index); select.innerText = ''; if (multiselectTag) { this.#selectedItems.push(item); - select.appendChild(ul); + select.appendChild(ulMultipul); const data = { option: this.#options, @@ -544,7 +551,7 @@ export class DropDown { selectedItems: this.#selectedItems, }; - ul.appendChild(createBreadcrumb(data, item.title, index, item.id)); + ulMultipul.appendChild(createBreadcrumb(data, item.title, index, item.id)); } else { this.#selectedItems.push(item.title); select.innerText = this.#selectedItems; @@ -552,11 +559,11 @@ export class DropDown { } else { if (multiselectTag) { const tagItem = document.getElementById(`tag-${index}-${item.id}`); - - ul.removeChild(tagItem); + ulMultipul.removeChild(tagItem); } this.#indexes.splice(checkIndex, 1); this.#selectedItems.splice(checkIndex, 1); + nativOptionMultiple(nativOption, item.title, false); } if (!this.#selectedItems.length) { @@ -569,7 +576,7 @@ export class DropDown { } } else { if (multiselectTag) { - select.appendChild(ul); + select.appendChild(ulMultipul); } else { select.innerText = this.#selectedItems; } @@ -578,11 +585,7 @@ export class DropDown { } else { select.innerText = item.title; this.#selectedItems = item; - nativOption.forEach((op) => { - if (op.textContent === item.title) { - op.setAttribute('selected', 'selected'); - } - }); + nativOptionOrdinary(nativOption, item.title); options.forEach((option) => { option.classList.remove('active'); diff --git a/src/components/create-element.js b/src/components/create-element.js index e27739a..16bb051 100644 --- a/src/components/create-element.js +++ b/src/components/create-element.js @@ -1,4 +1,4 @@ -import { customStylesFormat } from './utils'; +import { customStylesFormat, nativOptionMultiple } from './utils'; /** * @module createBreadcrumb */ @@ -16,6 +16,8 @@ export function createBreadcrumb(data, title, index, id) { const { placeholder, styles } = option; const selected = element.querySelector('.selected'); + const nativOption = element.querySelectorAll('.nativSelect__nativOption'); + const liChip = document.createElement('li'); const textNode = document.createTextNode(title); const svgIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); @@ -41,14 +43,14 @@ export function createBreadcrumb(data, title, index, id) { svgIcon.addEventListener('click', (event) => { event.stopPropagation(); + nativOptionMultiple(nativOption, title, false); const deleteIcon = indexes.indexOf(index); + let checkBox = ''; indexes.splice(deleteIcon, 1); selectedItems.splice(deleteIcon, 1); - let checkBox = ''; - if (id) { checkBox = document.getElementById(`chbox-${id}`); } else { diff --git a/src/components/utils.js b/src/components/utils.js index c254b26..7a3058e 100644 --- a/src/components/utils.js +++ b/src/components/utils.js @@ -108,3 +108,39 @@ export function getFormatItem(dataItem, index) { return item; } + +/** + * Поведение нативного(одинарного) селекта при выборе кастомного + * @param {NodeList} element NodeList нативного селекта + * @param {object} item выбранный элемент в кастомном селекте + */ +export function nativOptionOrdinary(element, item) { + element.forEach((option) => { + option.removeAttribute('selected'); + if (option.textContent === item) { + option.setAttribute('selected', 'selected'); + } + }); +} + +/** + * Поведение нативного(Multiple) селекта при выборе в кастомном + * @param {NodeList} element NodeList нативного селекта + * @param {object} item выбранный элемент в кастомном селекте + * @param {boolean} condition специальный флаг при котором добавляются/убераются атрибуты у нативного селекта + */ +export function nativOptionMultiple(element, item, condition) { + element.forEach((option) => { + if (condition == true) { + if (option.textContent === item) { + option.setAttribute('selected', 'selected'); + } + } else if (condition == false) { + if (option.textContent === item) { + option.removeAttribute('selected'); + } + } else { + return; + } + }); +} diff --git a/src/index.html b/src/index.html index 549a222..8a5cae0 100644 --- a/src/index.html +++ b/src/index.html @@ -14,9 +14,9 @@ - - --> + diff --git a/src/index.js b/src/index.js index 01044ae..598da3e 100644 --- a/src/index.js +++ b/src/index.js @@ -15,8 +15,11 @@ const dropdown = new DropDown({ 'MAN', 'max', ], + multiselect: true, + multiselectTag: true, }); +dropdown.disabled(false); // ------------------------------URL-------------------- // const dropdown3 = new DropDown({ // selector: '.cg-dropdown_three',