123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589 |
- /*!
- * B-JUI v1.2 (http://b-jui.com)
- * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
- * Copyright 2014 K'naan (xknaan@163.com).
- * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
- */
- /* ========================================================================
- * B-JUI: bjui-datepicker.js v1.2
- * reference: util.date.js
- * @author K'naan (xknaan@163.com)
- * -- Modified from dwz.datepicker.js (author:ZhangHuihua@msn.com)
- * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-datepicker.js
- * ========================================================================
- * Copyright 2014 K'naan.
- * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
- * ======================================================================== */
- +function ($) {
- 'use strict';
- // DATEPICKER GLOBAL ELEMENTS
- // ======================
-
- var $box, $main, $prev, $next, $year, $month, $time, $timeinps, $spinner, $hh, $mm, $ss, $tm, $close, $days, $dayNames, $clearBtn, $okBtn
-
- $(function() {
- var INIT_DATEPICKER = function() {
- var cp = BJUI.regional.datepicker
- var calendar = FRAG.calendarFrag
- .replace('#close#', cp.close)
- .replace('#prev#', cp.prev)
- .replace('#next#', cp.next)
- .replace('#clear#', cp.clear)
- .replace('#ok#', cp.ok)
-
- $box = $(calendar).hide()
- $('body').append('<!-- datepicker -->').append($box)
- $main = $box.find('> .main')
- $prev = $box.find('a.prev')
- $next = $box.find('a.next')
- $year = $box.find('select[name=year]')
- $month = $box.find('select[name=month]')
- $time = $box.find('.time')
- $timeinps = $time.find(':text')
- $spinner = $time.find('ul > li')
- $hh = $time.find('.hh')
- $mm = $time.find('.mm')
- $ss = $time.find('.ss')
- $tm = $main.find('> .tm')
- $close = $box.find('.close')
- $days = $main.find('> .body > .days')
- $dayNames = $main.find('> .body > .dayNames')
- $clearBtn = $box.find('.clearBtn')
- $okBtn = $box.find('.okBtn')
-
- //regional
- var dayNames = '', dr = BJUI.regional.datepicker
-
- $.each(dr.dayNames, function(i, v) {
- dayNames += '<dt>'+ v +'</dt>'
- })
- $dayNames.html(dayNames)
- $.each(dr.monthNames, function(i, v) {
- var m = i + 1
-
- $month.append('<option value="'+ m +'">'+ v +'</option>')
- })
-
- $box.on('selectstart', function() { return false })
- }
-
- INIT_DATEPICKER()
- })
-
- // DATEPICKER CLASS DEFINITION
- // ======================
- var Datepicker = function(element, options) {
- this.$element = $(element)
- this.options = options
- this.tools = this.TOOLS()
- this.$dateBtn = null
-
- //动态minDate、maxDate
- var now = new Date()
-
- this.options.minDate = now.formatDateTm(this.options.minDate)
- this.options.maxDate = now.formatDateTm(this.options.maxDate)
-
- //events
- this.events = {
- focus_time : 'focus.bjui.datepicker.time',
- click_prev : 'click.bjui.datepicker.prev',
- click_next : 'click.bjui.datepicker.next',
- click_ok : 'click.bjui.datepicker.ok',
- click_days : 'click.bjui.datepicker.days',
- click_clear : 'click.bjui.datepicker.clear',
- click_close : 'click.bjui.datepicker.close',
- click_tm : 'click.bjui.datepicker.tm',
- click_spinner : 'click.bjui.datepicker.spinner',
- mousedown_sp : 'mousedown.bjui.datepicker.spinner',
- mouseup_sp : 'mouseup.bjui.datepicker.spinner',
- change_ym : 'change.bjui.datepicker.ym',
- click_time : 'click.bjui.datepicker.time',
- keydown_time : 'keydown.bjui.datepicker.time',
- keyup_time : 'keyup.bjui.datepicker.time'
- }
- }
-
- Datepicker.DEFAULTS = {
- pattern : 'yyyy-MM-dd',
- minDate : '1900-01-01',
- maxDate : '2099-12-31',
- mmStep : 1,
- ssStep : 1
- }
-
- Datepicker.EVENTS = {
- afterChange : 'afterchange.bjui.datepicker'
- }
-
- Datepicker.prototype.TOOLS = function() {
- var that = this
- var tools = {
- changeTmMenu: function(sltClass) {
- $tm.removeClass('hh').removeClass('mm').removeClass('ss')
- if (sltClass) {
- $tm.addClass(sltClass)
- $timeinps.removeClass('slt').filter('.'+ sltClass).addClass('slt')
- }
- },
- clickTmMenu: function($input, type) {
- $tm
- .find('> ul')
- .hide()
- .filter('.'+ type)
- .show()
- .find('> li')
- .off(that.events.click_tm)
- .on(that.events.click_tm, function() {
- var $li = $(this)
- var val = parseInt($li.text()) < 10 ? ('0'+ $li.text()) : $li.text()
-
- $input.val(val)
- })
- },
- keydownInt: function(e) {
- if (!((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode == BJUI.keyCode.DELETE || e.keyCode == BJUI.keyCode.BACKSPACE))) { return false }
- },
- changeTm: function($input, $btn) {
- var ivalue = parseInt($input.val()), istart = parseInt($input.data('start')) || 0, iend = parseInt($input.data('end'))
- var istep = parseInt($input.data('step') || 1)
- var type = $btn ? ($btn.data('add') ? $btn.data('add') : -1) : 0
- var newVal = ivalue
-
- if (type == 1) {
- if (ivalue <= iend - istep)
- newVal = ivalue + istep
- } else if (type == -1) {
- if (ivalue >= (istart + istep))
- newVal = ivalue - istep
- } else if (ivalue > iend) {
- newVal = iend
- } else if (ivalue < istart) {
- newVal = istart
- }
- if (newVal < 10) newVal = '0'+ newVal
- $input.val(newVal)
- },
- closeCalendar: function(flag) {
- tools.changeTmMenu()
- if (flag) {
- $(document).off(that.events.click_close)
- $box.hide()
- }
- },
- get: function(name) {
- return that.options[name]
- },
- getDays: function (y, m) {
- return m == 2 ? (y % 4 || (!(y % 100) && y % 400) ? 28 : 29) : (/4|6|9|11/.test(m) ? 30 : 31)
- },
- minMaxDate: function(sDate) {
- var _count = sDate.split('-').length - 1
- var _format = 'y-M-d'
-
- if (_count == 1) _format = 'y-M'
- else if (_count == 0) _format = 'y'
-
- return sDate.parseDate(_format)
- },
- getMinDate: function() {
- return this.minMaxDate(that.options.minDate)
- },
- getMaxDate: function() {
- var _sDate = that.options.maxDate
- var _count = _sDate.split('-').length - 1
- var _date = this.minMaxDate(_sDate)
-
- if (_count < 2) { //format:y-M、y
- var _day = this.getDays(_date.getFullYear(), _date.getMonth() + 1)
- _date.setDate(_day)
- if (_count == 0)//format:y
- _date.setMonth(11)
- }
-
- return _date
- },
- getDateWrap: function(date) {
- if (!date) date = this.parseDate(that.sDate) || new Date()
-
- var y = date.getFullYear()
- var m = date.getMonth() + 1
- var days = this.getDays(y, m)
-
- return {
- year: y, month: m, day: date.getDate(),
- hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(),
- days: days, date: date
- }
- },
- changeDate: function(y, m, d) {
- var date = new Date(y, m - 1, d || 1)
-
- that.sDate = this.formatDate(date)
- return date
- },
- changeDateTime: function(y, M, d, H, m, s) {
- var date = new Date(y, M - 1, d, H, m, s)
-
- that.sDate = this.formatDate(date)
- return date
- },
- changeDay: function(day, chMonth) {
- if (!chMonth) chMonth = 0
- var dw = this.getDateWrap()
-
- return this.changeDate(dw.year, dw.month + parseInt(chMonth), day)
- },
- changeMonth: function(type) {
- var yearIndex = $year.get(0).selectedIndex
- var maxYear = $year.find('option').length
- var month = ($month.val() * 1) + type
-
- if (month == 0) {
- if (yearIndex == 0) {
- month = 1
- } else {
- month = 12
- yearIndex--
- $year.get(0).selectedIndex = yearIndex
- }
- } else if (month == 13) {
- if (yearIndex == (maxYear - 1)) {
- month = 12
- } else {
- month = 1
- yearIndex++
- $year.get(0).selectedIndex = yearIndex
- }
- }
- $month.val(month).change()
- },
- parseDate: function(sDate) {
- if (!sDate) return null
- return sDate.parseDate(that.options.pattern)
- },
- formatDate: function(date) {
- return date.formatDate(that.options.pattern)
- },
- hasHour: function() {
- return that.options.pattern.indexOf('H') != -1
- },
- hasMinute: function() {
- return that.options.pattern.indexOf('m') != -1
- },
- hasSecond: function() {
- return that.options.pattern.indexOf('s') != -1
- },
- hasTime: function() {
- return this.hasHour() || this.hasMinute() || this.hasSecond()
- },
- hasDate: function() {
- var _dateKeys = ['y','M','d','E']
-
- for (var i = 0; i < _dateKeys.length; i++) {
- if (that.options.pattern.indexOf(_dateKeys[i]) != -1) return true
- }
- return false
- },
- afterChange: function(date) {
- that.$element.trigger(Datepicker.EVENTS.afterChange, {value:date})
- }
- }
- return tools
- }
-
- Datepicker.prototype.addBtn = function() {
- var that = this, $element = that.$element
-
- if (!this.$dateBtn && !this.options.addbtn && !$element.parent().hasClass('wrap_bjui_btn_box')) {
- this.$dateBtn = $(FRAG.dateBtn)
- this.$element.css({'paddingRight':'15px'}).wrap('<span class="wrap_bjui_btn_box"></span>')
-
- var $box = this.$element.parent()
- var height = this.$element.addClass('form-control').innerHeight()
-
- $box.css({'position':'relative', 'display':'inline-block'})
-
- this.$dateBtn.css({'height':height, 'lineHeight':height +'px'}).appendTo($box)
- this.$dateBtn.on('selectstart', function() { return false })
- }
- }
-
- Datepicker.prototype.init = function() {
- if (this.$element.val()) this.sDate = this.$element.val().trim()
-
- var that = this
- var options = this.options
- var tools = this.tools
- var dw = tools.getDateWrap()
- var minDate = tools.getMinDate(), maxDate = tools.getMaxDate()
- var yearstart = minDate.getFullYear(), yearend = maxDate.getFullYear()
-
- $year.empty()
- for (var y = yearstart; y <= yearend; y++) {
- $year.append('<option value="'+ y +'"'+ (dw.year == y ? ' selected' : '') +'>'+ y +'</option>')
- }
-
- $month.val(dw.month)
- $year.add($month).off(this.events.change_ym).on(this.events.change_ym, function() {
- if (tools.hasTime()) {
- var $day = $days.find('.slt')
- var date = tools.changeDateTime($year.val(), $month.val(), $day.data('day'), dw.hour, dw.minute, dw.second)
-
- that.create(tools.getDateWrap(date), minDate, maxDate)
- } else {
- var $day = $days.find('.slt')
- var date = tools.changeDate($year.val(), $month.val(), $day.data('day'))
-
- that.create(tools.getDateWrap(date), minDate, maxDate)
- }
- })
- $prev.off(this.events.click_prev).on(this.events.click_prev, function() {
- that.tools.changeMonth(-1)
- })
- $next.off(this.events.click_prev).on(this.events.click_prev, function() {
- that.tools.changeMonth(1)
- })
- $clearBtn.off(this.events.click_clear).on(this.events.click_clear, function() {
- that.$element.val('')
- tools.closeCalendar(true)
- })
- $okBtn.off(this.events.click_ok).on(this.events.click_ok, function() {
- var $dd = $days.find('dd.slt')
-
- if ($dd.hasClass('disabled')) return false
-
- var date = tools.changeDay($dd.data('day'), $dd.data('month'))
-
- if (tools.hasTime()) {
- date.setHours(parseInt($hh.val()))
- date.setMinutes(parseInt($mm.val()))
- date.setSeconds(parseInt($ss.val()))
- }
- tools.closeCalendar(true)
- that.$element.val(tools.formatDate(date)).focus()
-
- //changedEvent
- tools.afterChange(date)
- })
- $close.off(this.events.click_close).on(this.events.click_close, function() {
- tools.closeCalendar(true)
- })
- $(document).on(this.events.click_close, function(e) {
- var $target = $(e.target)
-
- if (e.target == that.$element.get(0)) return
- if ($target.closest('#calendar').length) return
- if ($target.data('toggle') == 'datepicker' || $target.parent().data('toggle') == 'datepickerbtn' || $target.data('toggle') == 'datepickerbtn')
- tools.closeCalendar(false)
- else
- tools.closeCalendar(true)
- })
- this.create(dw, minDate, maxDate)
- }
-
- Datepicker.prototype.create = function(dw, minDate, maxDate) {
- var that = this
- var options = this.options
- var tools = this.tools
- var monthStart = new Date(dw.year, dw.month - 1, 1)
- var startDay = monthStart.getDay()
- var dayStr = ''
-
- if (startDay > 0) {
- monthStart.setMonth(monthStart.getMonth() - 1)
- var prevDateWrap = tools.getDateWrap(monthStart)
-
- for (var t = prevDateWrap.days - startDay + 1; t <= prevDateWrap.days; t++) {
- var _date = new Date(dw.year, dw.month - 2, t)
- var _ctrClass = (_date >= minDate && _date <= maxDate) ? '' : ' disabled'
-
- dayStr += '<dd class="other'+ _ctrClass +'" data-month="-1" data-day="'+ t +'">'+ t +'</dd>'
- }
- }
- for (var t = 1; t <= dw.days; t++) {
- var _date = new Date(dw.year, dw.month - 1, t)
- var _ctrClass = (_date >= minDate && _date <= maxDate) ? '' : 'disabled'
-
- if (t == dw.day)
- _ctrClass += ' slt'
- dayStr += '<dd class="'+ _ctrClass +'" data-day="'+ t +'">'+ t +'</dd>'
- }
- for (var t = 1; t <= 42 - startDay - dw.days; t++) {
- var _date = new Date(dw.year, dw.month, t)
- var _ctrClass = (_date >= minDate && _date <= maxDate) ? '' : ' disabled'
-
- dayStr += '<dd class="other'+ _ctrClass +'" data-month="1" data-day="'+ t +'">'+ t +'</dd>'
- }
-
- var $alldays = $days.html(dayStr).find('dd')
-
- $alldays.not('.disabled').off(this.events.click_days).on(this.events.click_days, function() {
- var $day = $(this)
-
- if (!tools.hasTime()) {
- var date = tools.changeDay($day.data('day'), $day.data('month'))
-
- tools.closeCalendar(true)
- that.$element.val(tools.formatDate(date)).focus()
-
- //changedEvent
- tools.afterChange(date)
- } else {
- $alldays.removeClass('slt')
- $day.addClass('slt')
- }
- })
-
- if (!tools.hasDate()) {
- $main.addClass('nodate') // only time
- } else {
- $main.removeClass('nodate')
- }
- if (tools.hasTime()) {
- $time.show()
- $hh.val(dw.hour < 10 ? ('0'+ dw.hour) : dw.hour).off(this.events.focus_time).on(this.events.focus_time, function() {
- tools.changeTmMenu('hh')
- })
-
- var iMinute = parseInt(dw.minute / options.mmStep) * options.mmStep
-
- $mm.val(iMinute < 10 ? ('0'+ iMinute) : iMinute).data('step', options.mmStep).off(this.events.focus_time).on(this.events.focus_time, function() {
- tools.changeTmMenu('mm')
- })
- $ss.val(tools.hasSecond() ? (dw.second < 10 ? ('0'+ dw.second) : dw.second) : '00').data('step', options.ssStep).off(this.events.focus_time).on(this.events.focus_time, function() {
- tools.changeTmMenu('ss')
- })
- $box.off('click').on('click', function(e) {
- if ($(e.target).closest('.time').length) return
- $tm.find('> ul').hide()
- tools.changeTmMenu()
- })
- $timeinps.off(this.events.keydown_time).on(this.events.keydown_time, tools.keydownInt).each(function() {
- var $input = $(this)
-
- $input.off(that.events.keyup_time).on(that.events.keyup_time, function() {
- tools.changeTm($input)
- })
- }).off(this.events.click_time).on(this.events.click_time, function() {
- tools.clickTmMenu($(this), $(this).data('type'))
- })
-
- var timer = null
-
- $spinner.off(this.events.click_spinner).on(this.events.click_spinner, function(e) {
- var $btn = $(this)
-
- $timeinps.filter('.slt').each(function() {
- tools.changeTm($(this), $btn)
- })
-
- e.preventDefault()
- }).off(this.events.mousedown_sp).on(this.events.mousedown_sp, function(e) {
- var $btn = $(this)
-
- timer = setInterval(function() {
- $timeinps.filter('.slt').each(function() {
- tools.changeTm($(this), $btn)
- })
- }, 150)
- }).off(this.events.mouseup_sp).on(this.events.mouseup_sp, function(e) {
- clearTimeout(timer)
- })
-
- if (!tools.hasHour()) $hh.attr('disabled', true)
- if (!tools.hasMinute()) $mm.attr('disabled', true)
- if (!tools.hasSecond()) $ss.attr('disabled', true)
- } else {
- $time.hide()
- }
- this.show()
- }
-
- Datepicker.prototype.show = function() {
- var offset = this.$element.offset()
- var iTop = offset.top + this.$element.get(0).offsetHeight
- // fix top
- var iBoxH = $box.outerHeight(true)
-
- if (iTop > iBoxH && iTop > $(window).height() - iBoxH)
- iTop = offset.top - iBoxH
- $box.css({
- left: offset.left,
- top: iTop
- }).show().click(function(e) {
- e.stopPropagation()
- })
- }
-
- // DATEPICKER PLUGIN DEFINITION
- // =======================
-
- function Plugin(option) {
- var args = arguments
- var property = option
-
- return this.each(function () {
- var $this = $(this)
- var options = $.extend({}, Datepicker.DEFAULTS, $this.data(), typeof option == 'object' && option)
- var data = $this.data('bjui.datepicker')
-
- if (!data) $this.data('bjui.datepicker', (data = new Datepicker(this, options)))
- if (typeof property == 'string' && $.isFunction(data[property])) {
- [].shift.apply(args)
- if (!args) data[property]()
- else data[property].apply(data, args)
- } else {
- data.init()
- }
- })
- }
- var old = $.fn.datepicker
-
- $.fn.datepicker = Plugin
- $.fn.datepicker.Constructor = Datepicker
-
- // DATEPICKER NO CONFLICT
- // =================
-
- $.fn.datepicker.noConflict = function () {
- $.fn.datepicker = old
- return this
- }
-
- // DATEPICKER DATA-API
- // ==============
-
- $(document).on(BJUI.eventType.initUI, function(e) {
- var $this = $(e.target).find('[data-toggle="datepicker"]')
-
- if (!$this.length) return
- if ($this.data('nobtn')) return
-
- Plugin.call($this, 'addBtn')
- })
-
- $(document).on('click.bjui.datepicker.data-api', '[data-toggle="datepickerbtn"]', function(e) {
- var $date = $(this).prevAll('[data-toggle="datepicker"]')
-
- if (!$date || !$date.is(':text')) return
- Plugin.call($date, $date.data())
-
- e.preventDefault()
- })
-
- $(document).on('click.bjui.datepicker.data-api', '[data-toggle="datepicker"]', function(e) {
- var $this = $(this)
-
- if ($this.data('onlybtn')) return
- if (!$this.is(':text')) return
- Plugin.call($this, $this.data())
-
- e.preventDefault()
- })
- }(jQuery);
|