jQueryUI timePicker — виджет для выбора времени

image В процессе работы над корпоративным проектом нередко приходится переключаться на задачи разработки пользовательского интерфейса. Конечно, для реализации фронт-энда мы уже давно не изобретаем велосипеды, а используем готовые компоненты. Казалось бы, на все случаи жизни уже есть свой плагин, но недавно я с удивлением обнаружил, что для поля выбора даты существует огромное количество реализаций элементов-календарей, а вот поле выбора времени как-то обходится стороной.

Не знаю, то ли я плохо искал (на plugins.jqueri.com есть только один подобный — KitKatClock, но он несколько «недоработан»), то ли искать не хотел, то ли и в правду до такого элемента никому дела нет. В общем, поскольку часть интерфейса, которую я разрабатывал, была ориентирована на заполнение полей пальцем (целевая аудитория устройств — инфокиоски) или, реже, мышкой, а полей для ввода времени было предостаточно, я решил родить еще один никому не нужный jquery-плагин.

Итак. Постановка ТЗ.
  1. Основные задачи которые должен решать элемент — более быстрый ввод времени в поле, без клавиатуры. В идеале — в два щелчка. Алгоритм выбора времени должен быть интуитивно понятным;
  2. Изначальная ориентированность на сенсорные экраны. Элемент должен предотвращать нежелательное всплытие экранной клавиатуры устройства; грамотно позиционироваться на экране так, чтобы, по возможности, не закрывать поле ввода и не выходить за пределы экрана;
  3. На десктопных машинах не мешать (а лучше — помогать) пользователю заполнять поле с клавиатуры, если он использует её как преимущественное средство ввода. Помощь может заключаться, скажем, в автоподстановке разделительного «:» символа. Т.е. человеку достаточно вводить только цифры;
  4. Обеспечивать совместимость со старыми браузерами. Да, да — без IE6 никуда. В целевых инфокиосках используется специализированное ПО, базирующееся на библиотеках сами-знаете-кого и именно той версии;
  5. Обеспечить совместимость с jQueryUI Calendar. Наш элемент должен корректно работать с полями, к которым уже присоединен любимый нами календарь, дополняя его и не мешая ему;
  6. Подключение и использование должно быть простым.


Подключение элемента почти тривиально:

<link rel="stylesheet" href="clock-ui.css" type="text/css"/>
<script language="javascript" src="clock-ui.min.js"></script>

Правда, есть одно но. Элемент использует изображения. И эти изображения могут располагаться у вас совсем в других местах. Изображения же прописаны в стилях. То есть используя такой элемент на своем сайте, вы должны поместить картинки куда надо, а затем внести соответствующие изменения в стили.

Скрытый текст
Я думал об использовании dataURI. Но, во-первых, css-файл становится объемным (что не хорошо), а во-вторых, IE это не нравится. Если кто расскажет как элегантно решить эту задачу, буду признателен.

Скрытый текст
Я думал об использовании SVG. Даже потратил 4 часа (!) на то, чтобы нарисовать часики в Xara Xtreme. Но к сожалению, Xara, при попытке экспортировать файл из родного формата в SVG, либо вылетает с ошибкой, либо сохраняет пустой файл. Жалко потраченного времени. Если есть добрые люди, способные сделать экспорт, будут рад. Обязательно соберу версию элемента на чистом SVG.
Вот этот файл.


Активация элемента еще проще:

$('input.time').timePicker();

Здесь мы связываем все текстовые поля, имеющие класс time, с нашим элементом. Причем допустимы повторные вызовы.

Можно вызывать для полей, связанных с календарем, при условии, что первым инициализируется календарь. Чтобы timePicker смог вставлять значение времени в такие совмещенные поля, необходимо у datePicker задать в опции dateFormat (и/или в altFormat) символ 'T' отделенный хотя бы одним пробелом:

$('.date')
		.datepicker({dateFormat: 'dd.mm.yy T'})
		.timePicker();

Если у календаря существует altField и altFormat и также содержит 'T', время будет устанавливаться и в нем.

Элемент timePicker поддерживает инициализацию с опциями. Опций не так много, но они есть.
  • Параметр touchscreen говорит элементу: является ли текущий тип устройства сенсорным? На самом деле элемент сам умеет определять такие устройства. Однако в процессе тестирования на инфокиосках столкнулись с тем, что экраны инфокиосков хоть и являются сенсорными, встроенный браузер события touchstart не поддерживает. Что приводило к неправильной работе элемента. Используйте параметр для решения таких ситуаций.
  • Параметр compatible (по умолчанию true). Предназначен для обеспечения совместимости со старыми браузерами. Например, элементу нужно, чтобы браузер обязательно поддерживал border-radius и background-size — иначе верстка станет не корректной. Если поддержка этих свойств есть, смело устанавливайте compatible = false, например так:

    $('.time').timePicker({
        compatible: !(Modernizr.backgroundsize && Modernizr.borderradius)
    });
    

  • Параметры defaultHour, defaultMinute задают время «по умолчанию» для пустых полей. Время задается в 12-часовом формате (от нуля). Параметр PM (логический) указывает на после полуденное время. Например, код ниже заставит элемент считать, что у пустых полей (или изначально некорректно заполненных), время равно 12:00:

    $('.time').timePicker({
        defaultHour: 0, defaultMinute: 0, PM: true
    });
    

  • Наконец, onOpened, onClosed устанавливают ваши обработчики на соответственно открытие и закрытие виджета. Важное замечание: обработчик вызывается уже после того, как виджет изменит свою видимость.


Существует два способа получить значение времени, выбранного в поле.

Первый: непосредственно считать value поля. В нашем проекте такие поля идут как строки и анализируются на стороне сервера, поэтому такое решение нас вполне устраивает.

Второй: можно прочитать время в «сыром» формате, например, так:

var hours = $('#element').data().hours,
    minutes = $('#element').data().minutes,
    pm = $('#element').data().pm_time;

Наконец, если вам необходимо получить время в unix-формате (в секундах от начала cуток), используйте:

$('#element').date().time;

Скрытый текст
Для элементов, связанных с календарем, хотелось сделать получение даты и времени более элегантно, через
$('#element').datepicker('getDate')
Но к сожалению, повлиять на дату элемента datePicker через getDate/setDate не удалось. Календарь, когда был скрыт, упорно возвращал текущую дату, а не выбранную ранее в поле.


Желающим протестировать работу элемента добро пожаловать.

Проект, как повелось, на гитхабе.
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 21

    0
    jQueryUI плагин, но оформлен не как jQueryUI плагин. Настоятельно советую прочитать тут jqueryui.com/widget и тут wiki.jqueryui.com/w/page/12138135/Widget%20factory. Не пишите комментарии на русском, это не комильфо и априори не по стандартам.
      +13
        0
        Мне этот больше понравился, чем предоставленный в статье.
        Ибо аутентичное положение стрелок это одно, но удобство такого выставления времени, когда нужно постоянно сверяться с результатом в цифрах — это другое. В приведенном выше примере всегда понятно, какой час выбран.
          0
          Есть ванильный вариант =) github.com/YouMeb/clockpicker.vanilla
          • UFO just landed and posted this here
              0
              Самый крутой из трех. Выбор ближайшей к клику стрелки — самое естественное пользовательское взаимодействие — как бы ты и сделал с реальными часами. Анимации и смену циферблатов если убрать — вообще идеально будет.
            0
            отлично работает, вот бы еще этот пикер заиметь для Angular-а…
              0
              Так легко написать директиву, которая обернет этот виджет. Как-то раз нашел интересный подход github.com/jmcpeak/jquery-widget
            0
            Версия под iOS ведет себя иначе, чем под винду — при открытии стрелки крутятся, что смущает (раздражает) и нельзя потаскать за стрелки, хотя два тапа работают очень логично. А вот на компе при открытии стрелки не крутятся, но два клика не работают, можно только потаскать за стрелку.
              +2
              Странно что не нашелся вот этот вот плагин — trentrichardson.com/examples/timepicker/
              Еще года 4 назад искал и сразу же наткнулся.
                0
                Ну тут же рассмотрели эмулятор циферблата) А так да, есть еще уйма интересных плагинов для таймпикера.
                  0
                  Ах вот оно что! А я из статьи и не уловил.
                +8
                Шесть раз прокрутил часовую стрелку, прежде чем понял, что AM\PM переключается по клику. Ну уж нет.
                  +5
                  Ах эти сладострастные пытки в интерфейсах корпоративного ПО… Родные мои…
                  • UFO just landed and posted this here
                    +9
                    В мире стало больше неудобных интерфейсов.
                      0
                      Вот этим пользуемся, всего два клика.
                        0
                        К сожалению пока нету ни одного достойного плагина. Все что есть работает исключительно в часовом поясе сервера. Везде нужно дорабатывать напильником чтобы работало с таймзоной.
                        +1
                        Переключатель AM/PM как мне кажется должен перещелкиваться автоматически при прокрутке часовой стрелки через «12».
                          0
                          Ещё один аналог в копилку: vitalets.github.io/clockface/

                          Only users with full accounts can post comments. Log in, please.