Skip to content

Instantly share code, notes, and snippets.

@balkhaev
Last active October 26, 2018 11:48
Show Gist options
  • Save balkhaev/6e2a2dd9d5d2b3f07058b471f40382dd to your computer and use it in GitHub Desktop.
Save balkhaev/6e2a2dd9d5d2b3f07058b471f40382dd to your computer and use it in GitHub Desktop.
Кастомный селект с возможность подтягивания данных - https://jsfiddle.net/n7fp3Lv9/1/
<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