diff --git a/README.md b/README.md index 4a572ec..06042f4 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,11 @@ Call the datepicker via javascript: ## Dependencies -Requires bootstrap's dropdown component (`dropdowns.less`). +Requires bootstrap's dropdown component (`dropdowns.less`) for some styles, and bootstrap's sprites (`sprites.less` and associated images) for arrows. + +A standalone .css file (including necessary dropdown styles and alternative, text-based arrows) can be generated by running `build/build_standalone.less` through the `lessc` compiler: + + $ lessc build/build_standalone.less datepicker.css ## Options diff --git a/build.less b/build/build.less similarity index 89% rename from build.less rename to build/build.less index edc917d..8de0a3b 100644 --- a/build.less +++ b/build/build.less @@ -1,13 +1,10 @@ -// Datepicker .css buildfile. Includes select mixins/variables from bootstrap +// Datepicker .less buildfile. Includes select mixins/variables from bootstrap // and imports the included datepicker.less to output a minimal datepicker.css // // Usage: -// lessc build.css css/datepicker.css +// lessc build.less datepicker.css // // Variables and mixins copied from bootstrap 2.0.2 -// -// Mixins must be included individually, else some (eg, .clearfix) will be -// included in the built .css // Variables @grayLight: #999; @@ -66,4 +63,4 @@ } } -@import "less/datepicker.less"; +@import "../less/datepicker.less"; diff --git a/build/build_standalone.less b/build/build_standalone.less new file mode 100644 index 0000000..b0dc24b --- /dev/null +++ b/build/build_standalone.less @@ -0,0 +1,69 @@ +// Datepicker standalone .less buildfile. Includes all necessary mixins/variables/rules from bootstrap +// and imports the included datepicker.less to output a minimal standalone datepicker.css +// +// Usage: +// lessc build_standalone.less datepicker.css +// +// Variables, mixins, and rules copied from bootstrap 2.0.2 + +@import "build.less"; + +// Dropdown css + +@zindexDropdown: 1000; +@grayDark: #333; +@baseLineHeight: 18px; +@tableBackground: transparent; // overall background-color +@dropdownBackground: @white; +@dropdownBorder: rgba(0,0,0,.2); +@dropdownLinkColor: @grayDark; +@dropdownLinkColorHover: @white; +@dropdownLinkBackgroundHover: @linkColor; + +// Drop shadows +.box-shadow(@shadow) { + -webkit-box-shadow: @shadow; + -moz-box-shadow: @shadow; + box-shadow: @shadow; +} + +// The dropdown menu (ul) +// ---------------------- +.datepicker.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: @zindexDropdown; + float: left; + display: none; // none by default, but block on "open" of the menu + min-width: 160px; + list-style: none; + background-color: @dropdownBackground; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,.2); + .border-radius(5px); + .box-shadow(0 5px 10px rgba(0,0,0,.2)); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + *border-right-width: 2px; + *border-bottom-width: 2px; + + // Normally inherited from bootstrap's `body` + color: #333333; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; + font-size:13px; + line-height: @baseLineHeight; + + th, td { + padding: 4px 5px; + } +} + +// Alternative arrows +// May require `charset="UTF-8"` in your `` tag +.datepicker { + .prev, .next {font-style:normal;} + .prev:after {content:"«";} + .next:after {content:"»";} +} diff --git a/js/bootstrap-datepicker.js b/js/bootstrap-datepicker.js index 7ee6091..14f49c0 100644 --- a/js/bootstrap-datepicker.js +++ b/js/bootstrap-datepicker.js @@ -24,7 +24,8 @@ var Datepicker = function(element, options){ this.element = $(element); - this.language = options.language in dates ? options.language : "en"; + this.language = options.language||this.element.data('date-language')||"en"; + this.language = this.language in dates ? this.language : "en"; this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy'); this.picker = $(DPGlobal.template) .appendTo('body') @@ -34,6 +35,8 @@ }); this.isInput = this.element.is('input'); this.component = this.element.is('.date') ? this.element.find('.add-on') : false; + if(this.component && this.component.length === 0) + this.component = false; if (this.isInput) { this.element.on({ @@ -45,6 +48,10 @@ } else { if (this.component){ this.component.on('click', $.proxy(this.show, this)); + var element = this.element.find('input'); + element.on({ + blur: $.proxy(this._hide, this) + }) } else { this.element.on('click', $.proxy(this.show, this)); } @@ -73,8 +80,8 @@ break; } - this.weekStart = options.weekStart||this.element.data('date-weekstart')||dates[this.language].weekStart||0; - this.weekEnd = this.weekStart == 0 ? 6 : this.weekStart - 1; + this.weekStart = ((options.weekStart||this.element.data('date-weekstart')||dates[this.language].weekStart||0) % 7); + this.weekEnd = ((this.weekStart + 6) % 7); this.startDate = -Infinity; this.endDate = Infinity; this.setStartDate(options.startDate||this.element.data('date-startdate')); @@ -501,7 +508,8 @@ this.show(); return; } - var dir, day, month; + var dateChanged = false, + dir, day, month; switch(e.keyCode){ case 27: // escape this.hide(); @@ -523,6 +531,7 @@ this.setValue(); this.update(); e.preventDefault(); + dateChanged = true; break; case 38: // up case 40: // down @@ -540,12 +549,28 @@ this.setValue(); this.update(); e.preventDefault(); + dateChanged = true; break; case 13: // enter this.hide(); e.preventDefault(); break; } + if (dateChanged){ + this.element.trigger({ + type: 'changeDate', + date: this.date + }); + var element; + if (this.isInput) { + element = this.element; + } else if (this.component){ + element = this.element.find('input'); + } + if (element) { + element.change(); + } + } }, showMode: function(dir) { @@ -662,7 +687,9 @@ validParts: /dd?|mm?|MM?|yy(?:yy)?/g, nonpunctuation: /[^ -\/:-@\[-`{-~\t\n\r]+/g, parseFormat: function(format){ - var separators = format.split(this.validParts), + // IE treats \0 as a string end in inputs (truncating the value), + // so it's a bad format delimiter, anyway + var separators = format.replace(this.validParts, '\0').split('\0'), parts = format.match(this.validParts); if (!separators || !separators.length || !parts || parts.length == 0){ throw new Error("Invalid date format."); diff --git a/js/locales/bootstrap-datepicker.da.js b/js/locales/bootstrap-datepicker.da.js new file mode 100644 index 0000000..33aaf61 --- /dev/null +++ b/js/locales/bootstrap-datepicker.da.js @@ -0,0 +1,13 @@ +/** + * Danish translation for bootstrap-datepicker + * Christian Pedersen + */ +;(function($){ + $.fn.datepicker.dates['da'] = { + days: ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag", "Søndag"], + daysShort: ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør", "Søn"], + daysMin: ["Sø", "Ma", "Ti", "On", "To", "Fr", "Lø", "Sø"], + months: ["Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December"], + monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"] + }; +}(jQuery)); \ No newline at end of file diff --git a/js/locales/bootstrap-datepicker.it.js b/js/locales/bootstrap-datepicker.it.js new file mode 100644 index 0000000..8b9f885 --- /dev/null +++ b/js/locales/bootstrap-datepicker.it.js @@ -0,0 +1,13 @@ +/** + * Italian translation for bootstrap-datepicker + * Enrico Rubboli + */ +;(function($){ + $.fn.datepicker.dates['it'] = { + days: ["Domenica", "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato", "Domenica"], + daysShort: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab", "Dom"], + daysMin: ["Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa", "Do"], + months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"], + monthsShort: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"] + }; +}(jQuery)); diff --git a/js/locales/bootstrap-datepicker.nl.js b/js/locales/bootstrap-datepicker.nl.js new file mode 100644 index 0000000..cf5413b --- /dev/null +++ b/js/locales/bootstrap-datepicker.nl.js @@ -0,0 +1,13 @@ +/** + * Dutch translation for bootstrap-datepicker + * Reinier Goltstein + */ +;(function($){ + $.fn.datepicker.dates['nl'] = { + days: ["Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Zondag"], + daysShort: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"], + daysMin: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"], + months: ["Januari", "Februari", "Maart", "April", "Mei", "Juni", "Juli", "Augustus", "September", "Oktober", "November", "December"], + monthsShort: ["Jan", "Feb", "Mrt", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"] + }; +}(jQuery)); diff --git a/js/locales/bootstrap-datepicker.ru.js b/js/locales/bootstrap-datepicker.ru.js new file mode 100644 index 0000000..1b5565e --- /dev/null +++ b/js/locales/bootstrap-datepicker.ru.js @@ -0,0 +1,13 @@ +/** + * Russian translation for bootstrap-datepicker + * Victor Taranenko + */ +;(function($){ + $.fn.datepicker.dates['ru'] = { + days: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"], + daysShort: ["Вск", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб", "Вск"], + daysMin: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"], + months: ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"], + monthsShort: ["Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек"] + }; +}(jQuery)); \ No newline at end of file