Разрешить ввод только определенных символов

Иногда мы хотим сделать валидацию в поле ввода для символов, которые пользователь может вводить. Другие символы не будут приниматься в поле ввода.

Вопрос: Сделайте поле ввода, которое принимает только цифры и пробелы. Также позаботьтесь о копировании-вставке (Ctrl +V ) недопустимых символов.

Первый шаг — зарегистрировать событие на метке ввода. Но какой тип события? 🤔 Мы вводим символы, поэтому keypress событие выглядит нормально.

<input type="text" id="input"/>
Вход в полноэкранный режим Выход из полноэкранного режима
const input = document.getElementById('input');  
var currentInputValue = '';  
input.addEventListener('keypress', function inputKeypressHandler(e) {  
    // keypress event on input box is listened here and this function is triggered  
    // which key is pressed, keyPressed = e.which || e.keyCode;   
    const key = e.which || e.keyCode;  
    // key code corresponds to digits 0-9 or space then okay👍🏼  
    // 0-9 key code is 48-57  
    // space keycode is 32  
    const SPACE = 32; // May be just stored somewhere  
    const ZERO = 48;  
    const NINE = 57;  
    // valid digit is b/w 0-9 thus invalid will be lt 0 or gt 9  
    const isNotValidDigit = key < ZERO || key > NINE;  
    // if key is not a space or not a digit prevent this event  
    if (key != SPACE || ( isNotValidDigit ) ) {  
        e.preventDefault();  
    }  
});
Войти в полноэкранный режим Выход из полноэкранного режима

Это довольно хорошее решение, но оно не предотвращает чит пасты. И это потому, что событие keypress фиксирует только нажатие клавиши внутри поля ввода. Необходим более подходящий тип события. input он работает для всех способов ввода, включая copy paste и drag.

var currentInputValue = '';  
input.addEventListener('input', function inputInputEventHandler(e) {  
    // use target of event to get value of input  
    const target = e.target;  
    // we can use regex to check if current input value  
    // is valid input  
    const DIGITS_SPACE_REGEX = /^[0-9s]*$/;  
    // test if target.value or value of input box now is valid.  
    // if value is valid then update currentInputValue   
    // target.value else its is not value and we will  
    // ignore this target.value and replace it with   
    // previously valid value currentInputValue  
    DIGITS_SPACE_REGEX.test(target.value)   
        ? ( currentInputValue = target.value )   
        : ( target.value = currentInputValue );  
});
Вход в полноэкранный режим Выход из полноэкранного режима

Это решает нашу проблему с вставкой, но здесь есть одна проблема. Если вы вставите что-то Ctrl/Cmd + V, ваша текущая позиция курсора будет потеряна и перемещена в начало. Этого не должно происходить, и вы должны иметь возможность сохранять положение курсора.

// Track cursor position  
// cursor position is changed when you type something  
const cursorState = {};  
input.addEventListener('keydown', function inputKeydownHandler(e) {  
    const target = e.target;  
    // record the start and end  
    cursorState.selectionStart = target.selectionStart;  
    cursorState.selectionEnd = target.selectionEnd;  
});
Вход в полноэкранный режим Выход из полноэкранного режима

теперь в обработчике input.

// modify  
DIGITS_SPACE_REGEX.test(target.value)   
        ? ( currentInputValue = target.value )   
        : ( target.value = currentInputValue );  
 // to  
 if (DIGITS_SPACE_REGEX.test(target.value)) {  
     currentValue = target.value;  
 }  
 else {  
    target.value = current.value;  
    // restore cursor state  
    target.setSelectionRange(  
        cursorState.selectionStart,  
        cursorState.selectionEnd  
    );  
 }
Войти в полноэкранный режим Выход из полноэкранного режима

Демонстрация 👨💻

Оцените статью
devanswers.ru
Добавить комментарий