X-Git-Url: http://git.roojs.org/?a=blobdiff_plain;f=docs%2Fsrc%2FRoo_DatePicker.js.html;fp=docs%2Fsrc%2FRoo_DatePicker.js.html;h=6f51ec9b36e6336c2bb90e65a8a2d7c60f1d931a;hb=9ff8ded6bbbd258ecd646184ba26020874e2c085;hp=0000000000000000000000000000000000000000;hpb=2542b67d1a0768025056f2f330bfe50b64d1ad38;p=roojs1 diff --git a/docs/src/Roo_DatePicker.js.html b/docs/src/Roo_DatePicker.js.html new file mode 100644 index 0000000000..6f51ec9b36 --- /dev/null +++ b/docs/src/Roo_DatePicker.js.html @@ -0,0 +1,665 @@ +/home/alan/gitlive/roojs1/Roo/DatePicker.js/* + * Based on: + * Ext JS Library 1.1.1 + * Copyright(c) 2006-2007, Ext JS, LLC. + * + * Originally Released Under LGPL - original licence link has changed is not relivant. + * + * Fork - LGPL + * <script type="text/javascript"> + */ + +/** + * @class Roo.DatePicker + * @extends Roo.Component + * Simple date picker class. + * @constructor + * Create a new DatePicker + * @param {Object} config The config object + */ +Roo.DatePicker = function(config){ + Roo.DatePicker.superclass.constructor.call(this, config); + + this.value = config && config.value ? + config.value.clearTime() : new Date().clearTime(); + + this.addEvents({ + /** + * @event select + * Fires when a date is selected + * @param {DatePicker} this + * @param {Date} date The selected date + */ + 'select': true, + /** + * @event monthchange + * Fires when the displayed month changes + * @param {DatePicker} this + * @param {Date} date The selected month + */ + 'monthchange': true + }); + + if(this.handler){ + this.on("select", this.handler, this.scope || this); + } + // build the disabledDatesRE + if(!this.disabledDatesRE && this.disabledDates){ + var dd = this.disabledDates; + var re = "(?:"; + for(var i = 0; i < dd.length; i++){ + re += dd[i]; + if(i != dd.length-1) { + re += "|"; + } + } + this.disabledDatesRE = new RegExp(re + ")"); + } +}; + +Roo.extend(Roo.DatePicker, Roo.Component, { + /** + * @cfg {String} todayText + * The text to display on the button that selects the current date (defaults to "Today") + */ + todayText : "Today", + /** + * @cfg {String} okText + * The text to display on the ok button + */ + okText : "&#160;OK&#160;", // &#160; to give the user extra clicking room + /** + * @cfg {String} cancelText + * The text to display on the cancel button + */ + cancelText : "Cancel", + /** + * @cfg {String} todayTip + * The tooltip to display for the button that selects the current date (defaults to "{current date} (Spacebar)") + */ + todayTip : "{0} (Spacebar)", + /** + * @cfg {Date} minDate + * Minimum allowable date (JavaScript date object, defaults to null) + */ + minDate : null, + /** + * @cfg {Date} maxDate + * Maximum allowable date (JavaScript date object, defaults to null) + */ + maxDate : null, + /** + * @cfg {String} minText + * The error text to display if the minDate validation fails (defaults to "This date is before the minimum date") + */ + minText : "This date is before the minimum date", + /** + * @cfg {String} maxText + * The error text to display if the maxDate validation fails (defaults to "This date is after the maximum date") + */ + maxText : "This date is after the maximum date", + /** + * @cfg {String} format + * The default date format string which can be overriden for localization support. The format must be + * valid according to {@link Date#parseDate} (defaults to 'm/d/y'). + */ + format : "m/d/y", + /** + * @cfg {Array} disabledDays + * An array of days to disable, 0-based. For example, [0, 6] disables Sunday and Saturday (defaults to null). + */ + disabledDays : null, + /** + * @cfg {String} disabledDaysText + * The tooltip to display when the date falls on a disabled day (defaults to "") + */ + disabledDaysText : "", + /** + * @cfg {RegExp} disabledDatesRE + * JavaScript regular expression used to disable a pattern of dates (defaults to null) + */ + disabledDatesRE : null, + /** + * @cfg {String} disabledDatesText + * The tooltip text to display when the date falls on a disabled date (defaults to "") + */ + disabledDatesText : "", + /** + * @cfg {Boolean} constrainToViewport + * True to constrain the date picker to the viewport (defaults to true) + */ + constrainToViewport : true, + /** + * @cfg {Array} monthNames + * An array of textual month names which can be overriden for localization support (defaults to Date.monthNames) + */ + monthNames : Date.monthNames, + /** + * @cfg {Array} dayNames + * An array of textual day names which can be overriden for localization support (defaults to Date.dayNames) + */ + dayNames : Date.dayNames, + /** + * @cfg {String} nextText + * The next month navigation button tooltip (defaults to 'Next Month (Control+Right)') + */ + nextText: 'Next Month (Control+Right)', + /** + * @cfg {String} prevText + * The previous month navigation button tooltip (defaults to 'Previous Month (Control+Left)') + */ + prevText: 'Previous Month (Control+Left)', + /** + * @cfg {String} monthYearText + * The header month selector tooltip (defaults to 'Choose a month (Control+Up/Down to move years)') + */ + monthYearText: 'Choose a month (Control+Up/Down to move years)', + /** + * @cfg {Number} startDay + * Day index at which the week should begin, 0-based (defaults to 0, which is Sunday) + */ + startDay : 0, + /** + * @cfg {Bool} showClear + * Show a clear button (usefull for date form elements that can be blank.) + */ + + showClear: false, + + /** + * Sets the value of the date field + * @param {Date} value The date to set + */ + setValue : function(value){ + var old = this.value; + + if (typeof(value) == 'string') { + + value = Date.parseDate(value, this.format); + } + if (!value) { + value = new Date(); + } + + this.value = value.clearTime(true); + if(this.el){ + this.update(this.value); + } + }, + + /** + * Gets the current selected value of the date field + * @return {Date} The selected date + */ + getValue : function(){ + return this.value; + }, + + // private + focus : function(){ + if(this.el){ + this.update(this.activeDate); + } + }, + + // privateval + onRender : function(container, position){ + + var m = [ + '<table cellspacing="0">', + '<tr><td class="x-date-left"><a href="#" title="', this.prevText ,'">&#160;</a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText ,'">&#160;</a></td></tr>', + '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>']; + var dn = this.dayNames; + for(var i = 0; i < 7; i++){ + var d = this.startDay+i; + if(d > 6){ + d = d-7; + } + m.push("<th><span>", dn[d].substr(0,1), "</span></th>"); + } + m[m.length] = "</tr></thead><tbody><tr>"; + for(var i = 0; i < 42; i++) { + if(i % 7 == 0 && i != 0){ + m[m.length] = "</tr><tr>"; + } + m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>'; + } + m[m.length] = '</tr></tbody></table></td></tr><tr>'+ + '<td colspan="3" class="x-date-bottom" align="center"></td></tr></table><div class="x-date-mp"></div>'; + + var el = document.createElement("div"); + el.className = "x-date-picker"; + el.innerHTML = m.join(""); + + container.dom.insertBefore(el, position); + + this.el = Roo.get(el); + this.eventEl = Roo.get(el.firstChild); + + new Roo.util.ClickRepeater(this.el.child("td.x-date-left a"), { + handler: this.showPrevMonth, + scope: this, + preventDefault:true, + stopDefault:true + }); + + new Roo.util.ClickRepeater(this.el.child("td.x-date-right a"), { + handler: this.showNextMonth, + scope: this, + preventDefault:true, + stopDefault:true + }); + + this.eventEl.on("mousewheel", this.handleMouseWheel, this); + + this.monthPicker = this.el.down('div.x-date-mp'); + this.monthPicker.enableDisplayMode('block'); + + var kn = new Roo.KeyNav(this.eventEl, { + "left" : function(e){ + e.ctrlKey ? + this.showPrevMonth() : + this.update(this.activeDate.add("d", -1)); + }, + + "right" : function(e){ + e.ctrlKey ? + this.showNextMonth() : + this.update(this.activeDate.add("d", 1)); + }, + + "up" : function(e){ + e.ctrlKey ? + this.showNextYear() : + this.update(this.activeDate.add("d", -7)); + }, + + "down" : function(e){ + e.ctrlKey ? + this.showPrevYear() : + this.update(this.activeDate.add("d", 7)); + }, + + "pageUp" : function(e){ + this.showNextMonth(); + }, + + "pageDown" : function(e){ + this.showPrevMonth(); + }, + + "enter" : function(e){ + e.stopPropagation(); + return true; + }, + + scope : this + }); + + this.eventEl.on("click", this.handleDateClick, this, {delegate: "a.x-date-date"}); + + this.eventEl.addKeyListener(Roo.EventObject.SPACE, this.selectToday, this); + + this.el.unselectable(); + + this.cells = this.el.select("table.x-date-inner tbody td"); + this.textNodes = this.el.query("table.x-date-inner tbody span"); + + this.mbtn = new Roo.Button(this.el.child("td.x-date-middle", true), { + text: "&#160;", + tooltip: this.monthYearText + }); + + this.mbtn.on('click', this.showMonthPicker, this); + this.mbtn.el.child(this.mbtn.menuClassTarget).addClass("x-btn-with-menu"); + + + var today = (new Date()).dateFormat(this.format); + + var baseTb = new Roo.Toolbar(this.el.child("td.x-date-bottom", true)); + if (this.showClear) { + baseTb.add( new Roo.Toolbar.Fill()); + } + baseTb.add({ + text: String.format(this.todayText, today), + tooltip: String.format(this.todayTip, today), + handler: this.selectToday, + scope: this + }); + + //var todayBtn = new Roo.Button(this.el.child("td.x-date-bottom", true), { + + //}); + if (this.showClear) { + + baseTb.add( new Roo.Toolbar.Fill()); + baseTb.add({ + text: '&#160;', + cls: 'x-btn-icon x-btn-clear', + handler: function() { + //this.value = ''; + this.fireEvent("select", this, ''); + }, + scope: this + }); + } + + + if(Roo.isIE){ + this.el.repaint(); + } + this.update(this.value); + }, + + createMonthPicker : function(){ + if(!this.monthPicker.dom.firstChild){ + var buf = ['<table border="0" cellspacing="0">']; + for(var i = 0; i < 6; i++){ + buf.push( + '<tr><td class="x-date-mp-month"><a href="#">', this.monthNames[i].substr(0, 3), '</a></td>', + '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', this.monthNames[i+6].substr(0, 3), '</a></td>', + i == 0 ? + '<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>' : + '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>' + ); + } + buf.push( + '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">', + this.okText, + '</button><button type="button" class="x-date-mp-cancel">', + this.cancelText, + '</button></td></tr>', + '</table>' + ); + this.monthPicker.update(buf.join('')); + this.monthPicker.on('click', this.onMonthClick, this); + this.monthPicker.on('dblclick', this.onMonthDblClick, this); + + this.mpMonths = this.monthPicker.select('td.x-date-mp-month'); + this.mpYears = this.monthPicker.select('td.x-date-mp-year'); + + this.mpMonths.each(function(m, a, i){ + i += 1; + if((i%2) == 0){ + m.dom.xmonth = 5 + Math.round(i * .5); + }else{ + m.dom.xmonth = Math.round((i-1) * .5); + } + }); + } + }, + + showMonthPicker : function(){ + this.createMonthPicker(); + var size = this.el.getSize(); + this.monthPicker.setSize(size); + this.monthPicker.child('table').setSize(size); + + this.mpSelMonth = (this.activeDate || this.value).getMonth(); + this.updateMPMonth(this.mpSelMonth); + this.mpSelYear = (this.activeDate || this.value).getFullYear(); + this.updateMPYear(this.mpSelYear); + + this.monthPicker.slideIn('t', {duration:.2}); + }, + + updateMPYear : function(y){ + this.mpyear = y; + var ys = this.mpYears.elements; + for(var i = 1; i <= 10; i++){ + var td = ys[i-1], y2; + if((i%2) == 0){ + y2 = y + Math.round(i * .5); + td.firstChild.innerHTML = y2; + td.xyear = y2; + }else{ + y2 = y - (5-Math.round(i * .5)); + td.firstChild.innerHTML = y2; + td.xyear = y2; + } + this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel'); + } + }, + + updateMPMonth : function(sm){ + this.mpMonths.each(function(m, a, i){ + m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel'); + }); + }, + + selectMPMonth: function(m){ + + }, + + onMonthClick : function(e, t){ + e.stopEvent(); + var el = new Roo.Element(t), pn; + if(el.is('button.x-date-mp-cancel')){ + this.hideMonthPicker(); + } + else if(el.is('button.x-date-mp-ok')){ + this.update(new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate())); + this.hideMonthPicker(); + } + else if(pn = el.up('td.x-date-mp-month', 2)){ + this.mpMonths.removeClass('x-date-mp-sel'); + pn.addClass('x-date-mp-sel'); + this.mpSelMonth = pn.dom.xmonth; + } + else if(pn = el.up('td.x-date-mp-year', 2)){ + this.mpYears.removeClass('x-date-mp-sel'); + pn.addClass('x-date-mp-sel'); + this.mpSelYear = pn.dom.xyear; + } + else if(el.is('a.x-date-mp-prev')){ + this.updateMPYear(this.mpyear-10); + } + else if(el.is('a.x-date-mp-next')){ + this.updateMPYear(this.mpyear+10); + } + }, + + onMonthDblClick : function(e, t){ + e.stopEvent(); + var el = new Roo.Element(t), pn; + if(pn = el.up('td.x-date-mp-month', 2)){ + this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate())); + this.hideMonthPicker(); + } + else if(pn = el.up('td.x-date-mp-year', 2)){ + this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate())); + this.hideMonthPicker(); + } + }, + + hideMonthPicker : function(disableAnim){ + if(this.monthPicker){ + if(disableAnim === true){ + this.monthPicker.hide(); + }else{ + this.monthPicker.slideOut('t', {duration:.2}); + } + } + }, + + // private + showPrevMonth : function(e){ + this.update(this.activeDate.add("mo", -1)); + }, + + // private + showNextMonth : function(e){ + this.update(this.activeDate.add("mo", 1)); + }, + + // private + showPrevYear : function(){ + this.update(this.activeDate.add("y", -1)); + }, + + // private + showNextYear : function(){ + this.update(this.activeDate.add("y", 1)); + }, + + // private + handleMouseWheel : function(e){ + var delta = e.getWheelDelta(); + if(delta > 0){ + this.showPrevMonth(); + e.stopEvent(); + } else if(delta < 0){ + this.showNextMonth(); + e.stopEvent(); + } + }, + + // private + handleDateClick : function(e, t){ + e.stopEvent(); + if(t.dateValue && !Roo.fly(t.parentNode).hasClass("x-date-disabled")){ + this.setValue(new Date(t.dateValue)); + this.fireEvent("select", this, this.value); + } + }, + + // private + selectToday : function(){ + this.setValue(new Date().clearTime()); + this.fireEvent("select", this, this.value); + }, + + // private + update : function(date) + { + var vd = this.activeDate; + this.activeDate = date; + if(vd && this.el){ + var t = date.getTime(); + if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){ + this.cells.removeClass("x-date-selected"); + this.cells.each(function(c){ + if(c.dom.firstChild.dateValue == t){ + c.addClass("x-date-selected"); + setTimeout(function(){ + try{c.dom.firstChild.focus();}catch(e){} + }, 50); + return false; + } + }); + return; + } + } + + var days = date.getDaysInMonth(); + var firstOfMonth = date.getFirstDateOfMonth(); + var startingPos = firstOfMonth.getDay()-this.startDay; + + if(startingPos <= this.startDay){ + startingPos += 7; + } + + var pm = date.add("mo", -1); + var prevStart = pm.getDaysInMonth()-startingPos; + + var cells = this.cells.elements; + var textEls = this.textNodes; + days += startingPos; + + // convert everything to numbers so it's fast + var day = 86400000; + var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime(); + var today = new Date().clearTime().getTime(); + var sel = date.clearTime().getTime(); + var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY; + var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY; + var ddMatch = this.disabledDatesRE; + var ddText = this.disabledDatesText; + var ddays = this.disabledDays ? this.disabledDays.join("") : false; + var ddaysText = this.disabledDaysText; + var format = this.format; + + var setCellClass = function(cal, cell){ + cell.title = ""; + var t = d.getTime(); + cell.firstChild.dateValue = t; + if(t == today){ + cell.className += " x-date-today"; + cell.title = cal.todayText; + } + if(t == sel){ + cell.className += " x-date-selected"; + setTimeout(function(){ + try{cell.firstChild.focus();}catch(e){} + }, 50); + } + // disabling + if(t < min) { + cell.className = " x-date-disabled"; + cell.title = cal.minText; + return; + } + if(t > max) { + cell.className = " x-date-disabled"; + cell.title = cal.maxText; + return; + } + if(ddays){ + if(ddays.indexOf(d.getDay()) != -1){ + cell.title = ddaysText; + cell.className = " x-date-disabled"; + } + } + if(ddMatch && format){ + var fvalue = d.dateFormat(format); + if(ddMatch.test(fvalue)){ + cell.title = ddText.replace("%0", fvalue); + cell.className = " x-date-disabled"; + } + } + }; + + var i = 0; + for(; i < startingPos; i++) { + textEls[i].innerHTML = (++prevStart); + d.setDate(d.getDate()+1); + cells[i].className = "x-date-prevday"; + setCellClass(this, cells[i]); + } + for(; i < days; i++){ + intDay = i - startingPos + 1; + textEls[i].innerHTML = (intDay); + d.setDate(d.getDate()+1); + cells[i].className = "x-date-active"; + setCellClass(this, cells[i]); + } + var extraDays = 0; + for(; i < 42; i++) { + textEls[i].innerHTML = (++extraDays); + d.setDate(d.getDate()+1); + cells[i].className = "x-date-nextday"; + setCellClass(this, cells[i]); + } + + this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear()); + this.fireEvent('monthchange', this, date); + + if(!this.internalRender){ + var main = this.el.dom.firstChild; + var w = main.offsetWidth; + this.el.setWidth(w + this.el.getBorderWidth("lr")); + Roo.fly(main).setWidth(w); + this.internalRender = true; + // opera does not respect the auto grow header center column + // then, after it gets a width opera refuses to recalculate + // without a second pass + if(Roo.isOpera && !this.secondPass){ + main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px"; + this.secondPass = true; + this.update.defer(10, this, [date]); + } + } + + + } +}); \ No newline at end of file