Pull to refresh

Comments 55

А если у пользователя установлена локаль с разделителем групп разрядов? Как этот алгоритм отреагирует на число 10,000.1 (десять тысяч целых, одна десятая в локали en-US)?
Может лучше использовать как в старой технике, разделитель тысячи делать апострофом?
10`000.1 = 10`000,1
или
10'000.1 = 10'000,1
На мой взгляд это очень наглядно и не сбивает с толку наличие двух знаков и более в одной строке.
10'000'000'000'000,500
страны разные с разными принципами написания чисел.
Не думаю, что тут будут проблемы — разделитесь групп разрядов отрисовывается на уровне API операционной системы и от вводимых символов мало зависит. Конкретно мой код для Lazarus (специально сейчас проверил) вообще не реагирует на смену системного разделителя — поле ввода имеет текстовый формат.

В целом же, мой алгоритм ориентирован на типичные для русскоязычных пользователей случаи. В случае с использованием раскладок, отличных от RUS/ENG, алгоритм нужно проверять и, вероятно, немного изменять.
Разделители групп разрядов обычно не вводятся в поля ввода, они предназначены лишь для форматирования вывода. А для случая «скопировал число и вставил в поле» можно учесть лишь последний разделитель, если он отличается от остальных.
В html (в чистом) — нет, фильтровать нельзя (хотя в html5 что-то подобное уже появилось), но почти все операции по чистке/фильтрации/обработке значений можно выполнять на js.
Я делаю так: ввод не фильтрую вообще, но при поступлении нового символа проверяю регуляркой правильность (цифры 0-9 и один любой десятичный разделитель не в начале или конце). Если содержимое неверно — поле подсвечивается красным, иначе подсветка убирается. При отправке десятичный разделитель заменяю на нужный уже в недрах приложения (т.е. ввёл 10,45 ',' заменяется на '.' и уходит куда надо, но пользователь этого не видит)

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

У вас кто-то забрал нумпад?
требую добавить на него запятую!
Вы не поверите, в русской раскладке на нём появляется запятая.
Вы не поверите, но очень неудобно, когда в английской раскладке его там нет. Я использую MS Office на английском языке, формулы ввожу на английском, а запятую приходится нажимать как шифт+., неудобно.
Не понимаю, в чём ваша проблема: в английской раскладке запятая-без-шифта появляется в основном блоке клавиатуры.
Вы правы, я имел в виду, что не удобно вводить запятую не на Num Pad'е, а где-то еще. При быстром вводе это сбивает.
Вот именно эту проблему решает предложенный алгоритм, позволяя вводить числа без нумпада, не сбиваясь на переключение раскладки и нажатие Shift для ввода разделителя.
Попробуйте в реальной задаче использовать такой фильтр — и убедитесь, насколько быстро к нему привыкаешь.
Насколько мне известно, английская раскладка имеет точку и запятую на разных клавишах. На моей клавиатуре жать Shift не нужно. Насколько мне еще известно, что в английской, что в русской, что в немецкой раскладке в Экселе на numpad всегда запятая. Кстати, зависит эта «запятая или точка» от настроек Экселя, в зависимости от которых, он будет подставлять то, что задано а) системой, б) вами, на любом языке определяя этот знак в качестве разделителя десятичной части.
Насчет шифта я ошибся, да.
А вот что вы дальше написали — так не работает, к сожалению. В системе стоит русская локаль, Excel требует запятую в качестве разделителя. А на Num Pad'е вводится тот символ, который соответствует текущей раскладке, и в английской раскладке это точка.
Вам по какой-то причине не повезло. На трех разных машинках проверил (Win 7, Office 2007 | 2010, локаль рус. англ. и нем.), везде одно и то же. На всех языках при использовании точки на Numpad, Excel показывает один и тот же символ, заданный в настройках. Поковыряйтесь в настройках если интересно, фишка работает, эксель шарит))
Ух ты, спасибо за наводку, очень круто.
Но для этого приходится переключать раскладку, а речь идет об одном нажатии на нумпаде, так было бы в разы удобней.
И ввод числа туда, где нужно разделителем внести точку, сразу же становится очень веселым, ага.
Кстати, в случае с ноутбуком быстрый ввод десятичного разделителя представляет собой ещё большую проблему — встречал модели, у которых клавиша "?/.," была сдвинута.
Ну и нумпады есть далеко не у всех моделей, да.
На моем ноутбуке его никогда и не было.
Когда попеременно ведётся ввод текста и числовых данных большинство пользователей предпочитает не прыгать рукой к нумпаду. Но мы же не можем принудить всех пользователей использовать строго нумпад, поэтому проблема ввода разделителя с основного поля актуальна.
Есть еще пару грабель:
1) ввод отрицательных чисел и / или ведущего знака
2) ввод в научном формате с экспонентой (здесь может быть два знака плюса или минуса и буквенный символ E)
Перфекционистам работы хватит надолго.
С отрицательными числами вообще не вижу проблем — минимальные изменения алгоритма фильтрации позволят вводить ведущий символ "-".

Что касается ввода в экспоненциальном виде — это тоже не проблема, но в моём случае такой задачи не было, требовался ввод финансовых значений.
еще смешная проблема с функциями формата числа в строку — нагло норовят для пограничных чисел научный формат выдать, если за этим не уследить…
блокируем попытку ввода более чем одного десятичного разделителя.
И заставляем пользователя биться головой об стол в попытках перенести неправильно вставленный разделитель. Это, конечно, будет только в половине случаев, когда человек попытается сначала поставить вторую точку, но это всё равно выкручивание рук. Такое же как и блокирование неугодных типов десятичных разделителей.
До сих пор не было жалоб от пользователей на такое поведение. Хотя, как вариант, стоит «переставлять» разделитель в случае его повторного ввода.
Согласен, «переставление» в данном случае поможет. Появится неприятный эффект в тот момент, когда пользователь решит разделять разряды (107,239,202.00), но это уже экзотика.
Я с ходу не смог вспомнить ни одного приложения, где бы мне приходилось вручную вводить разделители разрядов. Но в целом, согласен — такой случай мой алгоритм не обработает. Можно попытаться его адаптировать, но, как минимум, нужно проверять системные настройки (разделители) и уже от них плясать.
Разделители и прочий мусор можно самому не вводить, а получить в наследство от копируемого текста. В таком случае в поле могут оказаться в лучшем случае пробелы, а в худшем — куски фраз («0го года. 12 395 единиц было произ») или криво распознанный текст («б4.О»). Если копировать из pdf-ки, с некоторой долей везения можно вставить текст задом наперёд.
Я в таких полях (не текстовых) обычно блокирую вставку из буфера. Но в принципе, можно отлавливать вставку из буфера и чистить приходящее значение. Как бы в любом случае при отправке поля в SQL-запрос надо следить за содержимым, а вставленное из буфера содержимое потенциально, имхо, более опасно, чем ввёдённое с клавиатуры (поскольку может содержать чёрте что).
За запрет вставки из буфера обмена вам следует гореть в аду. Хуже этого греха только запрет копирования в буфер обмена…
Имхо, многое зависит от конкретного случая. Например, есть АРМ, где оператор вводит финансовые значения в диапазоне примерно от 10 до 2000. Значения вводятся «с листа», т.е. всегда с бумажного носителя. Нужен там копипаст? Нет.
В других случаях, да, без копипаста не обойтись, но, как я уже сказал, тогда нужна строгая валидация и зачистка.
вставленное из буфера содержимое потенциально, имхо, более опасно, чем ввёдённое с клавиатуры (поскольку может содержать чёрте что).

Чем опасен текст в поле? Да ничем, пока вы его не отправили. Что мешает перед отправкой проверить его на валидность?
Копипаст нельзя запрещать.

Письмо усталому Василию поздно вечером:
Василий, готово, срочно отправляй контрагенту сумму 14127634,48!!!
Усталый Василий, проклиная разработчика, желая ему гореть так, чтоб излучал все возможные спектры, набивает цифры глядя из окна в окно, сверяясь 7 раз.
По поводу копипаста ответил чуть выше.

Что касается опасности, то тут как минимум два нюанса. Во-первых, чем «свободнее» ввод, тем строже должна быть валидация. Это само по себе не проблема. Во-вторых, при копировании вероятность ошибки оператора в ряде ситуаций повышается (в сравнении с ручным вводом). К примеру, оператор копирует в поле ввода число 11127634,44 — если оператор случайно не выделит первую или последнюю цифры при копировании, то шанс, что он заметит ошибку ниже, чем если бы он вбивал числа вручную, глядя из окна в окно.

PS. Повторюсь, всё зависит от конкретного случая, где-то копипаст необходим, но не везде.
Тут согласен — смотря для чего предназначено то или иное ПО. Выше говорили про разделитель разрядов — если это крупный международный проект (типа Excel) разумеется стоит заморочиться над парсингом таких данных, а если это операторская утилита, с которой работают 8 человек в небольшой конторе?
Excel — это вообще отдельная тема, в силу своей универсальности он позволяет очень многое, перекладывая ответственность на пользователя. Там и не может быть никакой фильтрации (хотя из-за этого тоже свои заморочки).

Но мы же говорим о разработке собственного ПО, а здесь именно на нас, как на разработчиков, ложится ответственность за удобство работы. Разумеется, всегда нужно исходить из конкретной задачи. В конце концов, это программа должна быть инструментом (удобным!) в руках пользователя, а не пользователь — инструментом (сам-себе-валидатором) в руках программы.

Даже если взять АРМ, которым пользуются в небольшой конторе, допустим, 8 человек. Допустим, сейчас это 8 опытных сотрудников, которые хорошо знают, что и куда вводить в формах — их можно строго не ограничивать. А если завтра на их место придут новые сотрудники, плохо знакомые с устоявшимися принципами ввода данных? Вот чтобы они дров не наломали, нужно внимательно следить за вводом, ограничивая возможность ввода некорректных данных.
Класс, поддерживаю на 100%. Сам однажды делал поле ввода в десктомном приложении, но сделал проще — так, чтобы можно в качестве разделителя хоть точку, хоть запятую вводить. Пользователи были довольны.
Такой вариант тоже возможен. Единственный нюанс — если введённые данные дальше попадают в SQL-запрос, то при отправке формы запятую придётся либо заменить, либо экранировать.
Если введенные данные попадают в SQL-запрос, то их надо преобразовать в число, а потом обратно. А еще лучше — использовать параметризованные запросы.
Преобразование в число — это само собой. Но тут тоже есть подводный камень. (всё дальнейшее рассуждение относится прежде всего к desktop-приложениям, в частности к написанным в Delphi-подобных IDE) Если, допустим, мы не фильтруем ввод, а валидацию проводим при отправке формы, то высока вероятность при попытке преобразования получить системное исключение. Понятно, что его не проблема отловить и обработать. Но при этом нам придётся вывести пользователю сообщение об ошибке. А это, в свою очередь, выбивает пользователя из «потока», отвлекая его от основной задачи — ввода данных.

PS. На эту тему (информирование пользователя об ошибках ввода) очень хорошо написано у Купера в «About Face» — рекомендую к прочтению всем, кто проектирует интерфейсы.
Как будто «экранировать» некорректные данные, не сообщая ничего пользователю — лучше
Всё зависит, опять-таки, от данных. Вернёмся к исходной теме поста. Скажем зачем забивать пользователю голову такой ненужной информацией, как тип десятичного разделителя? С точки зрения пользователя важно ввести данные (быстро и правильно). Если мы заставим его думать над тем, запятую ему вводить, или точку — он будет отвлекаться от основной работы.
Другое дело, когда данные вводятся в достаточно свободной форме — тогда имеет смысл сообщать об ошибке (по возможности — не модально).
Да тут вообще нет проблем как таковых. Выше я показал пример — проверка происходит «на лету», и до тех пор, пока данные не введены правильно, никаких преобразований и отправок быть не может.

Конкретно на той форме у меня около 12 числовых полей и один метод проверки на все. Если хоть одно неверно, при попытке нажать «сохранить» выскакивает сообщение «Проверьте подсвеченные поля», и всё. Если уж пользователь до этого не догадался.
Следующее бесячее поле ввода: даты.
Не холивара ради, но с разделителем в числах война всегда шла в приложениях на Delphi (и его коллегой Builder'е) и Excel'е, как правило в тех же приложениях было совсем ужасно с датами.
Уже не помню, как там в Delphi, а в Lazarus со вводом даты проблем вообще нет — есть отличный компонент TZVDateTimePicker, который при ручном вводе всё лишнее фильтрует (ну и выбрать из календаря позволяет, да). Разделитель при этом используется системный. Дальше — дело техники: в базу пишем значение даты, преобразованное в UnixTime, а при выводе — преобразуем обратно (при таком раскладе о разделителе можно сильно не беспокоиться).
Sign up to leave a comment.

Articles