Last active
October 26, 2018 11:48
-
-
Save balkhaev/6e2a2dd9d5d2b3f07058b471f40382dd to your computer and use it in GitHub Desktop.
Кастомный селект с возможность подтягивания данных - https://jsfiddle.net/n7fp3Lv9/1/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
.custom-select { | |
position: relative; | |
display: block; | |
max-width: 400px; | |
min-width: 180px; | |
margin: 0 auto; | |
background-color: #bf9622; | |
z-index: 10; | |
} | |
.custom-select select { | |
border: none; | |
outline: none; | |
background: transparent; | |
-webkit-appearance: none; | |
-moz-appearance: none; | |
appearance: none; | |
border-radius: 0; | |
margin: 0; | |
display: block; | |
width: 100%; | |
padding: 12px 55px 15px 15px; | |
font-size: 14px; | |
color: #504422; | |
} | |
</style> | |
<select class="js-select" data-fetch-url="https://jsonplaceholder.typicode.com/users"></select> | |
<script> | |
/** | |
* Создание DOM элемента из строки | |
* @param {string} html - строка в которой содержится один родитель | |
* @returns {HTMLElement} | |
*/ | |
function createElement(html) { | |
const div = document.createElement('div'); | |
div.innerHTML = html; | |
return div.firstChild; | |
} | |
/** | |
* Оборачивание одного элемента другим | |
* @param wrapperEl - элемент в котором будет находится исходный элемент | |
* @param childrenEl - исходный элемент, должен присутствовать на странице | |
*/ | |
function wrapElement(wrapperEl, childrenEl) { | |
childrenEl.parentNode.insertBefore(wrapperEl, childrenEl); | |
wrapperEl.appendChild(childrenEl); | |
} | |
/** | |
* Получение данных | |
* @param {string} url - ссылка для запроса | |
* @returns {object|array} | |
*/ | |
async function fetchData(url) { | |
const res = await fetch(url); | |
return res.json(); | |
} | |
/** | |
* Создание label элемента | |
* @param forId - id select элемента для которого делается label | |
* @returns {HTMLElement} | |
*/ | |
const createLabel = (forId) => createElement(`<label class="custom-select" for="${forId}"></label>`); | |
/** | |
* Создание option элемента | |
* @param text - текст опции | |
* @param value - значение опции | |
* @returns {HTMLElement} | |
*/ | |
const createOption = (text, value) => createElement(`<option value="${value}">${text}</option>`); | |
let selectCounter = 0; | |
/** | |
* Инициализация кастомных селектов | |
* @param selector - селектор для выборки элементов | |
*/ | |
function init({ selector = '.js-select' } = {}) { | |
[].forEach.call(document.querySelectorAll(selector), async (selectEl) => { | |
selectCounter += 1; | |
selectEl.id = selectEl.id || 'custom-select-' + selectCounter; | |
const labelEl = createLabel(selectEl.id); | |
wrapElement(labelEl, selectEl); | |
if (selectEl.dataset.fetchUrl) { | |
const data = await fetchData(selectEl.dataset.fetchUrl); | |
data.forEach(item => selectEl.appendChild(createOption(item.name, item.id))); | |
} | |
}); | |
} | |
window.customSelect = opts => { | |
if (document.readyState !== 'loading') { | |
init(opts); | |
} else { | |
document.addEventListener('DOMContentLoaded', () => init(opts)); | |
} | |
} | |
customSelect(); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment