В сети полно чудовищных скриптов для наглядного выбора даты с помощью указателя мыши. Эти скрипты не могут быть не чудовищными по определению, так как созданы для позорной задачи: облегчить жизнь пользователям, не желающим набирать даты цифрами, с клавиатуры. Ну, и программистам, в общем, тоже – чтоб не встать в ступор от введённой с точками даты ("15.06.2011"), когда серверный скрипт знает только чёрточки ("15-06-2011").
Долго я не хотел заниматься этим datepicker'ом. Но клиенты задолбали, и вот наступило "а придётся". Ну, как я уже сказал в начале (не удержался), готовые скрипты в сети в большинстве своём оказались чудовищны. Календарь jQuery, наиболее полный по функционалу, был отбракован из-за чудовищности самой jQuery (ничего личного! :-)). То же и по другим библиотекам – религия не позволяет мне загружать сайты клиентов сотнями килобайт лишнего кода, когда можно обойтись парой сотен строк.
Календарь, о котором речь, – как раз такой случай: весь код занимает немногим более 200 строк (7 К). Вот дистрибутив: calendar_ir2.zip, для работы нужны файлы calendar.js и calendar.css (calendar.htm – для примера).
1. Добавить к HEAD HTML-страницы две строчки:
2. Полям ввода (input), в которые надо вставлять даты, назначить класс "date" (<input name='' class='date'>)
Массив календаря (месяцы, даты и дни недели) создаётся на один год. При загрузке – на текущий год, при выборе года – на выбранный год.
При щелчке по полю ввода (гм... и при активации с помощью Tab тоже) отрисовывается календарь на месяц. Помещается над полем ввода (если есть место) или под полем ввода (если сверху места не хватает, или если позицию клика определить нельзя).
По умолчанию отрисовывается текущий месяц, при выборе месяца – выбранный месяц.
При щелчке по дате дата вставляется в поле ввода. При потере фокуса полем ввода календар исчезает. При нажатии escape – тоже исчезает.
Объект календаря не цепляется к полям ввода – к ним цепляется только onclick, по которому отрисовывается календарь – по умолчанию (текущий год и месяц) или, если дата была выбрана, месяц и год выбранной даты.
В объект window.dict.calendar можно помещать две вещи:
1) разделитель даты (например, чёрточку или точку): dict.calendar.div = '.';
2) массив знаменательных дат и праздников (можно присылать его с сервера):
Знаменательные даты из массива отлавливаются при создании объекта календаря и соответствующие числа помечаются ма-аленькой красненькой меткой, лежащей в папке дистрибутива img, а также датам добавляется title с названием праздника.
Ну, что ещё... Вся локализация определяется в объекте lang внутри функции календаря: формат даты (d-m-Y), названия дней недели, начало недели (понедельник)... Это всё легко можно заменить на чужие реалии. Но зачем?
Рабочий пример: http://ir2.ru/static/calendar.htm
Простите, может не все внимательно прочитал, но не нашел ответ на такой вопрос. Я с JS не дружу. Но календарь понравился и при использовании его много плюсов, но есть проблема. Если дата выбирается из календаря, то при повторном смены даты в этом поле календарь показывает ту дату, которая была выставлена, а вот если в поле даты уже была вписана дата ранее (другим способом), то при смене, календарь открывается не на ту дату, которая была в поле, а на текущую. Как сделать, чтобы дата в календаре открывалась та, которая уже была записана в этом поле? Особенно неудобно, когда нужно снова выбирать месяц и год. Заранее спасибо.
funnybunny, уточняю: initCalendar(null, el) – null – это событие браузера (которого в данном случае нет)
funnybunny, если вы создаёте объекты на javascript, то вызывать функцию initCalendar можно из любого созданного вами объекта – просто написать где-нибудь в середине кода волшебное слово initCalendar(el), где el – это html-элемент input, к которому следует привязать календарь
Дилетант, Подскажите, initCalendar из какого объекта вызывать?
Василий, надо назначать события для Body с помощью функции addLoadEvent (а не просто писать body.onload=...)
funnybunny, надо допиливать руками: пробежаться в цикле по нужным элементам (инпутам) и для каждого элемента вызвать функцию initCalendar(null, el), где el – текущий элемент, к которому надо привязать Календарь
EURO_KOLYAN, да, можно такой тип свободной лицензии использовать (как бы неявно предполагается из контекста статьи)
Подскажите, пожалуйста, как этот datepicker к динамически создаваемым элементам привязывать: – если в html прописать – работает; – если элемент по js событию создается – нет
какой тип лицензии в дипломе прописать на использование этого календарика?? GNU LESSER GENERAL PUBLIC LICENSE ?
После перехода на зимнее время перестал работать календарь, на компе где не установлен апдэйт KB2998527 – все отображается нормально!
Перестал работать!!!
Тезка! Благодарю за простой и дельный код. Сам лично стараюсь уйти от загрузки лишних кодов без исключительной надобности, и уж тем более библиотек типа jQuery.
D.M., admin Большое спасибо, давно искал что-то подобное. Но вот вопрос: если для body страницы назначено событие onload, то календарь не отображается. Убираем onload – и всё опять работает хорошо. Пробовал в нескольких браузерах – эффект один и тот же.
С явой столкнулся впервые. Подскажите, пожалуйста в каком месте задается диапазон года? чтобы его увеличить какие параметры поменять надо?
passer-by,
не надо в тэге писать onClick='functionName()', в современных сайтах так редко делают. Это называется "ненавязчивый javascript" – поищите в Яндексе эту фразу.
Андрей,
это ж столет назад писалось, я уже не помню. На первый взгляд, в файле calendar.js есть параметр:
year_offset = 5
А начальный год, видимо, текущий. Надо найти его в коде и заменить на любой другой.
Так как JS я знаю не очень хорошо, пока не разобрался что заставляет появиться календарь при нажатии на <input>. Из того что видел раньше в теге input писали обычно onClick='functionName()'. А здесь ничего подобного нет. Проясните плиз. Такое ощущение, что при загрузке страницы в память также грузится файл calendar.js...
Serj, минус перед функцией, чтобы она сразу выполнилась (немедленно после загрузки) и исчезла из памяти (ну, кроме глобальных переменных). Читайте об этом подробнее на сайте javascript.ru
Спасибо. То, что надо. Свистелки и перделки фтопку.
В файле calendar.js на 15 строке: "-function ()", за чем минус перед функцией и почему без него ни чего не работает?))) спасибо.
Для неКодер и Пчеловод
Чтобы "левые" строки не добавлялись в список месяцев, можно добавить в функцию buildField после строки
for (id in idxs) {
строку
if (!idxs.hasOwnProperty(id)) continue;
Отличный календарь, спасибо
to Пчеловод Я чтобы долго не разбираться, тупо и программистски некрасиво ограничил формирование списка элементов 12тью элементами (см. ф-цию buildField) var i=0; for (id in idxs) { if(i < 12){params = {value:id} ac(buildEl2('option', params, idxs[id]), el)} i++ }
А можно ка-то подружить календарь с Mootools? При использовании на странице в подключенным mootools в список месяцев добавляется несколько строк с определением функций на JS.
Вариант календаря на jquery divhack.com/node/76 =)
-- фтопку жикверь
Да ничего страшного. Где уж там "резковато". Посмотрите, как отвечают на каком-нибудь phpclub.ru.
Ярослав, а выбор времени – это как? выпадающий список из 60-ти минут?..
Возможно, я несколько резковато ответил, Дилетант. Не обижайтесь. Спасибо за подсказку. Что касается подсчета количества дней, постараюсь эту задачу реализовать на JS. Негоже по всякой мелочевке гонять на сервер. Относительно остальных задач, есть один сайт, где это можно подсмотреть. Просто пока руки не дошли до анализа.
Спасибо за отличный и простой скрипт.
было бы не плохо сделать выбор времени)
Trofim, почём вы знаете, что я не разработчик. Это ведь бывает очень по-разному. Сегодня вы лицо официальное, а завтра, глядишь, и совсем наоборот...
Скрипт подсчёта дней есть здесь на php: http://ir2.ru/static/Propis.php (описание функции time-diff: propis.aspx). Если надо именно на js, посмотрите на форуме http://javascript.ru/forum/, там, где-то в разделе "Готовые решения" я видел.
Дилетант, у Вас ник слишком откровенный, чтобы вступать с Вами в дискуссию. Хотелось бы узнать мнение разработчика. Можно даже на почту, чтобы не засорять Форум.
Trofim, я бы сказал, что это, скорее, ошибка. Такие вещи обычно рассчитывают на стороне сервера, используя информацию, хранимую в БД. Потому что там слишком много параметров. А если надо отображать результаты вычислений без перезагрузки страницы, то использовать ajax.
Alex,
там где-то в начале кода есть объект lang, а в нём функция makeDate. Это зачаток мультиязычности. Чтобы вырастить его в норм. дерево, надо удалить текст функции, написать там взамен: "makeDate: [Имя_моей_функции]", ну, а уже в своей функции вы можете определять какой угодно формат вывода даты.
Да. А лучше, конечно, весь объект lang определять снаружи Календаря (его вообще можно присылать с сервера).
Наверное, хамство с моей сторны, но нельзя ли выложить код с кнопкой (количество дней), при нажатии на которую выдавалось бы количество дней в выбранном интервале. Про подсчет стоимости за выбранный период и выбор валюты расчета я вообще молчу. Такая вещь может пригодиться на сайте гостиницы. Чтобы посетитель мог на странице прикинуть стоимость проживания.
Андрей,
Календарь не стоит на месте, ему требуются всё новые и новые настройки, здесь я их не меняю (использую новые наработки на рабочих сайтах). Вот, попытался выдрать последнюю версию, выкладываю: http://ir2.ru/static/calendar2.htm
А как вывести дату в новой версии в формате YYYY-MM-DD ?
Так! А как сделать чтобы календарь при клике на поле ввода считывал дату и отображал уже выделенную дату? К примеру если я вручную сразу задаю поля или потом изменяю, то после клика текущей дате календарь отображает по умолчанию (текущий год и месяц). Доработайте плиз :)
Спасибо, довно искал такой простой скрипт календаря.
Саша, вроде бы, даже Яндекс пока не придумал, как ленивому пользователю найти информацию чисто тычками мыши (совсем без клавиатуры). Я лишь немного задел эту тему (чтоб с чего-то начать разговор). Ну, полемически преувеличил...
"Зачем нужны datepicker'ы? Ясно, что нормальному пользователю не влом набрать дату цифрами с клавиатуры."
Интересная логика, однако. А зачем тогда вообще делать сайты? Ясно ведь, что нормальному пользователю не влом до всего на свете додуматься самому, и все сделать своими руками. А мы только время зря тратим.
Роман,
календарь закрывается по клавише Esc. Видимо, на вашем железе виртуальная клавиатура закрывается с помощью того же кода. Можно убрать из кода календаря одну строчку, и он не будет закрываться по "коду 27" – Esc. Найдите там у себя эту строчку и удалите её:
if (27 == e.keyCode) {hidTemp()}
Все здорово! Одна проблема, если смотришь сайт с IPAD, при установке фокуса в поле выскакивает виртуальная клавиатура, которая в режиме ландшафт перекрывает календарь. Если ее закрыть, закрывается и календарь. Можно это как-то побороть?
Супер! Спс!
Ваня, а то ж! Это всё Пыхе спасибо (http://pyha.ru/), там помогли отладить работу скрипта.
Отличная работа! Как раз искал календарь с минимумом кода. И подключение простейшее, и код несложно подправить под себя.