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 http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Dropdown-list</title>
|
||||
<link href="main.css" rel="stylesheet" />
|
||||
<title>Cg-Select</title>
|
||||
<link href="./style/main.scss" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="style/customStyle.scss" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="dropdown">
|
||||
<div class="select">
|
||||
<span class="selected">BMW</span>
|
||||
<div class="caret"></div>
|
||||
</div>
|
||||
<div class="cg-dropdown"></div>
|
||||
|
||||
<ul class="list">
|
||||
<li class="list__item">Nissan</li>
|
||||
<li class="list__item">Mersedes</li>
|
||||
<li class="list__item">Ford</li>
|
||||
<li class="list__item active">Opel</li>
|
||||
<li class="list__item">Chevrolet</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cg-dropdown2"></div>
|
||||
|
||||
<!-- <div class="cg-dropdown3"></div> -->
|
||||
</div>
|
||||
</body>
|
||||
<script src="index.js"></script>
|
||||
<script type="module" src="index.js"></script>
|
||||
</html>
|
||||
|
67
src/index.js
67
src/index.js
@ -1,27 +1,48 @@
|
||||
const dropdowns = document.querySelectorAll('.dropdown');
|
||||
import { DropDown } from './cg-dropdown';
|
||||
|
||||
dropdowns.forEach(drop => {
|
||||
const select = drop.querySelector('.select');
|
||||
const caret = drop.querySelector('.caret');
|
||||
const list = drop.querySelector('.list');
|
||||
const options = drop.querySelectorAll('.list__item')
|
||||
const selected = drop.querySelector('.selected')
|
||||
const dropdown = new DropDown({
|
||||
selector: '.cg-dropdown',
|
||||
|
||||
select.addEventListener('click', () => {
|
||||
caret.classList.toggle('caret-rotate');
|
||||
list.classList.toggle('open');
|
||||
});
|
||||
items: ['BMW', 'Opel', 'Mersedes', 'MAN', 'max'],
|
||||
});
|
||||
|
||||
options.forEach(option => {
|
||||
option.addEventListener('click', () =>{
|
||||
selected.innerText = option.innerText;
|
||||
caret.classList.remove('caret-rotate');
|
||||
list.classList.remove('open');
|
||||
const dropdown2 = new DropDown({
|
||||
selector: '.cg-dropdown2',
|
||||
placeholder: 'Выберите авто',
|
||||
items: ['BMW', 'Opel', 'Mersedes', 'MAN', 'Kamaz'],
|
||||
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 =>{
|
||||
option.classList.remove('active');
|
||||
})
|
||||
option.classList.add('active');
|
||||
})
|
||||
})
|
||||
})
|
||||
// dropdown.addItem('Zaz');
|
||||
// const dropdown3 = new DropDown({
|
||||
// selector: '.cg-dropdown3',
|
||||
// selected: '',
|
||||
// items: [
|
||||
// {
|
||||
// title: 'Russia',
|
||||
// item: ['Rostov', 'Moskow'],
|
||||
// },
|
||||
// {
|
||||
// title: 'Germany',
|
||||
// item: ['Germany', 'Berlin'],
|
||||
// },
|
||||
// ],
|
||||
// });
|
||||
|
@ -1,26 +1,26 @@
|
||||
* {
|
||||
font-size: 14px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
|
||||
}
|
||||
body{
|
||||
|
||||
body {
|
||||
background: #1b1e25;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
margin: 50px auto;
|
||||
width: 800px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
|
||||
.cg-dropdown {
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.select {
|
||||
.cg-select {
|
||||
padding: 14px;
|
||||
max-width: 200px;
|
||||
min-width: 200px;
|
||||
height: 30px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
@ -31,11 +31,11 @@ body{
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.select:hover {
|
||||
transition: 0.5s;
|
||||
&:hover {
|
||||
transition: 0.5s;
|
||||
background: #394050;
|
||||
}
|
||||
}
|
||||
|
||||
.caret {
|
||||
@ -45,18 +45,20 @@ transition: 0.5s;
|
||||
border-right: 5px solid transparent;
|
||||
border-top: 6px solid #fff;
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.caret-rotate {
|
||||
&_rotate {
|
||||
transform: rotate(180deg);
|
||||
transition: 0.5s;
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
max-height: 230px;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
width: 212px;
|
||||
padding: 7px;
|
||||
margin-top: 1px;
|
||||
margin-top: -0.2px;
|
||||
list-style: none;
|
||||
|
||||
color: white;
|
||||
@ -69,24 +71,24 @@ transition: 0.5s;
|
||||
opacity: 0;
|
||||
display: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.list__item {
|
||||
&__item {
|
||||
transition: 0.5s;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.list__item:hover {
|
||||
&:hover {
|
||||
transition: 0.5s;
|
||||
cursor: pointer;
|
||||
background: #394050;
|
||||
background: #8282822c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
background: #394050;
|
||||
background: #8282822c;
|
||||
}
|
||||
.open {
|
||||
|
||||
.open {
|
||||
transition: 0.5s;
|
||||
display: block;
|
||||
opacity: 1;
|
Loading…
Reference in New Issue
Block a user