...

понедельник, 24 ноября 2014 г.

[Из песочницы] jQueryUI timePicker — виджет для выбора времени

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

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



Итак. Постановка ТЗ.



  1. Основные задачи которые должен решать элемент — более быстрый ввод времени в поле, без клавиатуры. В идеале — в два щелчка. Алгоритм выбора времени должен быть интуитивно понятным;

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

  3. На десктопных машинах не мешать (а лучше — помогать) пользователю заполнять поле с клавиатуры, если он использует её как преимущественное средство ввода. Помощь может заключаться, скажем, в автоподстановке разделительного «:» символа. Т.е. человеку достаточно вводить только цифры;

  4. Обеспечивать совместимость со старыми браузерами. Да, да — без IE6 никуда. В целевых инфокиосках используется специализированное ПО, базирующееся на библиотеках сами-знаете-кого и именно той версии;

  5. Обеспечить совместимость с jQueryUI Calendar. Наш элемент должен корректно работать с полями, к которым уже присоединен любимый нами календарь, дополняя его и не мешая ему;

  6. Подключение и использование должно быть простым.


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









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

Я думал об использовании 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 не удалось. Календарь, когда был скрыт, упорно возвращал текущую дату, а не выбранную ранее в поле.


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


Проект, как повелось, на гитхабе.


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий