Демо:

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

Плагины:

https://jquery.com/

https://imask.js.org/

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

//
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/imask@6.4.3/dist/imask.min.js"></script>

Разметка:

<div
    class="input-count"
    data-min="1"
    data-max="1000"
>
    <button type="button" data-step="-1">−</button>
    <input
        type="text"
        value="2"
        style="width: 1ch"
    />
    <button type="button" data-step="1">+</button>
</div>

Стили:

// blocks/inputs/input-count.scss

.input-count {
    display: flex;
    align-items: center;
    margin: -0.5rem;
    gap: 1rem;

    button {
        @include reset-btn;
        box-sizing: content-box;
        width: 1rem;
        color: #101010;
        font-family: inherit;
        font-size: 1.4rem;
        line-height: calc(12 / 14);
        text-transform: uppercase;
        padding: 0.5rem;
    }

    input {
        transition: none;
        padding: 0;
        border: 0;
        color: #101010;
        text-align: center;
        font-family: inherit;
        font-size: 1.4rem;
        text-transform: uppercase;
    }
}

Инициализация:

// modules/input-count.js

const CLASS_INPUT_COUNT = "input-count";

const findRootOf = (el) => {
    return $(el).closest(`.${CLASS_INPUT_COUNT}`);
};

const isValueInRange = (value, min, max) => {
    return value >= min && value <= max;
};

const updateButtons = ($root) => {
    const { mask, min, max } = $root.data();

    const inputValue = +mask.unmaskedValue;

    const $buttons = $root.find("button");
    $buttons.first().prop("disabled", inputValue === min);
    $buttons.last().prop("disabled", inputValue === max);
};

const updateInput = ($root) => {
    const { mask } = $root.data();

    const length = mask.value.length;
    $root.find("input").css("width", `${length || 1}ch`);
};

function handleButtonClick(e) {
    const { mask, min, max } = findRootOf(this).data();

    const step = +$(this).data("step");

    let newValue = +mask.unmaskedValue + step;

    if (isValueInRange(newValue, min, max)) {
        mask.unmaskedValue = newValue + "";
    }
}

function handleInputChange(e) {
    const { mask, min } = findRootOf(this).data();

    const value = +mask.unmaskedValue;

    if (value === 0) {
        mask.unmaskedValue = min + "";
    }
}

$(function () {
    $(`.${CLASS_INPUT_COUNT}`).each(function () {
        const $root = $(this);

        const { min, max } = $root.data();

        const $input = $root.find("input");

        // init imask
        const mask = IMask($input[0], {
            mask: Number,
            min: min || -Infinity,
            max: max || Infinity,
            thousandsSeparator: " ",
        });

        // save instance
        $root.data("mask", mask);

        // update appearance
        mask.on("accept", () => {
            updateInput($root);
            updateButtons($root);
        });

        updateButtons($root);
    });

    $(document).on("click", `.${CLASS_INPUT_COUNT} button`, handleButtonClick);
    $(document).on("change", `.${CLASS_INPUT_COUNT} input`, handleInputChange);
});
Рубрики: модуль

0 комментариев

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

Avatar placeholder

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