
Не знаю, то ли я плохо искал (на plugins.jqueri.com есть только один подобный — KitKatClock, но он несколько «недоработан»), то ли искать не хотел, то ли и в правду до такого элемента никому дела нет. В общем, поскольку часть интерфейса, которую я разрабатывал, была ориентирована на заполнение полей пальцем (целевая аудитория устройств — инфокиоски) или, реже, мышкой, а полей для ввода времени было предостаточно, я решил родить еще один
Итак. Постановка ТЗ.
- Основные задачи которые должен решать элемент — более быстрый ввод времени в поле, без клавиатуры. В идеале — в два щелчка. Алгоритм выбора времени должен быть интуитивно понятным;
- Изначальная ориентированность на сенсорные экраны. Элемент должен предотвращать нежелательное всплытие экранной клавиатуры устройства; грамотно позиционироваться на экране так, чтобы, по возможности, не закрывать поле ввода и не выходить за пределы экрана;
- На десктопных машинах не мешать (а лучше — помогать) пользователю заполнять поле с клавиатуры, если он использует её как преимущественное средство ввода. Помощь может заключаться, скажем, в автоподстановке разделительного «:» символа. Т.е. человеку достаточно вводить только цифры;
- Обеспечивать совместимость со старыми браузерами. Да, да — без IE6 никуда. В целевых инфокиосках используется специализированное ПО, базирующееся на библиотеках сами-знаете-кого и именно той версии;
- Обеспечить совместимость с jQueryUI Calendar. Наш элемент должен корректно работать с полями, к которым уже присоединен любимый нами календарь, дополняя его и не мешая ему;
- Подключение и использование должно быть простым.
Подключение элемента почти тривиально:
<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 не удалось. Календарь, когда был скрыт, упорно возвращал текущую дату, а не выбранную ранее в поле.Желающим протестировать работу элемента добро пожаловать.
Проект, как повелось, на гитхабе.