diff --git a/datetimepicker.jquery.json b/datetimepicker.jquery.json index 88f30de..2b1508b 100644 --- a/datetimepicker.jquery.json +++ b/datetimepicker.jquery.json @@ -16,9 +16,10 @@ "scroller", "picker", "i18n", - "input" + "input", + "touch" ], - "version": "1.1.1", + "version": "2.0.0", "author": { "name": "Chupurnov Valeriy", "url": "http://xdsoft.net/contacts.html" diff --git a/index.html b/index.html index f3930eb..2a33f42 100644 --- a/index.html +++ b/index.html @@ -1,6 +1,7 @@ + diff --git a/jquery.datetimepicker.css b/jquery.datetimepicker.css index 7d3ae3a..8454d24 100644 --- a/jquery.datetimepicker.css +++ b/jquery.datetimepicker.css @@ -12,7 +12,7 @@ padding-left: 0px; padding-top: 2px; position: absolute; - z-index: 9999; + z-index: 99; box-sizing: border-box; display:none; -webkit-touch-callout: none; @@ -22,6 +22,7 @@ -ms-user-select: none; user-select: none; } + .xdsoft_noselect{ -webkit-touch-callout: none; -webkit-user-select: none; @@ -143,8 +144,7 @@ .xdsoft_datetimepicker .xdsoft_label{ display: inline; position: relative; - z-index: 9999; - overflow: hidden; + z-index: 99; margin: 0; padding: 5px 3px; font-size: 14px; @@ -154,6 +154,37 @@ float:left; width:182px; text-align:center; + cursor:pointer; +} +.xdsoft_datetimepicker .xdsoft_label:hover{ + text-decoration:underline; +} +.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select{ + border:1px solid #ccc; + position:absolute; + display:block; + right:0px; + top:30px; + z-index:101; + display:none; + background:#fff; + max-height:160px; + overflow-y:hidden; +} +.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select.xdsoft_monthselect{right:-7px;} +.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select.xdsoft_yearselect{right:2px;} +.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option:hover{ + color: #fff; + background: #ff8000; +} +.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option{ + padding:2px 10px 2px 5px; +} +.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option.xdsoft_current{ + background: #33AAFF; + box-shadow: #178FE5 0px 1px 3px 0px inset; + color:#fff; + font-weight: 700; } .xdsoft_datetimepicker .xdsoft_month{ width:114px; @@ -219,7 +250,7 @@ .xdsoft_datetimepicker .xdsoft_calendar th{ font-weight: 700; text-align: center; - color: #999999; + color: #9999; cursor:default; } .xdsoft_datetimepicker .xdsoft_copyright{ color:#ccc !important; font-size:10px;clear:both;float:none;margin-left:8px;} @@ -231,12 +262,12 @@ position:relative; border:1px solid #ccc; } -.xdsoft_time_box > .xdsoft_scrollbar >.xdsoft_scroller{ +.xdsoft_scrollbar >.xdsoft_scroller{ background:#ccc !important; height:20px; border-radius:3px; } -.xdsoft_time_box > .xdsoft_scrollbar{ +.xdsoft_scrollbar{ position:absolute; width:7px; width:7px; @@ -244,4 +275,7 @@ top:0px; bottom:0px; cursor:pointer; +} +.xdsoft_scroller_box{ +position:relative; } \ No newline at end of file diff --git a/jquery.datetimepicker.js b/jquery.datetimepicker.js index 84adb3a..98cc7ae 100644 --- a/jquery.datetimepicker.js +++ b/jquery.datetimepicker.js @@ -1,9 +1,98 @@ /** - * @preserve jQuery DateTimePicker plugin v1.1.1 + * @preserve jQuery DateTimePicker plugin v2.0.0 * @homepage http://xdsoft.net/jqplugins/datetimepicker/ * (c) 2013, Chupurnov Valeriy. */ (function( $ ){ + $.fn.xdsoftScroller = function( _percent ){ + return this.each(function(){ + var timeboxparent = $(this); + if( !$(this).hasClass('xdsoft_scroller_box') ){ + var pointerEventToXY = function( e ){ + var out = {x:0, y:0}; + if(e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel'){ + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + out.x = touch.pageX; + out.y = touch.pageY; + }else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover'|| e.type=='mouseout' || e.type=='mouseenter' || e.type=='mouseleave') { + out.x = e.pageX; + out.y = e.pageY; + } + return out; + }; + var move = 0, + timebox = timeboxparent.children().eq(0), + parentHeight = timeboxparent[0].offsetHeight-2, + height = timebox[0].offsetHeight, + scrollbar = $('
'), + scroller = $('
'), + maximumOffset = 100, + start = false; + scrollbar.append(scroller); + timeboxparent.addClass('xdsoft_scroller_box').append(scrollbar); + scroller.on('mousedown.xdsoft_scroller',function( event ){ + var pageY = event.pageY, + top = parseInt(scroller.css('margin-top')), + h1 = scrollbar[0].offsetHeight; + $(document.body).addClass('xdsoft_noselect'); + $([document.body,window]).on('mouseup.xdsoft_scroller',function(){ + $([document.body,window]).off('mouseup.xdsoft_scroller',arguments.callee) + .off('mousemove.xdsoft_scroller',move) + .removeClass('xdsoft_noselect'); + }); + $(document.body).on('mousemove.xdsoft_scroller',move = function(event){ + var offset = event.pageY-pageY+top; + if( offset<0 ) + offset = 0; + if( offset+scroller[0].offsetHeight>h1 ) + offset = h1-scroller[0].offsetHeight; + timeboxparent.trigger('scroll_element.xdsoft_scroller',[maximumOffset?offset/maximumOffset:0]); + }); + }); + timeboxparent + .on('scroll_element.xdsoft_scroller',function( event,percent ){ + percent = percent>1?1:(percent<0||isNaN(percent))?0:percent; + scroller.css('margin-top',maximumOffset*percent); + timebox.css('marginTop',-parseInt((height-parentHeight)*percent)) + }) + .on('resize_scroll.xdsoft_scroller',function( event,_percent ){ + parentHeight = timeboxparent[0].offsetHeight-2; + height = timebox[0].offsetHeight; + var percent = parentHeight/height, + sh = percent*scrollbar[0].offsetHeight; + if( percent>1 ) + scroller.hide(); + else{ + scroller.show(); + scroller.css('height',parseInt(sh>10?sh:10)); + maximumOffset = scrollbar[0].offsetHeight-scroller[0].offsetHeight; + timeboxparent.trigger('scroll_element.xdsoft_scroller',[_percent?_percent:Math.abs(parseInt(timebox.css('marginTop')))/(height-parentHeight)]); + } + }) + timeboxparent.mousewheel&&timeboxparent.mousewheel(function(event, delta, deltaX, deltaY) { + var top = Math.abs(parseInt(timebox.css('marginTop'))); + timeboxparent.trigger('scroll_element.xdsoft_scroller',[(top-delta*20)/(height-parentHeight)]); + event.stopPropagation(); + return false; + }); + timeboxparent.on('touchstart',function( event ){ + start = pointerEventToXY(event); + }); + timeboxparent.on('touchmove',function( event ){ + if( start ){ + var coord = pointerEventToXY(event), top = Math.abs(parseInt(timebox.css('marginTop'))); + timeboxparent.trigger('scroll_element.xdsoft_scroller',[(top+(coord.y-start.y)/10)/(height-parentHeight)]); + event.stopPropagation(); + event.preventDefault(); + }; + }); + timeboxparent.on('touchend touchcancel',function( event ){ + start = false; + }); + } + timeboxparent.trigger('resize_scroll.xdsoft_scroller',[_percent]); + }); + }; $.fn.datetimepicker = function( opt ){ var CTRLKEY = 17, @@ -92,29 +181,73 @@ scrollTime:true, scrollInput:true, mask:false, - validateOnBlur:true + validateOnBlur:true, + yearStart:1950, + yearEnd:2050 }; var options = ($.isPlainObject(opt)||!opt)?$.extend({},default_options,opt):$.extend({},default_options); var createDateTimePicker = function( input ){ var datetimepicker = $('
'), xdsoft_copyright = $(''), datepicker = $('
'), - mounth_picker = $('
'), + mounth_picker = $('
'), calendar = $('
'), timepicker = $('
'), timeboxparent = timepicker.find('.xdsoft_time_box').eq(0), timebox = $('
'), scrollbar = $('
'), - scroller = $('
'); + scroller = $('
'), + monthselect =$('
'), + yearselect =$('
'); + + mounth_picker.find('.xdsoft_month span').after(monthselect); + mounth_picker.find('.xdsoft_year span').after(yearselect); + + mounth_picker.find('.xdsoft_month,.xdsoft_year').on('mousedown.xdsoft',function(){ + mounth_picker.find('.xdsoft_select').hide(); + var select = $(this).find('.xdsoft_select').eq(0),xd = datetimepicker.data('xdsoft_datetime'),val = 0,top = 0; + + if( xd&&xd.currentTime ) + val = xd.currentTime[$(this).hasClass('xdsoft_month')?'getMonth':'getFullYear'](); + + select.show(); + for(var items = select.find('div.xdsoft_option'),i = 0;i=0 ){ timebox.css('marginTop','-'+(top-options.timeHeightInTimePicker)+'px') } - datetimepicker.trigger('scroll.timebox',[Math.abs(parseInt(timebox.css('marginTop')))]); + timeboxparent.trigger('scroll_element.xdsoft_scroller',[Math.abs(parseInt(timebox.css('marginTop'))/(height-pheight))]); period= ( period>10 )?10:period-10; !stop&&(timer = setTimeout(arguments.callee,v?v:period)); })(500); @@ -420,10 +562,9 @@ stop = true; $([document.body,window]).off('mouseup.xdsoft',arguments.callee); }); - }); - - // generating a calendar and timepicker - datetimepicker.on('change.xdsoft',function(){ + }); + // base handler - generating a calendar and timepicker + datetimepicker.on('xchange.xdsoft',function(event){ var xd = $(this).data('xdsoft_datetime'), table = ''; var start = new Date(xd.currentTime.getFullYear(),xd.currentTime.getMonth(),1); @@ -453,8 +594,8 @@ } table+=''; calendar.html(table); - mounth_picker.find('.xdsoft_label').eq(0).text(options.i18n[options.lang].months[xd.currentTime.getMonth()]); - mounth_picker.find('.xdsoft_label').eq(1).text(xd.currentTime.getFullYear()); + mounth_picker.find('.xdsoft_label span').eq(0).text(options.i18n[options.lang].months[xd.currentTime.getMonth()]); + mounth_picker.find('.xdsoft_label span').eq(1).text(xd.currentTime.getFullYear()); var time = '',h = '',m =''; var line_time = function (h,m){ var now = new Date(); @@ -491,6 +632,16 @@ } } timebox.html(time); + var opt = '',i = 0; + for( i = parseInt(options.yearStart);i<= parseInt(options.yearEnd);i++ ){ + opt+='
'+i+'
'; + } + yearselect.children().eq(0).html(opt); + for( i = 0,opt = '';i<= 11;i++ ){ + opt+='
'+options.i18n[options.lang].months[i]+'
'; + } + monthselect.children().eq(0).html(opt); + event.stopPropagation(); //timebox.find('.xdsoft_current').length&&timebox.css('marginTop','-'+parseInt(timebox.find('.xdsoft_current').index()*options.timeHeightInTimePicker)+'px'); }); datetimepicker.on('afterOpen.xdsoft',function(){ @@ -501,7 +652,7 @@ if( (height-pheight)