Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Регулярное выражение для маски input (https://javascript.ru/forum/dom-window/81913-regulyarnoe-vyrazhenie-dlya-maski-input.html)

VolodinAS 13.02.2021 14:33

Регулярное выражение для маски input
 
Разрабатываю веб-приложения для журнала приёма пациентов. Необходимо оптимизировать ввод диагноза по мкб-10

Суть диагноза по мкб - это одна английская буква, затем две цифры - это категория мкб. Часто есть подкатегории мкб - это буква, две цифры, затем точка и еще одна цифра (двух вроде как не бывает).

Мой вопрос - как можно регуляркой это всё отразить?

проблема в том, что чтобы не переводить язык на английский, нужно, чтобы нажав "В" в поле ввелось "D", то есть, мкб - всегда начинается с английской буквы в верхнем регистре...

Примеры:
D44.1
C15.3
C73
U07.1
C81

Как это всё можно воплотить?

рони 13.02.2021 15:29

VolodinAS,
/[A-Z]\d{2}(\.\d)*/

рони 13.02.2021 16:38

маска для input first character is English only
 
VolodinAS,
<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
</head>
<body>
<input type="text" name="mkb">
    <script>
let input = document.querySelector('[name="mkb"]')
input.addEventListener("keydown", function(event) {
    let { code, key } = event;
    let { length } = input.value;
    if (['Delete', 'Backspace'].includes(code)) return;

    event.preventDefault();
    if (!length) {
        if (/^Key[A-Z]$/.test(code)) {
            input.value += code.slice(-1);
        }
    }
    if ([1, 2, 4].includes(length)) {
        if (/^Digit\d$/.test(code)) {
            input.value += code.slice(-1);
        }
    }
    if (length == 3) {
        if (key === '.') {
            input.value += key;
        }
    }
});
    </script>
</body>
</html>

voraa 13.02.2021 17:46

рони,
Вот такая последовательность.
"a" "1" "2" Ставим курсор между "1" и "2" Backspace "3"
Получаем A23 вместо A32

Не самое оптимальное решение, но лишено этого недостатка
<style>
#mkb10:invalid {
	border:1px solid red;
}

</style>

<body>
<label>МКБ 10 <input id=mkb10 type=text pattern="[A-Z]\d\d(\.\d)?" required></label>
<script>
const mkb = document.getElementById('mkb10');

	const cyrcode = 'ФИСВУАПРШОЛДЬТЩЗЙКЫМЯГ';
	const latcode = 'ABCDEFGHIJKLMNOPQRSTVZU'
	let icode = '';
	let rcode = '';
	mkb.addEventListener('keydown', (e) => {
		rcode = '';
		icode = e.key;
		if (icode.length == 1) {
			const ind = cyrcode.indexOf(icode.toUpperCase())
			if (ind>=0) {
				rcode = latcode[ind];
			} else if ('a'<=icode && icode<='z') {
				rcode = icode.toUpperCase();
			}
			if (! (/[A-Z0-9\.]/.test(rcode || icode))) {
				e.preventDefault();
			}
			
		}
	})
	mkb.addEventListener('input', (e) => {
		if (rcode) {
			const is = mkb.value.indexOf(icode)
			mkb.value = mkb.value.replace(icode, rcode);
			mkb.setSelectionRange(is+1, is+1);
		}
	})

</script>

рони 13.02.2021 18:25

voraa,
:thanks:

VolodinAS 13.02.2021 20:31

Спасибо огромное! Шикарное решение!

voraa 15.02.2021 09:15

Цитата:

Сообщение от рони
input.addEventListener("keydown", function(event) {
    let { code, key } = event;

Это хорошо, когда эти поля есть.
Я вот столкнулся с приколом, когда событие keydown возникает, а в event просто нет этих полей.
Ни code, ни key, ни keyCode, ни всяких meta, shift...
Соответственно на key.length получаю
TypeError: Cannot read property 'length' of undefined

Бывает и такое.

рони 15.02.2021 09:25

voraa,
бывает... :)

voraa 15.02.2021 09:30

Противно, что в документации нигде про такое не написано.
с одной ситуацией столкнулся, но может и другие есть.

Эта ситуевина возникает, когда выбираешь значение из списка автозаполнения.
Все мышью делается. Зачем там вообще keydown выскакивает?
Ведь если делать paste мышью из контекстного меню, никакого keydown не возникает. А тут примерно тоже самое - клавиатуру вообще не трогаю.


Часовой пояс GMT +3, время: 11:55.