Source:

https://html.ildar-meyker.ru/html-kgeu/components.html?tab=tab-selects

Демо:

https://codepen.io/ildar-meyker/pen/ZEPPJJB

Плагины:

https://jquery.com

Подключение:

//

<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 комментариев

Добавить комментарий

Avatar placeholder

Ваш адрес email не будет опубликован. Обязательные поля помечены *