Feat/add dropdown list via js (#1)
* [feat/add-dropdown-list] Refactoring dropdown list. * Refactoring class Dropdown * [feat/add-dropdown-list] Added bandler(parcler) * Added mouseenter event handling * Fix bug open dropdown and added main.scss * Added private fild and changed methods * Refactoring DropDown * Added placeholder * Added customStyle * Fixed initSelected * Refactored initSelected * Added feature in customize select * featch customStyle complited! * Delited file customStyle.scss Co-authored-by: MaxOvs <rock_maksimus@mail.ru>
This commit is contained in:
parent
80ae89f920
commit
8c0e972883
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.parcel-cache
|
4796
package-lock.json
generated
Normal file
4796
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
24
package.json
Normal file
24
package.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "dropdown-list",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "",
|
||||||
|
"scripts": {
|
||||||
|
"start": "parcel ./src/index.html -p 4500 --open",
|
||||||
|
"build": "parcel build ./src/index.html"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/MaxOvs19/Dropdown-list.git"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/MaxOvs19/Dropdown-list/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/MaxOvs19/Dropdown-list#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"@parcel/transformer-sass": "^2.7.0",
|
||||||
|
"parcel": "^2.7.0",
|
||||||
|
"prettier": "^2.7.1"
|
||||||
|
}
|
||||||
|
}
|
205
src/cg-dropdown.js
Normal file
205
src/cg-dropdown.js
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
export class DropDown {
|
||||||
|
#element;
|
||||||
|
#list;
|
||||||
|
#options;
|
||||||
|
#caret;
|
||||||
|
|
||||||
|
//ToDo: Added url
|
||||||
|
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.#init(options);
|
||||||
|
this.#initSelected();
|
||||||
|
this.#initAmount();
|
||||||
|
this.#initItems();
|
||||||
|
this.#initEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#open() {
|
||||||
|
this.#list.classList.toggle('open');
|
||||||
|
this.#caret.classList.toggle('caret_rotate');
|
||||||
|
}
|
||||||
|
|
||||||
|
#init(options) {
|
||||||
|
this.#options = options;
|
||||||
|
const elem = document.querySelector(options.selector);
|
||||||
|
|
||||||
|
if (!elem) {
|
||||||
|
throw new Error(`Element with selector ${options.selector}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#element = elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#initSelected() {
|
||||||
|
const { styles } = this.#options;
|
||||||
|
if (this.#options.selected) {
|
||||||
|
this.#createSelected(this.#options.selected);
|
||||||
|
} else {
|
||||||
|
this.#createSelected('Select...');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.#options.selected && this.#options.placeholder) {
|
||||||
|
this.#createSelected(this.#options.placeholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((styles && this.#options.placeholder) || (styles && this.#options.selected)) {
|
||||||
|
this.#createSelected(this.#options.placeholder);
|
||||||
|
this.#customStyles(styles);
|
||||||
|
} else {
|
||||||
|
this.#createSelected('Select...');
|
||||||
|
this.#customStyles(styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#element.addEventListener('click', () => {
|
||||||
|
this.#open();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#initAmount() {
|
||||||
|
const { amount } = this.#options;
|
||||||
|
|
||||||
|
if (!amount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let templete = '';
|
||||||
|
|
||||||
|
for (let i = 0; i < amount; i++) {
|
||||||
|
templete += `<li class="list__item">${i + 1}</li>`;
|
||||||
|
}
|
||||||
|
this.#element.innerHTML += `<ul class="list">${templete}</ul>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
#initItems() {
|
||||||
|
const { items, styles } = this.#options;
|
||||||
|
|
||||||
|
if (!Array.isArray(items)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const templete = items.map((item) => `<li class="list__item" >${item}</li>`).join('');
|
||||||
|
this.#element.innerHTML += `<ul class="list">${templete}</ul>`;
|
||||||
|
|
||||||
|
if (styles) {
|
||||||
|
const templete = items.map((item) => `<li class="list__item" >${item}</li>`).join('');
|
||||||
|
this.#element.innerHTML += `<ul class="list style = "${styles}">${templete}</ul>`;
|
||||||
|
this.#customStyles(styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = this.#element.querySelectorAll('.list__item');
|
||||||
|
const selected = this.#element.querySelector('.selected');
|
||||||
|
|
||||||
|
options.forEach((option) => {
|
||||||
|
option.addEventListener('click', () => {
|
||||||
|
selected.innerText = option.innerText;
|
||||||
|
|
||||||
|
options.forEach((option) => {
|
||||||
|
option.classList.remove('active');
|
||||||
|
});
|
||||||
|
option.classList.add('active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//ToDo: finish this function(catigories)
|
||||||
|
items.forEach((item) => {
|
||||||
|
if (typeof item === 'object') {
|
||||||
|
for (const key in item) {
|
||||||
|
const element = item[key];
|
||||||
|
// console.log(element);
|
||||||
|
if (typeof element === 'string') {
|
||||||
|
console.log(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#initEvent() {
|
||||||
|
const { event } = this.#options;
|
||||||
|
|
||||||
|
this.#list = this.#element.querySelector('.list');
|
||||||
|
this.#caret = this.#element.querySelector('.caret');
|
||||||
|
|
||||||
|
if (event === 'mouseenter') {
|
||||||
|
this.#element.addEventListener(event, () => {
|
||||||
|
this.#list.classList.add('open');
|
||||||
|
this.#caret.classList.add('caret_rotate');
|
||||||
|
});
|
||||||
|
|
||||||
|
this.#element.addEventListener('mouseleave', () => {
|
||||||
|
this.#list.classList.remove('open');
|
||||||
|
this.#caret.classList.remove('caret_rotate');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#customStyles(styles) {
|
||||||
|
if (!styles) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { head, caret, list, placeholder } = styles;
|
||||||
|
const select = this.#element.querySelector('.cg-select');
|
||||||
|
const crt = this.#element.querySelector('.caret');
|
||||||
|
const ul = this.#element.querySelector('.list');
|
||||||
|
const placeh = this.#element.querySelector('.selected');
|
||||||
|
|
||||||
|
if (head) {
|
||||||
|
Object.entries(head).forEach(([key, value]) => {
|
||||||
|
select.style[key] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caret) {
|
||||||
|
Object.entries(caret).forEach(([key, value]) => {
|
||||||
|
crt.style[key] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ul) {
|
||||||
|
if (list) {
|
||||||
|
Object.entries(list).forEach(([key, value]) => {
|
||||||
|
ul.style[key] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (placeh) {
|
||||||
|
if (placeholder) {
|
||||||
|
Object.entries(placeholder).forEach(([key, value]) => {
|
||||||
|
placeh.style[key] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#createSelected(content, styles) {
|
||||||
|
this.#element.innerHTML = `
|
||||||
|
<div class="cg-select">
|
||||||
|
<span class="selected">${content}</span>
|
||||||
|
<div class="caret"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (styles) {
|
||||||
|
this.#customStyles(styles);
|
||||||
|
|
||||||
|
this.#element.innerHTML = `
|
||||||
|
<div class="cg-select" style = "${styles}">
|
||||||
|
<span class="selected" style = "${styles}">${content}</span>
|
||||||
|
<div class="caret" style = "${styles}"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// addItem(item) {
|
||||||
|
// const { items } = this.#options;
|
||||||
|
|
||||||
|
// console.log('Добавление елемента', item);
|
||||||
|
|
||||||
|
// items.push(item);
|
||||||
|
|
||||||
|
// console.log(items);
|
||||||
|
// }
|
||||||
|
}
|
@ -4,26 +4,18 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Dropdown-list</title>
|
<title>Cg-Select</title>
|
||||||
<link href="main.css" rel="stylesheet" />
|
<link href="./style/main.scss" rel="stylesheet" />
|
||||||
|
<link rel="stylesheet" href="style/customStyle.scss" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="dropdown">
|
<div class="cg-dropdown"></div>
|
||||||
<div class="select">
|
|
||||||
<span class="selected">BMW</span>
|
|
||||||
<div class="caret"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="list">
|
<div class="cg-dropdown2"></div>
|
||||||
<li class="list__item">Nissan</li>
|
|
||||||
<li class="list__item">Mersedes</li>
|
<!-- <div class="cg-dropdown3"></div> -->
|
||||||
<li class="list__item">Ford</li>
|
|
||||||
<li class="list__item active">Opel</li>
|
|
||||||
<li class="list__item">Chevrolet</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script src="index.js"></script>
|
<script type="module" src="index.js"></script>
|
||||||
</html>
|
</html>
|
||||||
|
65
src/index.js
65
src/index.js
@ -1,27 +1,48 @@
|
|||||||
const dropdowns = document.querySelectorAll('.dropdown');
|
import { DropDown } from './cg-dropdown';
|
||||||
|
|
||||||
dropdowns.forEach(drop => {
|
const dropdown = new DropDown({
|
||||||
const select = drop.querySelector('.select');
|
selector: '.cg-dropdown',
|
||||||
const caret = drop.querySelector('.caret');
|
|
||||||
const list = drop.querySelector('.list');
|
|
||||||
const options = drop.querySelectorAll('.list__item')
|
|
||||||
const selected = drop.querySelector('.selected')
|
|
||||||
|
|
||||||
select.addEventListener('click', () => {
|
items: ['BMW', 'Opel', 'Mersedes', 'MAN', 'max'],
|
||||||
caret.classList.toggle('caret-rotate');
|
|
||||||
list.classList.toggle('open');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
options.forEach(option => {
|
const dropdown2 = new DropDown({
|
||||||
option.addEventListener('click', () =>{
|
selector: '.cg-dropdown2',
|
||||||
selected.innerText = option.innerText;
|
placeholder: 'Выберите авто',
|
||||||
caret.classList.remove('caret-rotate');
|
items: ['BMW', 'Opel', 'Mersedes', 'MAN', 'Kamaz'],
|
||||||
list.classList.remove('open');
|
event: 'mouseenter',
|
||||||
|
styles: {
|
||||||
|
head: {
|
||||||
|
background: 'red',
|
||||||
|
color: 'black',
|
||||||
|
width: '400px',
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
color: 'grey',
|
||||||
|
},
|
||||||
|
caret: {
|
||||||
|
'border-top': '6px solid black',
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
background: 'red',
|
||||||
|
color: 'black',
|
||||||
|
width: '412px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
options.forEach(option =>{
|
// dropdown.addItem('Zaz');
|
||||||
option.classList.remove('active');
|
// const dropdown3 = new DropDown({
|
||||||
})
|
// selector: '.cg-dropdown3',
|
||||||
option.classList.add('active');
|
// selected: '',
|
||||||
})
|
// items: [
|
||||||
})
|
// {
|
||||||
})
|
// title: 'Russia',
|
||||||
|
// item: ['Rostov', 'Moskow'],
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: 'Germany',
|
||||||
|
// item: ['Germany', 'Berlin'],
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// });
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
* {
|
* {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: #1b1e25;
|
background: #1b1e25;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
display: flex;
|
||||||
margin: 50px auto;
|
margin: 50px auto;
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: 200px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown {
|
.cg-dropdown {
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select {
|
.cg-select {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
max-width: 200px;
|
min-width: 200px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -31,12 +31,12 @@ body{
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
transition: 0.5s;
|
transition: 0.5s;
|
||||||
}
|
|
||||||
|
|
||||||
.select:hover {
|
&:hover {
|
||||||
transition: 0.5s;
|
transition: 0.5s;
|
||||||
background: #394050;
|
background: #394050;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.caret {
|
.caret {
|
||||||
width: 0;
|
width: 0;
|
||||||
@ -45,18 +45,20 @@ transition: 0.5s;
|
|||||||
border-right: 5px solid transparent;
|
border-right: 5px solid transparent;
|
||||||
border-top: 6px solid #fff;
|
border-top: 6px solid #fff;
|
||||||
transition: 0.5s;
|
transition: 0.5s;
|
||||||
}
|
|
||||||
|
|
||||||
.caret-rotate {
|
&_rotate {
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
transition: 0.5s;
|
transition: 0.5s;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
|
max-height: 230px;
|
||||||
|
overflow-y: auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 212px;
|
width: 212px;
|
||||||
padding: 7px;
|
padding: 7px;
|
||||||
margin-top: 1px;
|
margin-top: -0.2px;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
color: white;
|
color: white;
|
||||||
@ -69,24 +71,24 @@ transition: 0.5s;
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
display: none;
|
display: none;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
|
||||||
|
|
||||||
.list__item {
|
&__item {
|
||||||
transition: 0.5s;
|
transition: 0.5s;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
|
||||||
|
|
||||||
.list__item:hover {
|
&:hover {
|
||||||
transition: 0.5s;
|
transition: 0.5s;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: #394050;
|
background: #8282822c;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
background: #394050;
|
background: #8282822c;
|
||||||
}
|
}
|
||||||
.open {
|
|
||||||
|
|
||||||
|
.open {
|
||||||
transition: 0.5s;
|
transition: 0.5s;
|
||||||
display: block;
|
display: block;
|
||||||
opacity: 1;
|
opacity: 1;
|
Loading…
Reference in New Issue
Block a user