Skip to content

Commit

Permalink
Add custom-select
Browse files Browse the repository at this point in the history
  • Loading branch information
Teihden committed Aug 2, 2023
1 parent d0437ca commit 91eedf6
Show file tree
Hide file tree
Showing 21 changed files with 366 additions and 139 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/vendor/
98 changes: 98 additions & 0 deletions src/js/modules/custom-select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { handleEscapeKey } from './utils.js';

const { $ } = window;

const onDocumentKeydown = (cb, evt) => handleEscapeKey(cb, evt);

const closeSelect = (optionItemsContainer) => {
optionItemsContainer
.addClass('custom-select__hide');

$(document).off();
};

const openSelect = (optionItemsContainer) => {
$('.custom-select__items')
.not(optionItemsContainer[0])
.addClass('custom-select__hide')
.end()
.filter(optionItemsContainer[0])
.removeClass('custom-select__hide');

const closeSelectCallback = () => closeSelect(optionItemsContainer);

$(document).on('click', closeSelectCallback);
$(document).on('keydown', (evt) => onDocumentKeydown(closeSelectCallback, evt));
};

const onSelectedOptionClick = (evt) => {
evt.preventDefault();
evt.stopPropagation();

const target = $(evt.target);
const optionItemsContainer = target.next();

if (optionItemsContainer.hasClass('custom-select__hide')) {
openSelect(optionItemsContainer);
} else {
closeSelect(optionItemsContainer);
}
};

const onSelectOption = (evt) => {
/* При нажатии на элемент обновляется исходное поле выбора,
и выбранный элемент: */
const targetOption = $(evt.currentTarget);
const parentSelect = targetOption.parents('.custom-select').find('.custom-select__select')[0];
const selectedOptionContainer = targetOption.parent().prev();

[...parentSelect.options].forEach((parentSelectOption, index) => {
if ($(parentSelectOption).text() === targetOption.text().split(/\s+/).join(' ')) {
parentSelect.selectedIndex = index;
selectedOptionContainer.text(targetOption.text());
}
});
};

const addAccentClass = (_, htmlString) => {
const accentText = htmlString.split(/\s+/).slice(0, 2).join(' ');
const text = htmlString.split(/\s+/).slice(2).join(' ');

return `<span class="custom-select__option--accent">${accentText}</span>
<span>${text}</span>`;
};

const initCustomSelect = () => {
/* Ищем элементы с классом "custom-select": */
const customSelectContainers = $('.custom-select');

customSelectContainers.each((_, customSelectContainer) => {
const select = $('.custom-select__select', customSelectContainer)[0];

/* Для каждого элемента создаем новый DIV (selectedOption),
который будет выступать в качестве выбранной опции: */
$('<div></div>')
.addClass('custom-select__selected')
.text(select.options[select.selectedIndex].innerHTML)
.on('click', onSelectedOptionClick)
.appendTo(customSelectContainer);

/* Для каждого элемента создаем новый DIV, который будет содержать список опций */
const optionList = $('<div></div>').addClass('custom-select__items custom-select__hide');

[...select.options].forEach((option) => {
/* Для каждого варианта в исходном элементе select,
создаем новый DIV (selectOption), который будет выступать в качестве элемента выбора: */
$('<div></div>')
.addClass('custom-select__option')
.text($(option).text())
.html(addAccentClass)
.on('click', onSelectOption)
.appendTo((optionList));
});

$(customSelectContainer).append(optionList);
});
};

export { initCustomSelect };
14 changes: 6 additions & 8 deletions src/js/modules/datatables.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* eslint-disable arrow-body-style */
/* eslint-disable no-unused-vars */
import { initColResizable, removeColResizable } from './colresizable.js';
import { createDeleteButton } from './delete-row.js';
import { onNewRowButtonClick } from './add-row.js';
import { debounce } from './utils.js';
import { dataArray } from './dataArray.js';
import { initCustomSelect } from './custom-select.js';

const { $ } = window;

Expand All @@ -27,13 +27,13 @@ const ORDER = (index) => `<button class="data-table__drag-button drag-button" ty
const INPUT = (value, type, name, placeholder) => `<input class="data-table__input" type="${type}"
name="${name}" value="${value}" placeholder="${placeholder}">`;

const SELECT = `<select class="data-table__select" name="unit-name">
const SELECT = `<div class="custom-select"><select class="custom-select__select" name="unit-name">
<option value="Мраморный щебень фр. 2-5 мм, 25кг">Мраморный щебень фр. 2-5 мм, 25кг</option>
<option value="Мраморный щебень фр. 2-5 мм, 25кг (белый)">Мраморный щебень фр. 2-5 мм, 25кг (белый)</option>
<option value="Мраморный щебень фр. 2-5 мм, 25кг (вайт)">Мраморный щебень фр. 2-5 мм, 25кг (вайт)</option>
<option value="Мраморный щебень фр. 2-5 мм, 25кг, возврат">Мраморный щебень фр. 2-5 мм, 25кг, возврат</option>
<option value="Мраморный щебень фр. 2-5 мм, 1т">Мраморный щебень фр. 2-5 мм, 1т</option>
</select>`;
</select></div>`;

const initDatatable = (table) => {
const dataTable = table.DataTable({
Expand All @@ -43,9 +43,6 @@ const initDatatable = (table) => {
ordering: true,
info: false,
autoWidth: true,
// colReorder: {
// fixedColumnsLeft: 1,
// },
colReorder: true,
rowReorder: {
selector: '.data-table__drag-button',
Expand Down Expand Up @@ -85,7 +82,7 @@ const initDatatable = (table) => {
const cell = $(td);

cell.attr('data-label', 'Наименование единицы');
cell.addClass('data-table__body-cell');
cell.addClass('data-table__body-cell data-table__body-cell--select');
},
render: (data, type, row, meta) => {
const select = $(SELECT);
Expand Down Expand Up @@ -199,7 +196,8 @@ const initDatatable = (table) => {
}],
initComplete: () => {
$('th', table).addClass('data-table__head-cell');
initColResizable(table)
initColResizable(table);
initCustomSelect();
},
});

Expand Down
15 changes: 15 additions & 0 deletions src/pug/includes/table.pug
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ section.table
.table__container#table-container
table.table__data.data-table.nowrap#data-table

//- .custom-select
//- select.custom-select__select(name="unit-name")
//- option(value="Мраморный щебень фр. 2-5 мм, 25кг") Мраморный щебень фр. 2-5 мм, 25кг
//- option(value="Мраморный щебень фр. 2-5 мм, 25кг (белый)") Мраморный щебень фр. 2-5 мм, 25кг (белый)
//- option(value="Мраморный щебень фр. 2-5 мм, 25кг (вайт)") Мраморный щебень фр. 2-5 мм, 25кг (вайт)
//- option(value="Мраморный щебень фр. 2-5 мм, 25кг, возврат") Мраморный щебень фр. 2-5 мм, 25кг, возврат
//- option(value="Мраморный щебень фр. 2-5 мм, 1т") Мраморный щебень фр. 2-5 мм, 1т
//- .custom-select
//- select.custom-select__select(name="unit-name")
//- option(value="Мраморный щебень фр. 2-5 мм, 25кг") Мраморный щебень фр. 2-5 мм, 25кг
//- option(value="Мраморный щебень фр. 2-5 мм, 25кг (белый)") Мраморный щебень фр. 2-5 мм, 25кг (белый)
//- option(value="Мраморный щебень фр. 2-5 мм, 25кг (вайт)") Мраморный щебень фр. 2-5 мм, 25кг (вайт)
//- option(value="Мраморный щебень фр. 2-5 мм, 25кг, возврат") Мраморный щебень фр. 2-5 мм, 25кг, возврат
//- option(value="Мраморный щебень фр. 2-5 мм, 1т") Мраморный щебень фр. 2-5 мм, 1т
table.table__result.result-table.nowrap#result-table
tbody.result-table__body
tr.result-table__row
Expand Down
55 changes: 55 additions & 0 deletions src/scss/blocks/_custom-select.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* stylelint-disable */
/* Контейнер должен быть позиционирован relative: */
.custom-select {
position: relative;
}

/* Скрываем исходный элемент SELECT */
.custom-select__select {
display: none;
}

/* Контейнер c выбранной опцией */
.custom-select__selected {
max-width: 100%;
height: 35px;
padding: 8px 15px 7px 14px;
border: solid 1px var(--chinese-silver);
border-radius: 5px;
background-color: var(--white);
cursor: pointer;
overflow: hidden;
white-space: nowrap;
}

/* Контейнер c опциями */
.custom-select__items {
position: absolute;
top: calc(100% + 10px);
left: 0;
z-index: 100;
padding: 7px 10px;
border: solid 1px var(--chinese-silver);
border-radius: 5px;
background-color: var(--white);
box-shadow: $box-shadow-button;
display: flex;
flex-direction: column;
row-gap: 14px;
}

/* Стилизация опций, включая выбранный элемент */
.custom-select__option {
color: var(--dark);
cursor: pointer;
font-size: 14px;

&--accent {
font-weight: 700;
}
}

/* Скрываем элементы при закрытии поля выбора */
.custom-select__hide {
display: none;
}
88 changes: 46 additions & 42 deletions src/scss/blocks/_data-table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@

.data-table__head-cell {
display: none;
overflow: hidden;

padding: 14px 8px !important;
border: 1px solid var(--light-gray) !important;

font-weight: 600;
padding: 14px 8px !important;
white-space: nowrap;

cursor: grab;
user-select: none;

overflow: hidden;
text-overflow: clip;
white-space: nowrap;

@media (min-width: $tablet-width) {
display: table-cell;
}
Expand All @@ -24,41 +25,46 @@
.data-table__body-row {
display: flex;
flex-direction: column;
margin: 0 0 5px 0;
background-color: var(--white) !important;

margin: 0 0 5px;
padding: 14px 4px 10px;
border: 1px solid var(--light-gray);
border-radius: 10px;

background-color: var(--white) !important;
box-shadow: $box-shadow;
border: 1px solid var(--light-gray);
padding: 14px 4px 10px;

@media (min-width: $tablet-width) {
display: table-row;

margin: 0;
padding: 0;
border: none;
border-radius: none;

background-color: none;
box-shadow: none;
border: none;
padding: 0;
}
}

.data-table__body-cell {
padding: 0 10px 15px !important;
overflow: hidden;

padding: 0 10px 15px !important;

text-overflow: clip;
white-space: nowrap;

@media (min-width: $tablet-width) {
padding: 5px 10px !important;
}

&:before {
display: block;
&::before {
content: attr(data-label);
display: block;

margin: 0 0 5px;

color: var(--suva-grey);

font-size: 10px;
line-height: 11px;
color: var(--suva-grey);
margin: 0 0 5px 0;

@media (min-width: $tablet-width) {
display: none;
Expand All @@ -78,6 +84,14 @@
display: table-cell;
}
}

@media (min-width: $tablet-width) {
padding: 5px 10px !important;
}

&--select {
overflow: unset !important;
}
}

.data-table__drag-button {
Expand All @@ -92,18 +106,20 @@
}

.data-table__input {
-webkit-appearance: textfield;
appearance: textfield;
width: 100%;
height: 35px;
max-width: 100%;
padding: 8px 15px 6px 14px;
border-radius: 5px;
height: 35px;
padding: 8px 0 6px 14px;
border: solid 1px var(--chinese-silver);
font-family: inherit;
border-radius: 5px;

font-size: 16px;
font-family: inherit;
line-height: 16px;

appearance: textfield;
appearance: textfield;

&::-webkit-outer-spin-button {
appearance: none;
}
Expand All @@ -113,24 +129,12 @@
}

&::placeholder {
font-family: inherit;
color: var(--black);

font-size: 16px;
font-family: inherit;
line-height: 16px;
color: var(--black);

opacity: 0.3;
}
}

.data-table__select {
appearance: none;
width: 100%;
height: 35px;
max-width: 100%;
padding: 8px 15px 7px 14px;
border-radius: 5px;
border: solid 1px var(--chinese-silver);
font-family: inherit;
font-size: 16px;
line-height: 16px;
background-color: var(--white);
}
Loading

0 comments on commit 91eedf6

Please sign in to comment.