Source:
https://html.ildar-meyker.ru/html-kgeu/components.html?tab=tab-selects
Демо:
https://codepen.io/ildar-meyker/pen/ZEPPJJB
Плагины:
Подключение:
//
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
Разметка:
//
<div class="select-radio">
<div class="select-radio__btn-selected">
<span>Период публикации</span>
</div>
<div
class="select-radio__dropdown js-form-range-wrapper"
>
<label class="check-default">
<span>Неделя</span>
<input name="same2" type="radio" />
<i></i>
</label>
<label class="check-default">
<span>Месяц</span>
<input name="same2" type="radio" />
<i></i>
</label>
<label class="check-default">
<span>Год</span>
<input name="same2" type="radio" />
<i></i>
</label>
<label class="check-default">
<span>Все время</span>
<input name="same2" type="radio" />
<i></i>
</label>
<label class="check-default">
<span>Выбрать периоды</span>
<input
name="same2"
type="radio"
data-is-date="true"
/>
<i></i>
</label>
<div class="form-range" style="display: none">
<div class="form-range__date">
<div class="input-range">
<input
type="text"
placeholder="DD.MM.YYYY"
class="js-date"
/>
</div>
</div>
<div>–</div>
<div class="form-range__date">
<div class="input-range">
<input
type="text"
placeholder="DD.MM.YYYY"
class="js-date"
/>
</div>
</div>
<div>
<a
href="#"
class="btn-default form-range__btn-ok js-select-radio-apply-range"
>Ок</a
>
</div>
</div>
</div>
</div>
Стили:
//
// blocks/selects/select-radio.scss
.select-radio {
position: relative;
&.active {
.select-radio__btn-selected {
border-bottom: transparent;
border-radius: 1.2rem 1.2rem 0 0;
&:after {
transform: translateY(-50%) scaleY(1);
}
}
.select-radio__dropdown {
display: block;
}
}
&__btn-selected {
position: relative;
border: 1px solid rgba(0, 71, 186, 0.5);
padding: 1.7rem 2rem;
padding-right: 6rem;
background: #fff;
border-radius: 1.2rem;
font-size: 2rem;
cursor: pointer;
&:after {
content: " ";
position: absolute;
top: 50%;
transform: translateY(-50%) scaleY(-1);
right: 2rem;
width: 1em;
height: 1em;
font-size: 2.4rem;
background: url(https://html.ildar-meyker.ru/html-kgeu/img/icons/general/arrow-up-blue.svg) no-repeat
50% 50% / contain;
}
}
&__dropdown {
position: absolute;
z-index: 10;
top: 100%;
left: 0;
min-width: 100%;
padding: 0 2rem 2rem 2rem;
background: #fff;
border: 1px solid rgba(0, 71, 186, 0.5);
border-top: 0;
border-radius: 0 0 1.2rem 1.2rem;
display: none;
width: 100%;
}
}
// blocks/checks/check-default.scss
.check-default {
position: relative;
display: block;
padding-left: 2em;
margin-bottom: 1.6rem;
font-size: 2rem;
line-height: 1.2;
user-select: none;
cursor: pointer;
&:last-child {
margin-bottom: 0;
}
}
.check-default input {
position: absolute;
height: 0;
width: 0;
cursor: pointer;
opacity: 0;
}
.check-default i {
transition: all 0.2s;
position: absolute;
top: 0;
left: 0;
height: 1.2em;
width: 1.2em;
border: 1px solid #899ab7;
border-radius: 0.4rem;
}
.check-default input[type="radio"] ~ i {
border-radius: 50%;
}
.check-default i:after {
content: "";
position: absolute;
display: none;
left: 37%;
top: 11%;
width: 20%;
height: 50%;
border: solid #0047ba;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
.check-default input[type="radio"] ~ i:after {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 60%;
height: 60%;
background: #0047ba;
border-radius: 50%;
border: none;
}
.check-default:hover i {
}
.check-default input:checked ~ i {
}
.check-default input:checked ~ i:after {
display: block;
}
.check-default input:disabled ~ i {
opacity: 0.4;
}
@media (max-width: 999.98px) {
.check-default {
margin-bottom: 1.2rem;
font-size: 1.4rem;
}
}
// blocks/inputs/input-range.scss
.input-range {
input {
width: 100%;
padding: 0 1.5rem;
height: 4rem;
background: #fff;
border: 1px solid rgba(137, 154, 183, 0.2);
border-radius: 0.4rem;
font-size: 1.5rem;
line-height: 1.2;
color: #21222e;
&::placeholder {
color: #899ab7;
}
&:focus {
border-color: rgba(137, 154, 183, 0.4);
}
}
}
@media (max-width: 999.98px) {
.input-range {
input {
height: 4.4rem;
font-size: 1.4rem;
&::placeholder {
}
}
}
}
// blocks/buttons/btn-default.scss
.btn-default {
@extend .reset-btn;
display: inline-flex;
justify-content: center;
align-items: center;
min-width: 20rem;
border: 1px solid transparent;
padding: 0 4rem;
height: 6rem;
border-radius: 1.2rem;
background: #0047ba;
font-size: 1.8rem;
line-height: 1.2;
text-align: center;
color: #fff;
&:hover {
background: lighten(#0047ba, 5%);
}
&--gray {
background: #eff1f4;
color: #21222e;
&:hover {
background: lighten(#eff1f4, 1%);
}
}
&--white {
background: #fff;
color: #21222e;
&:hover {
background: lighten(#eff1f4, 1%);
}
}
}
@media (max-width: 999.98px) {
.btn-default {
width: 100%;
font-size: 1.4rem;
border-radius: 0.8rem;
height: 4.8rem;
padding: 0 2rem;
}
}
// blocks/forms/form-range.scss
.form-range {
display: flex;
align-items: center;
gap: 0.8rem;
&__date {
flex-grow: 1;
}
&__btn-ok {
width: auto;
min-width: auto;
padding: 0 1.2rem;
font-size: 1.3rem;
height: 4rem;
}
}
@media (max-width: 999.98px) {
.form-range {
&__date {
flex-grow: 0;
input {
width: 12rem;
}
}
}
}
Инициализация:
let isAnySelectOpen = false;
function isOutsideOf(el, selector) {
return $(el).closest(selector).length === 0;
}
function getClosestSelect(elem) {
return $(elem).closest(".select-radio");
}
function setButtonText($select, value) {
$select.find(".select-radio__btn-selected").html(value);
}
function calcLabelForRange($select) {
const values = $select
.find(".form-range input")
.toArray()
.map((input) => {
return $(input).val();
});
const result = values.join("–");
return result.length > 10 ? result : "Выбрать периоды";
}
function handleBtnClick() {
const $select = getClosestSelect(this);
$(".select-radio").not($select).removeClass("active");
$select.toggleClass("active");
if ($select.hasClass("active")) {
isAnySelectOpen = true;
}
}
function handleInputChange() {
const $select = getClosestSelect(this);
const label = $(this).closest(".check-default").text().trim();
const isDate = $(this).data("is-date");
if (isDate) {
setButtonText($select, calcLabelForRange($select));
} else {
$select.removeClass("active");
setButtonText($select, label);
}
}
function handleOutsideClick(e) {
if (!isAnySelectOpen) return;
if (!isOutsideOf(e.target, ".select-radio")) return;
$(".select-radio").removeClass("active");
isAnySelectOpen = false;
console.log("select-radio:handleOutsideClick");
}
function handleApplyRange(e) {
e.preventDefault();
const $select = getClosestSelect(this);
const label = calcLabelForRange($select);
setButtonText($select, label);
$select.removeClass("active");
}
$(function () {
$(document).on("click", ".select-radio__btn-selected", handleBtnClick);
$(document).on(
"change",
".select-radio__dropdown input[type='radio']",
handleInputChange
);
$(document).on("click", ".js-select-radio-apply-range", handleApplyRange);
$(document).on("click", handleOutsideClick);
});
// modules/form-range.js
function handleInputChange() {
const isDate = $(this).data("is-date");
const $formRange = $(this)
.closest(".js-form-range-wrapper")
.find(".form-range");
if (isDate) {
$formRange.show();
} else {
$formRange.hide();
}
}
$(function () {
$(document).on(
"change",
".js-form-range-wrapper input[type='radio']",
handleInputChange
);
});
0 комментариев