Как сделать группу инпутов удобной

    Когда я работал над сервисом заметок jotsky.com, еще до работы в Островке, надо было сделать ввод телефонного номера из двух инпутов. Примерно такой:



    Я сделал навигацию с помощью стрелочек. Сделал, чтобы по мере заполнения фокус переключался к следующем инпуту. А вот сделать правильную вставку из буфера обмена у меня никак не получалось.

    Вставку из буфера можно реализовать установив атрибут maxlength с запасом. Для кода города его значение должно быть минимум длины телефонного номера, то есть не три, а десять.

    Проблема была даже не в том, чтобы между цифрами вставить еще цифры. А в том, что если зажать кнопку с клавиатуры и не отжимать, то поведение получалось очень странным: вначале заполняется один инпут на весь maxlength, потом пользователь отжимает клавишу и получает мерцание из-за того, что цифры распределяются по остальным инпутам.

    К слову, это был 2008 год, и единственная возможность, которую я видел, было спрограммировать все через setTimeout. Предвидя время разработки и неудовлетворительный результат, мы объединили эту форму в одну, которая дожила без изменений до наших дней.

    Прошли годы. Браузеры реализовали событие oninput. Сообщество популизировало событие onpropertychange в IE. А передо мной, уже в Островке, встала задача реализовать вставку из буфера обмена номера кредитной карты и заодно для поля срока ее действия.



    Это было знаком решить проблему в целом. С накопленным опытом и десятком юнит тестов, у меня получилось найти ту комбинацию остальных событий, при которых заполнение полей будет самым естественным для пользователя.

    Встречайте jQuery Group Inputs — плагин для группировки инпутов.

    Инпуты начинают вести себя будто у них общие данные:
    — Когда место заканчивается, каретка перемещается дальше
    — Кнопки вправо/влево перебрасывают каретку в следующий/предыдущий инпут
    — Вставка текста разбрасывает текст по инпутам, после вставки курсор встает так, как-будто это один инпут.

    Пример использования:
    <script src="jquery-1.7.2.js"></script>
    <script src="jquery.groupinputs.js"></script>
    <input type="text" maxlength="4" class="group1" name="">
    <input type="text" maxlength="4" class="group1" name="">
    <input type="text" maxlength="4" class="group1" name="">
    <input type="text" maxlength="4" class="group1" name="">
    <script>
         $('.group1').groupinputs();
    </script>
    


    Репозиторий на GitHub.
    Демо.

    Автор: lusever
    Ostrovok.ru 39,16
    Компания
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Похожие публикации
    Комментарии 98
    • +9
      Огромное спасибо
      • 0
        эээм… opera 11.64 Win XP. Копирую пример — не работает =)
        • 0
          Дык нет еще одного плагина. курсорс.чего-то там.
          Смотрите в демо, на гите.

          Кстати сделать бы опшн для замены не-цифр (при вводе телефона/карты с пробелами-черточками полезно)
          • 0
            Не уверен насчет версии 11, но в 12 сделал.
          • 0
            Да, да, Вилен, вот так это делается. Куча тестов, тщательный подбор событий, пробы, ошибки, правки… Годы работы. А не «а не зафигарить ли нам такую фичу!?».
          • +3
            Example -> выделить -> Ctrl + V в поле с первым инпутом, (неотпуская crtl с прошлого раза) CTRL + Z
            Если в первый импут вставить и попытаться нажать CTRL + A (я так всегда делаю, чтоб выделить и заменить) — то перескакиваем на второй импут, ещё до нажатия на A

            Как то по мне не удобненько
            • 0
              Второй пункт с CTRL+A срабатывает, если курсором ткнуть в конец текста в инпуте.
              • 0
                А в «Credit Card Example» такой баг не наблюдается.
                • +1
                  Прошу прощения, наблюдается, но при специфических условиях, см. выше.
                • +1
                  +Delete не работает между инпутами. Chrome 20 (омг, еще недавно был 10!), Linux x86.
                  • +1
                    У меня в хроме и фаерфоксе, если находиться в конце инпута и нажать просто на Ctrl, то перескакивает на следующий инпут. Думаю, это не сложно исправить :-)
                    • 0
                      Не только Ctrl, любая клавиша перебрасывает (лично у меня). Shift, Alt, Arrow Down, etc.
                    • +1
                      Спасибо, буду исправлять.
                      • 0
                        Исправил, спасибо.
                      • 0
                        Спасибо, удобная вещь. Не планируется ли возможность перезаписи существующих значений полей? Пример: заполнили все поля двойками, потом стрелками переместились в первое поле, и зажали тройку. Сейчас просто ничего не произойдет, а было бы здорово иметь возможность заменять текущее значение новым.
                        • 0
                          Я не планирую. Ниже есть обсуждение плагинов, из которых Masked Input точно умеет делать такое поведение, но для одного инпута.
                        • 0
                          В примере пробелы съелись.
                          • 0
                            Исправил, спасибо.
                            • 0
                              Я сначала подумал что это так и нужно, предположив что jqyery обрабатывает такие инпуты.
                          • +19
                            Чем не люблю такие поля — никогда не знаешь примет ли оно все значение целиком или придется копировать каждую часть по-отдельности.
                            • +4
                              Я привык в таких случаях сначала копировать значение целиком, получилось — отлично, сэкономил время; не получилось, ну и ладненько — первое поле заполнилось, остальные придётся по частям.
                            • +39
                              >> Как сделать группу инпутов удобными
                              Отказаться от группы инпутов и сделать один-единственный инпут. Номер карты позволить вводить через дефисы, через пробелы или слитно, код в номере телефона — в скобках, через дефис или через пробел.
                              • 0
                                Как вариант (можно в ненормальное программирование)
                                1 импут, наверстать на нём маленькие дивы вертикальными разделителями, и яваскриптом сделать вставку пробелов через каждые 4 символа.
                                • +4
                                  В jquery кстати есть плагин для ввода по маске, он сам разбивает текст по заданному шаблону, вставляет недостающие символы, вырезает лишние и вообще довольно умный + корректно работает с историей ввода реализованной как самим браузером так и сторонними плагинами того же jquery
                                  • 0
                                    имя, брат, имя?!
                                    • +1
                                      сейчас ниже столько плагинов накидают :)
                                      Надо только подождать, всё интересное в комментах, как всегда.
                                      • +1
                                        Да вот коммент написал а сам пошел вспоминать проект где использовал и искать)

                                        jquery.maskedinput звать

                                        Выбирал из нескольких, понравился этот. Самое в нем приятное, что служебные символы в маске, которые задаешь сам — например для номера (926) 234-2455 служебными могут быть (___) ___-____
                                        Эти символы как будто живут «вне» инпута и их нельзя удалить, перенести или вообще как-либо испортить, они всегда будут стоять на своих местах. При этом они нормально копируются вместе с текстом и не мегают вставке и вводу (курсор через них «перепрыгивает»)
                                        • 0
                                          Собственно сайт digitalbush.com/projects/masked-input-plugin/

                                          и там же живые примеры
                                          • 0
                                            Почти хороший, кроме того что при фокусе выделяет весь инпут, и в iOS курсор не очень правильно работает.
                                            • 0
                                              Выделение инпута при фокусе вполне стандартное поведение, не вижу проблемы в этом?
                                              • 0
                                                Это естественно для строки адресной строки браузера, или для поисковой строки. Для полей ввода естественно поставить курсор в место куда кликнули.
                                                • 0
                                                  Хмм пожалуй да, согласен. Думаю такое поведение можно «вылечить»
                                          • 0
                                            Вот этот плагин на основе маскединпута, но гораздо круче
                                            github.com/RobinHerbots/jquery.inputmaskhttps://github.com/RobinHerbots/jquery.inputmask
                                    • +1
                                      В опере вставка не работает
                                      • +8
                                        Вы что, судя по последним тенденциям большинство веб разработчиков вообще оперу за браузер не считают.
                                        • –1
                                          <Дядя Миша> У тебя какая-то неправильная Опера, называется Хром. Правильная Опера — это Мозилла.
                                          • 0
                                            И слава богу, может тогда ее доля вместе ие упадет
                                            • +1
                                              Монополия Хрома — это тоже не очень-то хорошо.
                                          • 0
                                            Исправил, проверял в 12ой, спасибо.
                                          • –1
                                            А кто-то всё это вводит вручную? Проще сохранить в текстовый файлик или keepass, да копипастить…
                                            • +13
                                              > Hacker
                                              > сохранить в текстовый файлик
                                              facepalm.jpg
                                              • +1
                                                Так он же hacker, вот и советует так, чтобы потом проще ломать было.
                                              • 0
                                                Мне кажется, Вы путаете понятия «разработчики» и «целевая аудитория сайта».
                                              • 0
                                                Неоднократно нарывался на неприятный момент в таких разделенных инпутах (особенно при установке Windows старых версий), когда глядя то в бумажку, то на клавиатуру пропускаешь один символ или вставляешь лишний. В вашем плагине при удалении символа в середине, правая часть не подтягивается влево. И добавить в середину тоже невозможно.
                                                • +7
                                                  Есть прекрасный плагин inputmask, который как раз позволяет в пределах одного инпута делать любые разделители. Это гораздо удобнее, чем возиться с энным количеством инпутов (не говоря уже о том, что на сервере это потом в одно значение надо собирать).
                                                  • +2
                                                    Это же стартап, там дух делать свои изобретения ещё не угас.
                                                    А за плагин плюсик, он действительно делает свою работу.
                                                    • +1
                                                      С моего пулл-реквеста там, кстати, русские символы в буквосодержащих масках работают :)
                                                      Так что активно используется в работе.
                                                    • 0
                                                      Мало того собирать на стороне сервера, это потом еще (когда человек захочет, например, отредактировать номер телефона) — обратно надо разбирать все на инпуты.
                                                    • +1
                                                      Мне нравится вот этот плагин. Тут его продолжение. Очень удобно.
                                                      • 0
                                                        Мне всё-таки кажется, при попытке вставить срок годности карты со случайно захваченным пробелом спереди его стоит вычистить.
                                                        • 0
                                                          Более того стоит вообще игнорировать все символы кроме цифр, зачем они нам.
                                                        • 0
                                                          После вставки через ctrl+v, если решишь перезаписать номер вручную, то не стирается предыдущее значение за курсором. Т.е. по моему у таких контролов должен быть что-то вроде replace mode, т.к. сейчас складывается ощущение что вообще readonly пока не выделишь и не удалишь. (chromium + ubuntu x64) последние версии.
                                                          • +1
                                                            ITU-T recommendation E.123 describes how to represent an international telephone number in writing or print, starting with a plus sign ("+") and the country code.

                                                            для кого эти стандарты пишут не понятно, тем более и jotsky.com вы сделали на английском, если б делали для одной страны ладно уже можно было и без "+".

                                                            • 0
                                                              Плюс действительно нужен. Я немного не однозначно написал.
                                                              Картинка примерно иллюстрирует как поле ввода выглядело давно. Сейчас оно выглядит по другому и там есть знак плюса.
                                                            • +1
                                                              А что насчет телефонов то в итоге? Сделали какое-нибудь решение?
                                                              Приведенное решение по очевидным причинам не подходит:

                                                              «Код страны», для русскоговорящей аудитории — +7 либо +375 либо +380 либо многие указывают «8». Т. е. maxlength мне какой ставить? 1, 2, 3 или 4?

                                                              «Код города» — от 3 до 5 цифр, например 495 у Москвы или 83531 у Алатыря
                                                              maxlength 3 или 5?

                                                              Соответственно последнее поле (номер телефона) — от 7 до 5 цифр в зависимости от города.
                                                              maxlength — 7? А если человек хочет указать добавочный (для корп. пользователей например распространенный формат +7 495 123-45-67 (доб. 231)
                                                              • –1
                                                                Для телефонов не подходит.
                                                                Мы остановились на select для кода города и input для продолжения.
                                                              • 0
                                                                надо было сделать ввод телефонного номера из двух инпутов
                                                                А вот интересно, зачем? Почему не одно поле?
                                                                • +3
                                                                  Некоторые люди, когда у них спрашивают номер телефона — вводят свой городской номер и не парятся.
                                                                  А ты гадай, из какого он города (или вообще — страны, если сайт ориентирован на СНГ)

                                                                  Поля «код страны» и «код города» служат напоминанием, что надо указать эти сведения.

                                                                  Masked Input и иже с ними — не панацея:
                                                                  Во-первых, если человеку предлагается ввести номер телефона, а поле ввода выглядит примерно так:
                                                                  +_ (___) ___-__-__
                                                                  это вводит его в небольшой ступор — причины объяснил выше:
                                                                  1. У старшего поколение сам такой внешний вид поля может вызвать недопонимание
                                                                  2. У пользователей из Украины и Беларуси код страны это 3 цифры а не одна. Если человек хочет указать бесплатный номер (8-800) указывать его в формате +7 800 не совсем верно.
                                                                  3. У пользователей из региональных городов в коде города может быть 4-5 цифр, а сам номер телефона — соответственно 6-5 цифр
                                                                  4. Если сайт ориентирован на корпоративных пользователей (которым как раз удобнее указывать городские номера) — им также удобно в поле «номер телефона» указывать сразу в скобках добавочный. Либо для добавочного делать отдельное поле.
                                                                  • 0
                                                                    Насчет города и городского телефона написал ниже.
                                                                    Насчет масок: мне кажется, пользователю надо позволять вводить символы произвольно, а не по маске. Не нужно пользователей держать за идиотов, неспособных ввести номер телефона.
                                                                    • 0
                                                                      Код страны/города можно подставлять, например.
                                                                  • +1
                                                                    Как по мне, так такого плана поля крайне неудобны.
                                                                    Почему не сделать 1 поле и уже на сервере разбивать значение как душе угодно? На клиенте по желанию, можно по событию (теряет фокус, достигает определенного кол-ва символов, таймаут) привести к нужному формату (добавить + к номеру телефона, разбить на группы и т.д.).
                                                                    • 0
                                                                      Некоторые люди, когда у них спрашивают номер телефона — вводят свой городской номер и не парятся.
                                                                      А ты гадай, из какого он города (или вообще — страны, если сайт ориентирован на СНГ)
                                                                      21-й век на дворе, по IP определите его город
                                                                      И потом, если даже он ввел только номер городского телефона, у вас не возникает подозрения, что в 7 введенных символах не уместить код города и телефон?
                                                                      • 0
                                                                        Промахнулся, это ответ на этот комментарий
                                                                        • +1
                                                                          по IP определите его город

                                                                          у нас например офис находится в Казани, но при этом все городские телефоны московские.

                                                                          не возникает подозрения, что в 7 введенных символах не уместить код города и телефон
                                                                          возникает, потому что в номере телефона должно быть 10 цифр + код страны.

                                                                          Понятно, что можно сделать, например, всплывающую подсказку «не забудьте указать код города» если человек ввел меньше 10 цифр.

                                                                          Но, все-таки лично я считаю, что гораздо лучше пользователю сразу дать понять, что от него хотят, чем потом ему напоминать и заставлять возвращаться к полю, которое он уже заполнил.

                                                                          И для этого поля «код города» — «номер телефона», как мне кажется, прекрасно выполняют свою функцию.
                                                                          • 0
                                                                            И для этого поля «код города» — «номер телефона», как мне кажется, прекрасно выполняют свою функцию.

                                                                            А мобильный номер как вводить? Там «кода города», формально нет.

                                                                            А чем вам не нравиться вариант с примером норма в самой форме (ну или рядом). Когда видишь в каком формате от тебя ждут номер — очень сложно ошибиться.
                                                                            • 0
                                                                              норма в виде
                                                                              "+_ (___) ___-__-__"?

                                                                              Я уже два раза ответил на этот вопрос — тем, что количество цифр в коде страны, города и номере телефона разное в разных городах и странах

                                                                              Там «кода города»

                                                                              Как показывает практика, пользователи в таком случае либо первые три цифры номера мобильного указывают как «код города» либо заполняют только поля «код страны» — "+7" и оставшуюся часть (912-345-67-89) вводят как «номер телефона», пропуская «код города».

                                                                              Заметьте, я нигде не уточнял, что «код города» — это обязательное поле. Оно нужно для напоминания (мол не забудьте указать код города), но если его не заполнить, при этом заполнив поле «номер телефона» — валидатор не должен выдавать ошибки.

                                                                              Обязательное поле «номер телефона». «Код города» и «код страны» — поля-напоминалки.
                                                                              • +1
                                                                                Я одного не понимаю — зачем просить пользователя разделить код страны, код города и собственно сам номер.

                                                                                Все равно использовать(т.е. звонить, руками или автоматизировано) нужно только «полный» номер.

                                                                                «Код города» и «код страны» — поля-напоминалки.

                                                                                Так и не увидел, чем вам не нравиться когда в форме присутвуют напоминалки-напоминалки — т.е. или пример в самом поле, либо пример рядом с полем. Оно же проще и компактнее.
                                                                        • 0
                                                                          На андроиде вставляется только в первый инпут. Или андроид не поддерживается?
                                                                          • 0
                                                                            Opera 12.00 — копипаста номера не работает. вставляется только в первый инпут
                                                                            • 0
                                                                              В какой-то момент забыл об опере, и не протестировал. Исправил.
                                                                            • 0
                                                                              Автору спасибо, было бы не плохо ещё реализовать такую фичу:
                                                                              при заполненных полях и вставке текста из буфера, скажем со второго символа (или первого), последующие символы заменялись новыми данными
                                                                              • +1
                                                                                В любом инпуте, кропе последнего, нажатие на End или Ctrl+→ перебрасывает каретку на следующий.
                                                                                • +1
                                                                                  Тоже самое при нажатии кнопки Home: хочу попасть в начало инпута, а перескакивает на следующий.
                                                                                • 0
                                                                                  Ох, здорово.
                                                                                  У меня руки не дошли вставку из буфера сделать, но такую же задачку решал.
                                                                                  Добавил еще работу Home/End.
                                                                                  Демка | GiHub
                                                                                  • 0
                                                                                    Теперь не работает выделение по Shift+[Home|End]. :)
                                                                                    • 0
                                                                                      Параллельно делали :)
                                                                                    • +2
                                                                                      Когда уже появится
                                                                                      <input type="creditcard">
                                                                                      
                                                                                      • 0
                                                                                        Ник автора показался знакомым, так и оказалось, раньше соотрудничали на фрилансе.
                                                                                        В другой статье из одного административного района человек.
                                                                                        Как узок мир.

                                                                                        А насчет планина, что сказать, не идеален, но весьма добротно реализован.
                                                                                        • 0
                                                                                          А нельзя просто отслеживать все события по нажатию кнопок и производить действия с контролами через js (обрубая дефолтную функциональность)?
                                                                                          Предложенное Вами решение мне видится штабелем заплаток, которое не факт, что не стрельнет где-то в каком-то браузере.
                                                                                          • 0
                                                                                            А ваше чем не заплатка.
                                                                                            В любом случае костыль получается. Всех вариантов не предусмотреть.
                                                                                            • 0
                                                                                              Сейчас так и поступают в редакторах кода. И я думал что бы сделать так. Но передумал по двум причинам:
                                                                                              1) Скорость мигания курсора не возможно взять из настроек ОС. Его все эмулируют.
                                                                                              2) Придется верстать инпуты, они не могут быть системными.
                                                                                            • 0
                                                                                              Отлично, спасибо!
                                                                                              И сразу бага: когда курсор находится в конце одного из заполненных инпутов, если при этом нажать Shift, курсор перемещается в следующий инпут. Нелогично это потому, что я нажимаю шифт, чтобы перескочить в предыдущий инпут при помощи Shift+Tab.
                                                                                              • 0
                                                                                                Да, исправил. Спасибо.
                                                                                              • 0
                                                                                                спасибо
                                                                                                • 0
                                                                                                  Казалось бы такая тривиальная задача, но далеко не всем хватает времени/желания ее реализовать в своих проектах. Спасибо большое.
                                                                                                  • +10
                                                                                                    Понасуют кривых скриптов на сайты, а потом сиди и мучайся: то вставка не работает, то выделение, то хрен знает как это заполнять с мобильника.
                                                                                                    • 0
                                                                                                      Вместо использования атрибута class для логики, лучше используйте data-* атрибуты. Оставьте class для представления.
                                                                                                      • 0
                                                                                                        Принято завязываться на классы. Так быстрее.
                                                                                                        • –1
                                                                                                          Ну, в истории веб дева много чего «принято». Таблицами верстать, 1х1-пиксельными гифами забивать… Плевать на кросс-браузерность и стандарты с высокой колокольни… Но это не значит, что так нужно делать всегда.

                                                                                                          То, что оно на синтетическом тесте в два раза медленнее я не спорю, но дело не в этом. Я более чем уверен, что data-* селекторы в будущем соптимизируют. А вот себя соптимизировать и писать по стандарту можно уже сейчас…
                                                                                                      • 0
                                                                                                        в демо при заполнении последнего поля номеря курсор не переходит на дату, поэтому демонстрацию считаю не полной ))
                                                                                                        • 0
                                                                                                          Можешь насладиться демонстрацией во время бронирования отеля :)
                                                                                                        • 0
                                                                                                          В iPade демо не срабатывает
                                                                                                          • 0
                                                                                                            Does not work in iOS

                                                                                                            К сожалению. В iOS нельзя сделать переместить фокус из одного ипута в другой.
                                                                                                          • 0
                                                                                                            Чего-то с кодировкой:

                                                                                                            asyncTest("paste symbols : [|◊] to [|◊]", function() {
                                                                                                            • 0
                                                                                                              Под маком отображаются) Заменил небезопасные символы. Спасибо.
                                                                                                            • 0
                                                                                                              Есть большой минус: если я заполнил первый инпут и нажал таб (стандартное поведение), то фокус автоматически переходит на 3-й инпут.
                                                                                                              Советую почитать, как с этим боролся Сергей Чикуёнок: chikuyonok.ru/2010/07/simple-things/
                                                                                                              • 0
                                                                                                                Один инпут всегда лучше нескольких. Лучше — когда данные, введённые в один инпут автоматически проверяются при вводе и при необходимости — разбиваются на группы, видимые пользователю.

                                                                                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                                                                Самое читаемое