diff --git a/DatePicker.php b/DatePicker.php new file mode 100644 index 0000000..11790bd --- /dev/null +++ b/DatePicker.php @@ -0,0 +1,99 @@ + "YYYY/0M/0D"]; + + public function init() + { + parent::init(); + if (!isset($this->options['id'])) { + $this->options['id'] = $this->getId(); + } + if (!$this->hasModel() && $this->name === null) { + throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified."); + } + if ($this->hasModel() && !isset($this->options['id'])) { + $this->options['id'] = Html::getInputId($this->model, $this->attribute); + } + } + + function run() + { + $this->registerAsset(); + + echo $this->renderInput(); + + $this->renderJsCode(); + } + /** + * Register datepicker asset into view. + */ + function registerAsset() + { + DatePickerAsset::register($this->getView()); + } + /** + * Render input. + */ + function renderInput() + { + if ($this->hasModel()) { + return Html::activeTextInput($this->model, $this->attribute, $this->options); + } else { + return Html::textInput($this->name, $this->value, $this->options); + } + } + /** + * Render Js code. + */ + function renderJsCode() + { + $name = 'persianDatepicker'; + $id = $this->options['id']; + $options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions); + $js = "jQuery('#$id').$name($options);"; + $this->getView()->registerJs($js); + } + /** + * @return boolean whether this widget is associated with a data model. + */ + protected function hasModel() + { + return $this->model instanceof Model && $this->attribute !== null; + } +} \ No newline at end of file diff --git a/DatePickerAsset.php b/DatePickerAsset.php new file mode 100644 index 0000000..c07c718 --- /dev/null +++ b/DatePickerAsset.php @@ -0,0 +1,23 @@ +IE8, Chrome, Firefox, safari, opera +- **Light weight:** ~14k minified +- **Beautiful themes:** default, dark +- **Size and font:** set the size (width & height) and fontsize for datepicker cells +- **Show persian numbers:** (۰ - ۹) +- **Select gregorian date:** (good way to convert jalali date to gregorian date) +- **Multi formatting date:** like ("YYYY/0M/DD hh:ss") becomes like **1392/07/22 16:45** +- **Selectable months and years:** [1, 3, 4, 12] + + +##Usage +1- include jQuery & persianDatepicker.js & persianDatepicker.css +```html + + + +``` +2- add your html element (input or span or etc) +```html + + +``` +3- call the persianDatepicker plugin +```html + +``` + + +##Options +To customize persian datepicker, simply pass in an options object: (defaults shown) +```javascript +$("#input1")persianDatePicker({ + months: ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند"], + dowTitle: ["شنبه", "یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنج شنبه", "جمعه"], + shortDowTitle: ["ش", "ی", "د", "س", "چ", "پ", "ج"], + showGregorianDate: false, + persianNumbers: true, + formatDate: "YYYY/MM/DD", + prevArrow: '\u25c4', + nextArrow: '\u25ba', + theme: 'default', + alwaysShow: false, + selectableYears: null, + selectableMonths: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], + cellWidth: 25, + cellHeight: 20, + fontSize: 13, + isRTL: false, + calendarPosition: { + x: 0, + y: 0, + }, + onShow: function(calendar) { + calendar.show(); + }, + onHide: function(calendar) { + calendar.hide(); + }, +}); +``` + +##Credit +Created by [@kharabati](http://twitter.com/kharabati "@kharabati"), [blog](http://mbehzadi.com/ "mbehzadi.com") + +use, share , fork , enjoy! , ... diff --git a/assets/css/persianDatepicker-dark.css b/assets/css/persianDatepicker-dark.css new file mode 100644 index 0000000..3fcdbaa --- /dev/null +++ b/assets/css/persianDatepicker-dark.css @@ -0,0 +1,190 @@ + +@keyframes start { + from { + transform: scale(.5); + } + to { + transform: scale(1); + } +} + +@-webkit-keyframes start { + from { + -webkit-transform: scale(.5); + } + to { + -webkit-transform: scale(1); + } +} +.rtl{direction:rtl} +.pdp-dark { + position: absolute; + direction: rtl; + color: #f2f2f2; + box-shadow: 1px 1px 8px 1px rgba(0, 0, 0, 0.49); +} + +.pdp-dark ::-webkit-scrollbar-track +{ + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); + background-color: #F5F5F5; +} + +.pdp-dark ::-webkit-scrollbar +{ + width: 15px; + background-color: #F5F5F5; +} + +.pdp-dark ::-webkit-scrollbar-thumb +{ + background-color: #444444; +} +.pdp-dark ::selection{ + color: #67cdcc; +} + +.pdp-dark .header{ + background-color: #333; + border-top: 2px solid #999; + border-left: 1px solid #999; + border-right: 1px solid #999; + border-bottom: none; + padding: 2px; + font-weight: bold; +} + +.pdp-dark .yearSelect{ + overflow-y: auto; + direction: ltr; +} + +.pdp-dark .monthSelect li.desableMonth, .pdp-dark .monthSelect li.desableMonth:hover{ + color: #bbb; + background: #eee; +} + +.pdp-dark .yearSelect, .pdp-dark .monthSelect{ + font:normal 12px Tahoma; + background: #555; + border: 1px solid #999; + list-style: none; + position: absolute; + padding: 0; + width: 99.6%; + text-align: right; + z-index: 9999; + animation: start 0.2s; + -webkit-animation: start 0.2s; +} +.pdp-dark .selected{ + background: #15a6eb; + color: #ffffff; +} + +.pdp-dark .yearSelect li, .pdp-dark .monthSelect li { + padding: 1px; + cursor: default; + display: inline-table; + text-align: center; + border: 1px dotted #888; +} +.pdp-dark .yearSelect li:hover, .pdp-dark .monthSelect li:hover { + background: #FF9933; + color: #ffffff; + border-color: #FF7700; +} + +.pdp-dark .nextArrow{ + right:0; +} +.pdp-dark .prevArrow{ + left:0; +} +.pdp-dark .monthYear{ + width: 80%; + margin: 0 auto; + text-align: center; + cursor: pointer; +} + +.pdp-dark .nextArrow, .pdp-dark .prevArrow{ + cursor: pointer; + position: absolute; + top:1px; + padding: 2px; +} + +.pdp-dark .nextArrow:hover, .pdp-dark .prevArrow:hover{ + color: #0073ea; +} + +.pdp-dark .cell { + display: inline-block; + cursor: default; + text-align: center; +} + +/* Days of the week */ +.pdp-dark .dows { + background: #35516F; + color: #fff; +} +.pdp-dark .dow { + font: bold 14px 'helvetica'; + border: 1px solid #35516F; +} + +.pdp-dark .days{ + background-color: #444; + border: 1px solid #777; + border-top: none; + font: normal 12px Tahoma; +} + +.pdp-dark .day{ + border: 1px solid #777; +} + +.pdp-dark .day:hover{ + background: #aaa; + border: 1px solid #f0f0f0; +} +.pdp-dark .selday, .pdp-dark .selday:hover{ + background: #eadaa6; + border-color: #eb5b04; + color: #222; +} + +.pdp-dark .friday{ + color: #D55372; +} + +.pdp-dark .today{ + color: #fff; + background: #0073ea; +} +.pdp-dark .today:hover{ + color: #fff; + background: #0073ea; +} + +.pdp-dark .nul{ + border: 1px solid #777; + background: #777; +} + +.pdp-dark .footer{ + background: #888; + font: normal 12px Tahoma; + text-align: center; + height: 17px; +} +.pdp-dark .footer .goToday{ + color: #f0f0f0; + text-decoration: none; +} +.pdp-dark .footer .goToday:hover{ + color: #ffffff; + text-decoration: overline; +} diff --git a/assets/css/persianDatepicker-default.css b/assets/css/persianDatepicker-default.css new file mode 100644 index 0000000..96085ec --- /dev/null +++ b/assets/css/persianDatepicker-default.css @@ -0,0 +1,190 @@ + +@keyframes start { + from { + transform: scale(.5); + } + to { + transform: scale(1); + } +} + +@-webkit-keyframes start { + from { + -webkit-transform: scale(.5); + } + to { + -webkit-transform: scale(1); + } +} +.rtl{direction:rtl} +.pdp-default { + position: absolute; + direction: rtl; + color: #555; + box-shadow: 1px 1px 8px 1px rgba(0, 0, 0, 0.19); +} + +.pdp-default ::-webkit-scrollbar-track +{ + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); + background-color: #F5F5F5; +} + +.pdp-default ::-webkit-scrollbar +{ + width: 15px; + background-color: #F5F5F5; +} + +.pdp-default ::-webkit-scrollbar-thumb +{ + background-color: #444444; +} +.pdp-default ::selection{ + color: #67cdcc; +} + +.pdp-default .header{ + background-color: #ffffff; + border-top: 2px solid #999; + border-left: 1px solid #999; + border-right: 1px solid #999; + border-bottom: none; + padding: 2px; + font-weight: bold; +} + +.pdp-default .yearSelect{ + overflow-y: auto; + direction: ltr; +} + +.pdp-default .monthSelect li.desableMonth, .pdp-default .monthSelect li.desableMonth:hover{ + color: #bbb; + background: #eee; +} + +.pdp-default .yearSelect, .pdp-default .monthSelect{ + font:normal 12px Tahoma; + background: #f9f9f9; + border: 1px solid #ccc; + list-style: none; + position: absolute; + padding: 0; + width: 99.6%; + text-align: right; + z-index: 9999; + animation: start 0.2s; + -webkit-animation: start 0.2s; +} +.pdp-default .selected{ + background: #15a6eb; + color: #ffffff; +} + +.pdp-default .yearSelect li, .pdp-default .monthSelect li { + padding: 1px; + cursor: default; + display: inline-table; + text-align: center; + border: 1px dotted #ddd; +} +.pdp-default .yearSelect li:hover, .pdp-default .monthSelect li:hover { + background: #FF9933; + color: #ffffff; + border-color: #FF7700; +} + +.pdp-default .nextArrow{ + right:0; +} +.pdp-default .prevArrow{ + left:0; +} +.pdp-default .monthYear{ + width: 80%; + margin: 0 auto; + text-align: center; + cursor: pointer; +} + +.pdp-default .nextArrow, .pdp-default .prevArrow{ + cursor: pointer; + position: absolute; + top:1px; + padding: 2px; +} + +.pdp-default .nextArrow:hover, .pdp-default .prevArrow:hover{ + color: #0073ea; +} + +.pdp-default .cell { + display: inline-block; + cursor: default; + text-align: center; +} + +/* Days of the week */ +.pdp-default .dows { + background: #5F5D5D;/*#006fe0;*/ + color: #fff; +} +.pdp-default .dow { + font: bold 14px 'helvetica'; + border: 1px solid #5F5D5D; +} + +.pdp-default .days{ + background-color: #ffffff; + border: 1px solid #999; + border-top: none; + font: normal 12px Tahoma; +} + +.pdp-default .day{ + border: 1px solid #f1f1f1; +} + +.pdp-default .day:hover{ + background: #f3f3f3; + border: 1px solid #bbb; + border-radius: 2px; +} +.pdp-default .selday, .pdp-default .selday:hover{ + background: #eadaa6; + border-color: #eb5b04; +} + +.pdp-default .friday{ + color: #f38; +} + +.pdp-default .today{ + color: #fff; + background: #0073ea; +} +.pdp-default .today:hover{ + color: #fff; + background: #0073ea; +} + +.pdp-default .nul{ + border: 1px solid #f1f1f1; + background: #f1f1f1; +} + +.pdp-default .footer{ + background: #999; + font: normal 12px Tahoma; + text-align: center; + height: 17px; +} +.pdp-default .footer .goToday{ + color: #f0f0f0; + text-decoration: none; +} +.pdp-default .footer .goToday:hover{ + color: #ffffff; + text-decoration: overline; +} diff --git a/assets/js/persianDatepicker.js b/assets/js/persianDatepicker.js new file mode 100644 index 0000000..dc6f333 --- /dev/null +++ b/assets/js/persianDatepicker.js @@ -0,0 +1,726 @@ +/*! + * persianDatepicker v0.1.0 + * http://github.com/behzadi/persianDatepicker/ + * http://mbehzadi.com/persianDatepicker/ + * + * Copyright (c) 2013 Mohammad hasan Behzadi All rights reserved. + * + * Released under the MIT license. + * + * jalali Date Functions from NASA.gov + * + * Date: Tue Jan 1 2013 + */ +; +(function () { + $.fn.persianDatepicker = function (options) { + var pluginName = 'persianDatepicker'; + var instance = this.data(pluginName); + if (!instance) { + return this.each(function () { + return $(this).data(pluginName, new persianDatepicker(this, options)); + }); + } + return (options === true) ? instance : this; + }; + // persianDatepicker object + var persianDatepicker = (function () { + function persianDatepicker(element, userOptions) { + var defaults = { + months: ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند"], + dowTitle: ["شنبه", "یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنج شنبه", "جمعه"], + shortDowTitle: ["ش", "ی", "د", "س", "چ", "پ", "ج"], + showGregorianDate: !1, + persianNumbers: !0, + formatDate: "YYYY/MM/DD", + selectedBefore: !1, + selectedDate: null, + prevArrow: '\u25c4', + nextArrow: '\u25ba', + theme: 'default', + alwaysShow: !1, + selectableYears: null, + selectableMonths: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], + cellWidth: 25, // by px + cellHeight: 20, // by px + fontSize: 13, // by px + isRTL: !1, + calendarPosition: { + x: 0, + y: 0, + }, + onShow: function () { }, + onHide: function () { }, + onSelect: function () { } + }; + var self = this; + self.el = $(element); + var el = self.el; + self.options = $.extend(false, {}, defaults, userOptions); + var options = self.options; + + _fontSize = options.fontSize; + _cw = parseInt(options.cellWidth); + _ch = parseInt(options.cellHeight); + self.cellStyle = "style='width:" + _cw + "px;height:" + _ch + "px;line-height:" + _ch + "px; font-size:" + (_fontSize) + "px; ' "; + self.headerStyle = "style='height:" + _ch + "px;line-height:" + _ch + "px; font-size:" + (_fontSize + 4) + "px;' "; + self.selectUlStyle = "style='margin-top:" + _ch + "px;height:" + (_ch * 7 + 20) + "px; font-size:" + (_fontSize - 2) + "px;' "; + self.selectMonthLiStyle = "style='height:" + (_ch * 7 + 7) / (4) + "px;line-height:" + (_ch * 7 + 7) / (4) + "px; width:" + (7 * _cw + 1) / (3) + "px;width:" + (7 * _cw) / (3) + "px\\9;' "; + self.selectYearLiStyle = "style='height:" + (_ch * 7 + 10) / (6) + "px;line-height:" + (_ch * 7 + 10) / (6) + "px; width:" + (7 * _cw - 14) / (3) + "px;width:" + (7 * _cw - 15) / (3) + "px\\9;' "; + self.footerStyle = "style='height:" + _ch + "px;line-height:" + _ch + "px; font-size:" + _fontSize + "px;' "; + + self.jDateFunctions = new jDateFunctions(); + + if (self.options.selectedDate == undefined) { + var patt1 = new RegExp('^([1-9][0-9][0-9][0-9])/([0]?[1-9]|[1][0-2])/([0]?[1-9]|[1-2][0-9]|[3][0-1])$'); + if (el.is('input')) { + if (patt1.test(el.val())) + self.options.selectedDate = el.val(); + } else { + if (patt1.test(el.html())) + self.options.selectedDate = el.html(); + } + } + self._persianDate = (self.options.selectedDate != undefined) ? new persianDate().parse(self.options.selectedDate) : self.now(); + if (options.selectableYears != undefined && options.selectableYears._indexOf(self._persianDate.year) == -1) + self._persianDate.year = options.selectableYears[0]; + if (self.options.selectableMonths._indexOf(self._persianDate.month) == -1) + self._persianDate.month = options.selectableMonths[0]; + + self.persianDate = self._persianDate; + self._id = 'pdp-' + Math.round(Math.random() * 1e7); + self.persianDate.formatDate = options.formatDate; + self.calendar = $('
') + + if (!(el.attr('pdp-id') || '').length) { + el.attr('pdp-id', self._id); + } + + el + .addClass('pdp-el') + .bind('click', function (e) { + self.show(e); + }) + .bind('focus', function (e) { + self.show(e); + }); + + if (options.selectedBefore && !options.showGregorianDate) { + if (self.options.selectedDate != undefined) + self.showDate(el, self.persianDate.parse(self.options.selectedDate).toString(options.formatDate)); + else + self.showDate(el, self.now().toString(options.formatDate)); + } + + if (options.selectedBefore && options.showGregorianDate) { + if (self.options.selectedDate != undefined) + self.showDate(el, self.persianDate.parse(self.options.selectedDate).gDate._toString(self.options.formatDate)); + else + self.showDate(el, self.now().gDate._toString(self.options.formatDate)); + } + + if (options.isRTL) + el.addClass('rtl'); + if (self.calendar.length && !options.alwaysShow) { + self.calendar.hide(); + } + $(document).bind('mouseup', function (e) { + var target = e.target; + var calendar = self.calendar; + if (!el.is(target) && !calendar.is(target) && calendar.has(target).length === 0 && calendar.is(':visible')) { + self.hide(); + } + var container = $(".pdp-" + options.theme + " .yearSelect"); + if (!container.is(e.target) && container.has(e.target).length === 0) { + container.hide(); + } + container = $(".pdp-" + options.theme + " .monthSelect"); + if (!container.is(e.target) && container.has(e.target).length === 0) { + container.hide(); + } + }); + var onResize = function () { + var elPos = el.offset(); + self.calendar.css( + { + top: (elPos.top + el.outerHeight() + options.calendarPosition.y) + 'px', + left: (elPos.left + options.calendarPosition.x) + 'px' + }); + }; + self.onresize = onResize; + $(window).resize(onResize); + $('body').append(self.calendar); + self.render(); + onResize(); + } + ; + // persianDatepicker methods + persianDatepicker.prototype = { + show: function () { + this.calendar.show(); + //$.each($('.pdp-el').not(this.el), function(i, o) { + // if (o.length) { + // o.options.onHide(o.calendar); + // } + //}); + this.options.onShow(this.calendar); + this.onresize(); + }, + hide: function () { + this.calendar.hide(); + //if (this.options && !this.options.alwaysShow) { + // this.options.onHide(this.calendar); + //} + this.options.onHide(this.calendar); + }, + render: function () { + this.calendar.children().remove(); + this.header(); + this.dows(); + this.content(); + this.footer(); + }, + header: function () { + var self = this; + _monthYear = $('
'); + _monthYear.appendTo(this.calendar); + _head = $('
'); + _head.appendTo(this.calendar); + _next = $('
') + .html(this.options.nextArrow) + .attr('title', 'ماه بعد') + .bind("click", function () { + nextMonth = self.persianDate.month + 1; + for (; self.options.selectableMonths._indexOf(nextMonth) == -1 && nextMonth < 13; nextMonth++); + self.persianDate.addMonth(nextMonth - self.persianDate.month); + self.render(); + }); + _next.appendTo(_head); + var _monthSelect = $('