Прикручиваем jQuery DatePicker к Webform

Главные вкладки

Аватар пользователя mrjavum mrjavum 13 апреля 2009 в 20:53

Захотелось мне к выбору даты в вебформе прикрутить какой-нибудь высплывающий календарь. Пошарился по инету - ничего готового не нашел.
Предлагаю свой способ решения данной задачи.

Захотелось мне к выбору даты в вебформе прикрутить какой-нибудь высплывающий календарь. Пошарился по инету - ничего готового не нашел.
Предлагаю свой способ решения данной задачи.
Считаем, что требуемые модули у вас установлены и уже создана нужная вебформа с компонентом выбора даты в виде выпадающих списков (select lists) - обычно этот вид установлен по-умолчанию.
Складываем скрипты date.js и jquery.datePicker.js в корневик вашей темы или в отдельную папку внутри каталога темы. Также поступаем с datePicker.css.
Я в своем примере все положил в корневик темы.
Также из каталога установленного модуля Webform в каталог своей темы копируем webform-form.tpl.php. Открываем его для редактирования и в самое начало дописываем такие строчки:

<?php
drupal_add_css
(path_to_theme() .'/datePicker.css');
drupal_add_js(path_to_theme() .'/date.js');
drupal_add_js(path_to_theme() .'/jquery.datePicker.js');
drupal_add_js(path_to_theme() .'/myDP.js');
?>

и сохраняем.
Далее в корневике создаем файл myDP.js и вписываем в него следующее:

$(document).ready(function(){

  // строки русификации используемых скриптов дат и самого календаря
  Date.dayNames = ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'];
  Date.abbrDayNames = ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'];
  Date.monthNames = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
  Date.abbrMonthNames = ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'];

  Date.firstDayOfWeek = 1;
  Date.format = 'dd.mm.yyyy';

  $.dpText = {
    TEXT_PREV_YEAR              :       'Предыдущий год',
    TEXT_PREV_MONTH             :       'Предыдущий месяц',
    TEXT_NEXT_YEAR              :       'Следующий год',
    TEXT_NEXT_MONTH             :       'Следующий месяц',
    TEXT_CLOSE                  :       'Закрыть',
    TEXT_CHOOSE_DATE    :       'Выберите дату',
    HEADER_FORMAT               :       'mmmm yyyy'
  }
  // конец блока русификации
 
  var cal;
        var $this;

        var checkForMouseout = function(event) //функция определения выхода курсора мыши за пределы календаря
        {
                var el = event.target;
               
                while (true){
                        if (el == cal) {
                                return true;
                        } else if (el == document) {
                                $this.dpClose();
                                return false;
                        } else {
                                el = $(el).parent()[0];
                        }
                }
        };

  // внутрь блока с выпадающими списками добавляем еще один пустой блок #wfdp
  $('#edit-submitted-date-wrapper div.container-inline').append('<div id="wfdp"></div>');
 
  $('#wfdp').datePicker({
                        // к блоку #wfdp привязываем наш календарь
                        // по умолчанию выбор дат начинается с текущей
                        // для изменения начальной даты используйте параметр startDate:'01/01/1995'
                                endDate:'31/12/2020' // задаем конец отрезка выбираемых дат
                        }
                ).bind(
                        // во время показа календаря следим за курсором мыши, пока он не выйдет за пределы календаря
                        'dpDisplayed',
                        function(event, datePickerDiv)
                        {
                                cal = datePickerDiv;
                                $this = $(this);
                                $(document).bind(
                                        'mouseover',
                                        checkForMouseout
                                );
                        }
                ).bind(
                        // привязывем показ календаря по клику
                        'click', function()
                        {
                                updateSelects($(this).dpGetSelected()[0]);
                                $(this).dpDisplay();
                                return false;
                        }
                ).bind(
                        // при выборе даты в календаре вызываем функцию апдейта положения выпадающих списков
                        'dateSelected',
                        function(e, selectedDate, $td, state)
                        {
                                updateSelects(selectedDate);
                        }
                ).bind(
                        // при закрытии календаря перестаем следаить за положением курсора мыши
                        'dpClosed',
                        function(e, selected)
                        {
                                updateSelects(selected[0]);
        $(document).unbind(
                                        'mouseover',
                                        checkForMouseout
                                );
                        }
                );
 
  var updateSelects = function (selectedDate) // функция обновления положения выпадающих списков
        {
                var selectedDate = new Date(selectedDate);
                $('#edit-submitted-date-day option[value=' + selectedDate.getDate() + ']').attr('selected', 'selected');
                $('#edit-submitted-date-month option[value=' + (selectedDate.getMonth()+1) + ']').attr('selected', 'selected');
                $('#edit-submitted-date-year option[value=' + (selectedDate.getFullYear()) + ']').attr('selected', 'selected');
        }
 
  $('#edit-submitted-date-day, #edit-submitted-date-month, #edit-submitted-date-year')
                .bind(
                        // привязываем изменение выбранной даты в календаре при изменении положения выпадающих списков
                        'change',
                        function()
                        {
                                var d = new Date(
                                                        $('#edit-submitted-date-year').val(),
                                                        $('#edit-submitted-date-month').val()-1,
                                                        $('#edit-submitted-date-day').val()
                                                );
                                $('#wfdp').dpSetSelected(d.asString());
                        }
                );
       
        // по умолчанию устанавливаем выбранной текущую дату
        var today = new Date();
        updateSelects(today.getTime());
       
        // и изменяем дату в календаре также на текущую
        $('#edit-submitted-date-day').trigger('change');
});

Названия блоков выпадающих списков можно подсмотреть в HTML-коде страницы с вебформой и заменить на нужные в вышепреведенном скрипте. В моем случае это:
#edit-submitted-date-day
#edit-submitted-date-month
#edit-submitted-date-year

Подсматривается легко:
для каждого элемента даты (день, месяц, год) ищите строку типа:<select name="submitted[date][day]" class="form-select" id="edit-submitted-date-day" >, где id зависит от имени вашего поля в настройках вашей вебформы.
#edit-submitted-date-wrapper - это блок, обрамляющий выпадающие списки даты, его название также зависит от заданного имени в настройках вебформы.
Далее в стиле вашей темы (обычно это файл style.css) дописываем стиль кнопки календаря:

a.dp-choose-date {
  width: 16px;
  height: 16px;
  line-height:100%;
  display: inline-block;
  background: url(images/calendar.png) no-repeat;
  overflow:hidden;
  text-indent:-2000px;
}

ну и темизируете эту кнопку - на ваш вкус и цвет, но это уже отдельная история.

Получившийся результат можете посмотреть здесь.

ВложениеРазмер
Иконка пакета WebFormDatePicker.zip16.5 КБ

Комментарии

Аватар пользователя gorr gorr 15 апреля 2009 в 11:25

Работает на показанном сайте, но с кодировкой почему-то глюк - вижу квадратики вместо букв в именах месяцев.

Аватар пользователя gorr gorr 16 апреля 2009 в 15:07

Да, теперь все в порядке. Можно было бы сделать открывание при наводе мышки, хотя это уже на чей вкус...

Аватар пользователя WildSW WildSW 20 июля 2009 в 1:29

Очень хорошо, вот бы это прикрутить к полю «Время создания»,
во время создания или редактирования ноды
в разделе «Информация об авторе», там формат такой вот 2009-07-16 20:13:05 +0300.

Может кто подскажет выход?

Аватар пользователя relogger relogger 4 августа 2009 в 16:28

<a href="mailto:WildSW@drupal.org">WildSW@drupal.org</a> wrote:
Очень хорошо, вот бы это прикрутить к полю «Время создания»,
во время создания или редактирования ноды
в разделе «Информация об авторе», там формат такой вот 2009-07-16 20:13:05 +0300.

Может кто подскажет выход?

да было бы удобно.