Ввод дробных значений без смены раскладки

в 12:30, , рубрики: Delphi, input, lazarus, Алгоритмы, ввод чисел, интерфейсы

Как часто вам приходится вводить в интерфейс какой-либо программы/web-сервиса дробные значения? Если часто, то, вероятно, вы сталкивались с неадекватным поведением таких полей. Я, например, довольно регулярно бьюсь лбом об абсолютно тупые формы. Хотите знать, почему ввод дробных значений может довести до белого каления, и что с этим делать? Добро пожаловать по кат.

По моим наблюдениям наиболее часто встречаются следующие алгоритма их поведения:

  • Угадай, куда нажать. Такие поля чаще всего встречаются в десктопных приложениях. Поле строго фильтрует ввод любых символов, кроме цифр и десятичного разделителя. Казалось бы, всё логично. Но давайте проведём эксперимент: закройте глаза и попробуйте ввести в такое строго поле десятичный разделитель, нажав всего одну кнопку. Получилось? Ой, не факт! Проблема строгой фильтрации в том, что пользователь: а) не знает, какой из двух стандартных десятичных разделителей использовал разработчик; б) при вводе цифр может не задумываться о текущей раскладке клавиатуры. В результате попытка ввести разделитель более чем в половине случаев заканчивается неудачей. Это не слишком критично, если нужно единожды ввести одно значение, но когда вводить дробные числа приходится регулярно — такое поведение формы утомляет.
  • Аккуратность — прежде всего. Этот тип более характерен для web'а. Ввод не фильтруется вообще, а при попытке сохранить форму происходит одно из трёх: отображается сообщение об ошибке; поле ввода очищается (или возвращается предыдущее значение); вообще ничего не происходит (форма проверяется в фоновом режиме и её отправка блокируется без видимых пользователю причин). Видимо, некоторые разработчики наивно полагают, что пользователь всегда знает, что должно вводить в форму.
  • Ну как-то так... Третий тип корявых форм периодически встречается везде. Предугадать их поведение практически невозможно. К примеру, в одной неплохой, в общем-то, shareware-программе для ведения домашней бухгалтерии при попытке ввести неверный десятичный разделитесь (точнее — при нажатии кнопки с символом разделителя не в текущей раскладке) целая часть числа бесследно исчезает. В другой (также далеко не бесплатной) утилите ввод любого символа, отличного от цифры и ожидаемого программой разделителя, вообще вызывает системное исключение. Наконец, у одного очень крупного российского интернет-магазина ввод любого недопустимого символа приводит к вставке десятичной запятой и двух нулей в дробной части, а ввод точки приводит к… вставке десятичной точки.

В общем, на дворе XXI век, интерфейсы развиваются, а такое тривиальнейшее действия, как ввод дробных значений, до сих пор является головной болью пользователей. Несколько лет назад мне довелось проектировать (и частично кодить) небольшую программку, для пользователей которой ввод дробных значений был повседневной задачей. Естественно, мне не хотелось повторять варианты поведения, описанные выше. В результате недолгих раздумий родился довольно простой алгоритм.

Итак, что же делать с дробными числами? Прежде всего, нужно обязательно фильтровать ввод. Проверка при отправке формы — штука хорошая, но для пользователя гораздо удобнее, если ввести значение удаётся с первого раза, а не после пинка со стороны скрипта. Вот мой вариант такого фильтра:

  1. Разрешаем ввод числе от 0 до 9.
  2. При нажатии любой кнопки, несущей любой возможный десятичный разделитель в любой раскладке необходимо подменить отправленный с клавиатуры символ так, чтобы в поле ввода попал правильный десятичный разделитель.
  3. блокируем попытку ввода более чем одного десятичного разделителя.
  4. ограничиваем число знаков в дробной части вводимого числа в зависимости от типа вводимых данных.

Пример 1. Пользователь на русской раскладке последовательно нажимает клавиши [1] [2] [3] [б] [4] [5]. Результат в поле ввода: 123.45

Пример 2. Пользователь на английской раскладке последовательно нажимает клавиши [1] [2] [3] [Shift+?] [4] [5]. Результат в поле ввода: 123.45

Результат работы данного алгоритма даёт отличный (вау-)эффект. Пользователям больше не нужно думать о раскладке, нажимать Shift и гадать, точку или запятую принял за десятичный разделитесь программист. Опыты на живых пользователях показали, что после 1-2 недель работы с таким «умным» полем ввода возврат к обычным полям вызывает ломку и желание убить программиста сломать клавиатуру.

PS. Честно говоря, этот алгоритм настолько прост, что я на 146% уверен, что такой подход был использован уже не раз и не два. Но по непонятным причинам он не получил широкого распространения (если не верите, найдите ближайшее поле ввода и проверьте его поведение — почти уверен, что оно впишется в один из трёх «корявых» алгоритмов, а не в приведённый мной «правильный»).

PPS. Для тех, кто пишет на Delphi или Lazarus приведу ссылку на компонент CurrencyEdit, реализующий данный алгоритм на соответствующем языке: Google Code.

PPPS. Конкретные примеры не привожу исключительно из уважения в авторам соответствующих программ. Если кто-либо из читателей Хабра обнаружит в своём коде «неправильные» алгоритмы и решит поменять их на «правильные» — благодарность от пользователей гарантирована.

PPPPS. Как-то я не совсем в теме: в HTML-формах в принципе можно фильтровать ввод?

Автор: nik_vr

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js