From 270282e3a26b21184a2051995cb5b9a2755b823d Mon Sep 17 00:00:00 2001 From: wei <> Date: Sat, 18 Feb 2006 23:41:16 +0000 Subject: Update some javascript code. --- .../Web/Javascripts/colorpicker/colorpicker.js | 4 +- framework/Web/Javascripts/datepicker/datepicker.js | 57 +++- framework/Web/Javascripts/extended/event.js | 137 +++++++-- framework/Web/Javascripts/extended/string.js | 60 +++- framework/Web/Javascripts/extended/util.js | 4 +- framework/Web/Javascripts/js/colorpicker.js | 4 +- framework/Web/Javascripts/js/datepicker.js | 323 +++++++++++---------- framework/Web/Javascripts/js/validator.js | 9 + framework/Web/Javascripts/prado/prado.js | 10 + framework/Web/Javascripts/prado/validation.js | 17 +- framework/Web/Javascripts/prado/validators.js | 6 +- framework/Web/UI/THtmlWriter.php | 12 + framework/Web/UI/WebControls/TCompareValidator.php | 2 +- framework/Web/UI/WebControls/TDatePicker.php | 276 ++++++++++++++++-- .../Web/UI/WebControls/TValidationSummary.php | 29 ++ .../Web/UI/WebControls/TValueTypeValidator.php | 2 +- 16 files changed, 721 insertions(+), 231 deletions(-) (limited to 'framework/Web') diff --git a/framework/Web/Javascripts/colorpicker/colorpicker.js b/framework/Web/Javascripts/colorpicker/colorpicker.js index c2c9cd28..cc4587ff 100644 --- a/framework/Web/Javascripts/colorpicker/colorpicker.js +++ b/framework/Web/Javascripts/colorpicker/colorpicker.js @@ -338,8 +338,8 @@ Object.extend(Prado.WebUI.TColorPicker.prototype, Event.observe(document.body, "mouseup", this._onMouseUp); //Because of using the CSS filter, IE can't do colour change quickly - if(!Prado.Browser().ie) - Event.observe(document.body, "mousemove", this._onMouseMove); + //if(!Prado.Browser().ie) + Event.observe(document.body, "mousemove", this._onMouseMove); Event.observe(this.buttons.Cancel, "click", this.hide.bindEvent(this,this.options['Mode'])); Event.observe(this.buttons.OK, "click", this.onOKClicked.bind(this)); diff --git a/framework/Web/Javascripts/datepicker/datepicker.js b/framework/Web/Javascripts/datepicker/datepicker.js index 5468fb6c..49bcfac9 100644 --- a/framework/Web/Javascripts/datepicker/datepicker.js +++ b/framework/Web/Javascripts/datepicker/datepicker.js @@ -16,31 +16,30 @@ Prado.WebUI.TDatePicker.prototype = FromYear : 2000, UpToYear: 2015, - initialize : function(control, attr) + initialize : function(options) { - this.attr = attr || []; - this.control = $(control); + this.options = options || []; + this.control = $(options.ID); this.dateSlot = new Array(42); this.weekSlot = new Array(6); this.minimalDaysInFirstWeek = 4; this.selectedDate = this.newDate(); //which element to trigger to show the calendar - if(this.attr.Trigger) + if(this.options.Trigger) { - this.trigger = $(this.attr.Trigger) ; - var triggerEvent = this.attr.TriggerEvent || "click"; + this.trigger = $(this.options.Trigger) ; + var triggerEvent = this.options.TriggerEvent || "click"; } else { this.trigger = this.control; - var triggerEvent = this.attr.TriggerEvent || "focus"; + var triggerEvent = this.options.TriggerEvent || "focus"; } + Object.extend(this,options); + Event.observe(this.trigger, triggerEvent, this.show.bindEvent(this)); - - Object.extend(this,attr); - this.create(); }, @@ -389,7 +388,20 @@ Prado.WebUI.TDatePicker.prototype = onchange : function() { - this.control.value = this.formatDate(); + if(this.options.InputMode == "TextBox") + this.control.value = this.formatDate(); + else + { + var day = $(this.options.ID+"_day"); + var month = $(this.options.ID+"_month"); + var years = $(this.options.ID+"_year").options; + var date = this.selectedDate; + day.selectedIndex = date.getDate()-1; + month.selectedIndex = date.getMonth(); + var currentYear = date.getFullYear(); + for(var i = 0; i < years.length; i++) + years[i].selected = years[i].value.toInteger() == currentYear; + } }, formatDate : function() @@ -457,7 +469,12 @@ Prado.WebUI.TDatePicker.prototype = if(!this.showing) { var pos = Position.cumulativeOffset(this.control); - pos[1] += this.control.offsetHeight; + + if(this.options.InputMode == "TextBox") + pos[1] += this.control.offsetHeight; + else + pos[1] += $(this.options.ID+"_day").offsetHeight-1; + this._calDiv.style.display = "block"; this._calDiv.style.top = (pos[1]-1) + "px"; this._calDiv.style.left = pos[0] + "px"; @@ -466,7 +483,7 @@ Prado.WebUI.TDatePicker.prototype = this.documentClickEvent = this.hideOnClick.bindEvent(this); this.documentKeyDownEvent = this.keyPressed.bindEvent(this); Event.observe(document.body, "click", this.documentClickEvent); - var date = Date.SimpleParse(Form.Element.getValue(this.control), this.Format); + var date = this.getDateFromInput(); if(!isNull(date)) { this.selectedDate = date; @@ -476,6 +493,20 @@ Prado.WebUI.TDatePicker.prototype = this.showing = true; } }, + + getDateFromInput : function() + { + if(this.options.InputMode == "TextBox") + return Date.SimpleParse($F(this.control), this.Format); + else + { + var day = $F(this.options.ID+"_day"); + var month = $F(this.options.ID+"_month"); + var year = $F(this.options.ID+"_year"); + var newdate=new Date(year,month,day, 0, 0, 0); + return newdate; + } + }, //hide the calendar when clicked outside any calendar hideOnClick : function(ev) diff --git a/framework/Web/Javascripts/extended/event.js b/framework/Web/Javascripts/extended/event.js index b6dccf3b..fc1c447b 100644 --- a/framework/Web/Javascripts/extended/event.js +++ b/framework/Web/Javascripts/extended/event.js @@ -1,45 +1,137 @@ -Object.extend(Event, { - OnLoad : function (fn) { +/** + * @class Event extensions. + */ +Object.extend(Event, +{ + /** + * Register a function to be executed when the page is loaded. + * Note that the page is only loaded if all resources (e.g. images) + * are loaded. + * + * Example: Show an alert box with message "Page Loaded!" when the + * page finished loading. + * + * Event.OnLoad(function(){ alert("Page Loaded!"); }); + * + * + * @param {Function} function to execute when page is loaded. + */ + OnLoad : function (fn) + { // opera onload is in document, not window - var w = document.addEventListener && !window.addEventListener ? document : window; + var w = document.addEventListener && + !window.addEventListener ? document : window; Event.__observe(w,'load',fn); }, - observe: function(elements, name, observer, useCapture) { - if(!isList(elements)) - return this.__observe(elements, name, observer, useCapture); - for(var i=0; iuseCapture is true, the + * listener is registered as a capturing event listener. If + * useCapture is false, it is registered as a + * normal event listener. + * + * Event.observe may be called multiple times to register + * multiple event handlers for the same type of event on the + * same nodes. Note, however, that the DOM makes no guarantees + * about the order in which multiple event handlers will be invoked. + * + * Example: Show an alert box with message "Clicked!" when a link + * with ID "link1" is clicked. + * + * var link1_clicked = function() + * { + * alert("Clicked!"); + * }; + * Event.observe("link1", "click", link1_clicked); + * + * + * @param {Object} element id string, DOM Element, or an Array + * of element ids or elements. + * @param {String} The type of event for which the event listener + * is to be invoked. For example, "load", "click", or "mousedown". + * @param {Function} The event listener function that will be + * invoked when an event of the specified type is dispatched to + * this Document node. + * @param {Boolean} If true, the specified listener is to be + * invoked only during the capturing phase of event propagation. + * The more common value of false means that the listener + * will not be invoked during the capturing phase but instead will + * be invoked when this node is the actual event target or when the + * event bubbles up to this node from its original target. + */ + observe: function(elements, name, observer, useCapture) + { + if(!isList(elements)) + return this.__observe(elements, name, observer, useCapture); + for(var i=0; i 0) - || element.attachEvent)) - name = 'keydown'; + if (name == 'keypress' && + ((navigator.appVersion.indexOf('AppleWebKit') > 0) + || element.attachEvent)) + name = 'keydown'; - this._observeAndCache(element, name, observer, useCapture); - }, - keyCode : function(e) + this._observeAndCache(element, name, observer, useCapture); + }, + + /** + * @param {Event} a keyboard event + * @return {Number} the Unicode character code generated by the key + * that was struck. + */ + keyCode : function(e) { return e.keyCode != null ? e.keyCode : e.charCode }, + /** + * @param {String} event type or event name. + * @return {Boolean} true if event type is of HTMLEvent, false + * otherwise + */ isHTMLEvent : function(type) { - var events = ['abort', 'blur', 'change', 'error', 'focus', 'load', 'reset', 'resize', 'scroll', 'select', 'submit', 'unload']; + var events = ['abort', 'blur', 'change', 'error', 'focus', + 'load', 'reset', 'resize', 'scroll', 'select', + 'submit', 'unload']; return events.include(type); }, + /** + * @param {String} event type or event name + * @return {Boolean} true if event type is of MouseEvent, + * false otherwise + */ isMouseEvent : function(type) { - var events = ['click', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup']; + var events = ['click', 'mousedown', 'mousemove', 'mouseout', + 'mouseover', 'mouseup']; return events.include(type); }, + /** + * Dispatch the DOM event of a given type on a DOM + * element. Only HTMLEvent and MouseEvent can be + * dispatched, keyboard events or UIEvent can not be dispatch + * via javascript. + * @param {Object} element id string or a DOM element. + * @param {String} event type to dispatch. + */ fireEvent : function(element,type) { + element = $(element); if(document.createEvent) { if(Event.isHTMLEvent(type)) @@ -51,7 +143,8 @@ Object.extend(Event, { { var event = document.createEvent('MouseEvents'); event.initMouseEvent(type,true,true, - document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null); + document.defaultView, 1, 0, 0, 0, 0, false, + false, false, false, 0, null); } else { diff --git a/framework/Web/Javascripts/extended/string.js b/framework/Web/Javascripts/extended/string.js index e265edf4..46274256 100644 --- a/framework/Web/Javascripts/extended/string.js +++ b/framework/Web/Javascripts/extended/string.js @@ -1,4 +1,14 @@ +/** + * @class String extensions + */ Object.extend(String.prototype, { + /** + * @param {String} "left" to pad the string on the left, "right" to pad right. + * @param {Number} minimum string length. + * @param {String} character(s) to pad + * @return {String} padded character(s) on the left or right to satisfy minimum string length + */ + pad : function(side, len, chr) { if (!chr) chr = ' '; var s = this; @@ -7,26 +17,49 @@ Object.extend(String.prototype, { return s; }, + /** + * @param {Number} minimum string length. + * @param {String} character(s) to pad + * @return {String} padded character(s) on the left to satisfy minimum string length + */ padLeft : function(len, chr) { return this.pad('left',len,chr); }, + /** + * @param {Number} minimum string length. + * @param {String} character(s) to pad + * @return {String} padded character(s) on the right to satisfy minimum string length + */ padRight : function(len, chr) { return this.pad('right',len,chr); }, + /** + * @param {Number} minimum string length. + * @return {String} append zeros to the left to satisfy minimum string length. + */ zerofill : function(len) { return this.padLeft(len,'0'); }, + /** + * @return {String} removed white spaces from both ends. + */ trim : function() { return this.replace(/^\s+|\s+$/g,''); }, + /** + * @return {String} removed white spaces from the left end. + */ trimLeft : function() { return this.replace(/^\s+/,''); }, + /** + * @return {String} removed white spaces from the right end. + */ trimRight : function() { return this.replace(/\s+$/,''); }, @@ -35,7 +68,7 @@ Object.extend(String.prototype, { * Convert period separated function names into a function reference. * e.g. "Prado.AJAX.Callback.Action.setValue".toFunction() will return * the actual function Prado.AJAX.Callback.Action.setValue() - * @return Function the corresponding function represented by the string. + * @return {Function} the corresponding function represented by the string. */ toFunction : function() { @@ -58,7 +91,7 @@ Object.extend(String.prototype, { /** * Convert a string into integer, returns null if not integer. - * @return {integer|null} null if string does not represent an integer. + * @return {Number} null if string does not represent an integer. */ toInteger : function() { @@ -72,8 +105,8 @@ Object.extend(String.prototype, { /** * Convert a string into a double/float value. Internationalization * is not supported - * @param {string} the decimal character - * @return {float|null} null if string does not represent a float value + * @param {String} the decimal character + * @return {Double} null if string does not represent a float value */ toDouble : function(decimalchar) { @@ -93,10 +126,10 @@ Object.extend(String.prototype, { * of dicimal digits, grouping and decimal characters can be specified. * The currency input format is very strict, null will be returned if * the pattern does not match. - * @param {string} the grouping character, default is "," - * @param {int} number of decimal digits - * @param {string} the decimal character, default is "." - * @type {float|null} the currency value as float. + * @param {String} the grouping character, default is "," + * @param {Number} number of decimal digits + * @param {String} the decimal character, default is "." + * @type {Double} the currency value as float. */ toCurrency : function(groupchar, digits, decimalchar) { @@ -116,5 +149,16 @@ Object.extend(String.prototype, { + ((digits > 0) ? "." + m[7] : ""); var num = parseFloat(cleanInput); return (isNaN(num) ? null : num); + }, + + /** + * Converts the string to a date by finding values that matches the + * date format pattern. + * @param string date format pattern, e.g. MM-dd-yyyy + * @return {Date} the date extracted from the string + */ + toDate : function(format) + { + return Date.SimpleParse(this, format); } }); diff --git a/framework/Web/Javascripts/extended/util.js b/framework/Web/Javascripts/extended/util.js index fc5ec844..86f2ae90 100644 --- a/framework/Web/Javascripts/extended/util.js +++ b/framework/Web/Javascripts/extended/util.js @@ -1,10 +1,10 @@ /** - * Test if it is an object and has no constructors. + * @return {Boolean} true if is an object and has no constructors. */ function isAlien(a) { return isObject(a) && typeof a.constructor != 'function' } /** - * isArray? + * @return {Boolean} */ function isArray(a) { return isObject(a) && a.constructor == Array } diff --git a/framework/Web/Javascripts/js/colorpicker.js b/framework/Web/Javascripts/js/colorpicker.js index 2484b6d8..e220ab33 100644 --- a/framework/Web/Javascripts/js/colorpicker.js +++ b/framework/Web/Javascripts/js/colorpicker.js @@ -320,7 +320,7 @@ this.inputs=_65; var _67=Prado.WebUI.TColorPicker.UIImages; this.inputs["currentColor"]=SPAN({className:"currentColor"}); this.inputs["oldColor"]=SPAN({className:"oldColor"}); -var _68=TABLE({className:"inputs"},TBODY(null,TR(null,TD({className:"currentcolor",colSpan:2},this.inputs["currentColor"],this.inputs["oldColor"])),TR(null,TD(null,"H:"),TD(null,this.inputs["H"],"\xc2\xb0")),TR(null,TD(null,"S:"),TD(null,this.inputs["S"],"%")),TR(null,TD(null,"V:"),TD(null,this.inputs["V"],"%")),TR(null,TD({className:"gap"},"R:"),TD({className:"gap"},this.inputs["R"])),TR(null,TD(null,"G:"),TD(null,this.inputs["G"])),TR(null,TD(null,"B:"),TD(null,this.inputs["B"])),TR(null,TD({className:"gap"},"#"),TD({className:"gap"},this.inputs["HEX"])))); +var _68=TABLE({className:"inputs"},TBODY(null,TR(null,TD({className:"currentcolor",colSpan:2},this.inputs["currentColor"],this.inputs["oldColor"])),TR(null,TD(null,"H:"),TD(null,this.inputs["H"],'°')),TR(null,TD(null,"S:"),TD(null,this.inputs["S"],"%")),TR(null,TD(null,"V:"),TD(null,this.inputs["V"],"%")),TR(null,TD({className:"gap"},"R:"),TD({className:"gap"},this.inputs["R"])),TR(null,TD(null,"G:"),TD(null,this.inputs["G"])),TR(null,TD(null,"B:"),TD(null,this.inputs["B"])),TR(null,TD({className:"gap"},"#"),TD({className:"gap"},this.inputs["HEX"])))); var _69={selector:SPAN({className:"selector"}),background:SPAN({className:"colorpanel"}),slider:SPAN({className:"slider"}),hue:SPAN({className:"strip"})}; if(Prado.Browser().ie){ var _70="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"; @@ -350,9 +350,7 @@ this._onMouseMove=this.onMouseMove.bind(this); Event.observe(this.inputs.background,"mousedown",this._onColorMouseDown); Event.observe(this.inputs.hue,"mousedown",this._onHueMouseDown); Event.observe(document.body,"mouseup",this._onMouseUp); -if(!Prado.Browser().ie){ Event.observe(document.body,"mousemove",this._onMouseMove); -} Event.observe(this.buttons.Cancel,"click",this.hide.bindEvent(this,this.options["Mode"])); Event.observe(this.buttons.OK,"click",this.onOKClicked.bind(this)); },onColorMouseDown:function(ev){ diff --git a/framework/Web/Javascripts/js/datepicker.js b/framework/Web/Javascripts/js/datepicker.js index 4ab5cd68..b9d7b610 100644 --- a/framework/Web/Javascripts/js/datepicker.js +++ b/framework/Web/Javascripts/js/datepicker.js @@ -1,46 +1,46 @@ Prado.WebUI.TDatePicker=Class.create(); -Prado.WebUI.TDatePicker.prototype={MonthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],ShortWeekDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],Format:"yyyy-MM-dd",FirstDayOfWeek:1,ClassName:"TDatePicker",FromYear:2000,UpToYear:2015,initialize:function(_1,_2){ -this.attr=_2||[]; -this.control=$(_1); +Prado.WebUI.TDatePicker.prototype={MonthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],ShortWeekDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],Format:"yyyy-MM-dd",FirstDayOfWeek:1,ClassName:"TDatePicker",FromYear:2000,UpToYear:2015,initialize:function(_1){ +this.options=_1||[]; +this.control=$(_1.ID); this.dateSlot=new Array(42); this.weekSlot=new Array(6); this.minimalDaysInFirstWeek=4; this.selectedDate=this.newDate(); -if(this.attr.Trigger){ -this.trigger=$(this.attr.Trigger); -var _3=this.attr.TriggerEvent||"click"; +if(this.options.Trigger){ +this.trigger=$(this.options.Trigger); +var _2=this.options.TriggerEvent||"click"; }else{ this.trigger=this.control; -var _3=this.attr.TriggerEvent||"focus"; +var _2=this.options.TriggerEvent||"focus"; } -Event.observe(this.trigger,_3,this.show.bindEvent(this)); -Object.extend(this,_2); +Object.extend(this,_1); +Event.observe(this.trigger,_2,this.show.bindEvent(this)); this.create(); },create:function(){ +var _3; var _4; var _5; -var _6; var tr; var td; this._calDiv=document.createElement("div"); this._calDiv.className=this.ClassName; this._calDiv.style.display="none"; this._calDiv.style.position="absolute"; -_4=document.createElement("div"); -_4.className="calendarHeader"; -this._calDiv.appendChild(_4); -_5=document.createElement("table"); -_5.style.cellSpacing=0; +_3=document.createElement("div"); +_3.className="calendarHeader"; +this._calDiv.appendChild(_3); +_4=document.createElement("table"); +_4.style.cellSpacing=0; +_3.appendChild(_4); +_5=document.createElement("tbody"); _4.appendChild(_5); -_6=document.createElement("tbody"); -_5.appendChild(_6); tr=document.createElement("tr"); -_6.appendChild(tr); +_5.appendChild(tr); td=document.createElement("td"); -var _9=document.createElement("button"); -_9.className="prevMonthButton"; -_9.appendChild(document.createTextNode("<<")); -td.appendChild(_9); +var _8=document.createElement("button"); +_8.className="prevMonthButton"; +_8.appendChild(document.createTextNode("<<")); +td.appendChild(_8); tr.appendChild(td); td=document.createElement("td"); tr.appendChild(td); @@ -72,58 +72,58 @@ this._yearSelect.appendChild(opt); td.appendChild(this._yearSelect); td=document.createElement("td"); td.className="nextMonthButton"; -var _12=document.createElement("button"); -_12.appendChild(document.createTextNode(">>")); -td.appendChild(_12); +var _11=document.createElement("button"); +_11.appendChild(document.createTextNode(">>")); +td.appendChild(_11); tr.appendChild(td); -_4=document.createElement("div"); -_4.className="calendarBody"; -this._calDiv.appendChild(_4); -var _13=_4; -var _14; -_5=document.createElement("table"); -_5.className="grid"; -_4.appendChild(_5); -var _15=document.createElement("thead"); -_5.appendChild(_15); +_3=document.createElement("div"); +_3.className="calendarBody"; +this._calDiv.appendChild(_3); +var _12=_3; +var _13; +_4=document.createElement("table"); +_4.className="grid"; +_3.appendChild(_4); +var _14=document.createElement("thead"); +_4.appendChild(_14); tr=document.createElement("tr"); -_15.appendChild(tr); +_14.appendChild(tr); for(i=0;i<7;++i){ td=document.createElement("th"); -_14=document.createTextNode(this.ShortWeekDayNames[(i+this.FirstDayOfWeek)%7]); -td.appendChild(_14); +_13=document.createTextNode(this.ShortWeekDayNames[(i+this.FirstDayOfWeek)%7]); +td.appendChild(_13); td.className="weekDayHead"; tr.appendChild(td); } -_6=document.createElement("tbody"); -_5.appendChild(_6); +_5=document.createElement("tbody"); +_4.appendChild(_5); for(week=0;week<6;++week){ tr=document.createElement("tr"); -_6.appendChild(tr); +_5.appendChild(tr); for(day=0;day<7;++day){ td=document.createElement("td"); td.className="calendarDate"; -_14=document.createTextNode(String.fromCharCode(160)); -td.appendChild(_14); +_13=document.createTextNode(String.fromCharCode(160)); +td.appendChild(_13); tr.appendChild(td); var tmp=new Object(); tmp.tag="DATE"; tmp.value=-1; -tmp.data=_14; +tmp.data=_13; this.dateSlot[(week*7)+day]=tmp; Event.observe(td,"mouseover",this.hover.bindEvent(this)); Event.observe(td,"mouseout",this.hover.bindEvent(this)); } } -_4=document.createElement("div"); -_4.className="calendarFooter"; -this._calDiv.appendChild(_4); -var _17=document.createElement("button"); -_17.className="todayButton"; -var _18=this.newDate(); -var _19=_18.SimpleFormat(this.Format); -_17.appendChild(document.createTextNode(_19)); -_4.appendChild(_17); +_3=document.createElement("div"); +_3.className="calendarFooter"; +this._calDiv.appendChild(_3); +var _16=document.createElement("button"); +_16.className="todayButton"; +var _17=this.newDate(); +var _18=_17.SimpleFormat(this.Format); +_16.appendChild(document.createTextNode(_18)); +_3.appendChild(_16); if(Prado.Browser().ie){ this.iePopUp=document.createElement("iframe"); this.iePopUp.src=""; @@ -136,24 +136,24 @@ document.body.appendChild(this._calDiv); this.update(); this.updateHeader(); this.ieHack(true); -_9.hideFocus=true; -_12.hideFocus=true; -_17.hideFocus=true; -Event.observe(_9,"click",this.prevMonth.bindEvent(this)); -Event.observe(_12,"click",this.nextMonth.bindEvent(this)); -Event.observe(_17,"click",this.selectToday.bindEvent(this)); +_8.hideFocus=true; +_11.hideFocus=true; +_16.hideFocus=true; +Event.observe(_8,"click",this.prevMonth.bindEvent(this)); +Event.observe(_11,"click",this.nextMonth.bindEvent(this)); +Event.observe(_16,"click",this.selectToday.bindEvent(this)); Event.observe(this._monthSelect,"change",this.monthSelect.bindEvent(this)); Event.observe(this._yearSelect,"change",this.yearSelect.bindEvent(this)); Event.observe(this._calDiv,"mousewheel",this.mouseWheelChange.bindEvent(this)); -Event.observe(_13,"click",this.selectDate.bindEvent(this)); -},ieHack:function(_20){ +Event.observe(_12,"click",this.selectDate.bindEvent(this)); +},ieHack:function(_19){ if(this.iePopUp){ this.iePopUp.style.display="block"; this.iePopUp.style.top=(this._calDiv.offsetTop-1)+"px"; this.iePopUp.style.left=(this._calDiv.offsetLeft-1)+"px"; this.iePopUp.style.width=Math.abs(this._calDiv.offsetWidth-2)+"px"; this.iePopUp.style.height=(this._calDiv.offsetHeight+1)+"px"; -if(_20){ +if(_19){ this.iePopUp.style.display="none"; } } @@ -174,48 +174,48 @@ if(kc==Event.KEY_ESC){ Event.stop(ev); this.hide(); } -var _23=function(_24,_25){ -_24=(_24+12)%12; -var _26=[31,28,31,30,31,30,31,31,30,31,30,31]; -var res=_26[_24]; -if(_24==1){ -res+=_25%4==0&&!(_25%400==0)?1:0; +var _22=function(_23,_24){ +_23=(_23+12)%12; +var _25=[31,28,31,30,31,30,31,31,30,31,30,31]; +var res=_25[_23]; +if(_23==1){ +res+=_24%4==0&&!(_24%400==0)?1:0; } return res; }; if(kc<37||kc>40){ return true; } -var _28=this.selectedDate; -var d=_28.valueOf(); +var _27=this.selectedDate; +var d=_27.valueOf(); if(kc==Event.KEY_LEFT){ if(ev.ctrlKey||ev.shiftKey){ -_28.setDate(Math.min(_28.getDate(),_23(_28.getMonth()-1,_28.getFullYear()))); -d=_28.setMonth(_28.getMonth()-1); +_27.setDate(Math.min(_27.getDate(),_22(_27.getMonth()-1,_27.getFullYear()))); +d=_27.setMonth(_27.getMonth()-1); }else{ d-=86400000; } }else{ if(kc==Event.KEY_RIGHT){ if(ev.ctrlKey||ev.shiftKey){ -_28.setDate(Math.min(_28.getDate(),_23(_28.getMonth()+1,_28.getFullYear()))); -d=_28.setMonth(_28.getMonth()+1); +_27.setDate(Math.min(_27.getDate(),_22(_27.getMonth()+1,_27.getFullYear()))); +d=_27.setMonth(_27.getMonth()+1); }else{ d+=86400000; } }else{ if(kc==Event.KEY_UP){ if(ev.ctrlKey||ev.shiftKey){ -_28.setDate(Math.min(_28.getDate(),_23(_28.getMonth(),_28.getFullYear()-1))); -d=_28.setFullYear(_28.getFullYear()-1); +_27.setDate(Math.min(_27.getDate(),_22(_27.getMonth(),_27.getFullYear()-1))); +d=_27.setFullYear(_27.getFullYear()-1); }else{ d-=604800000; } }else{ if(kc==Event.KEY_DOWN){ if(ev.ctrlKey||ev.shiftKey){ -_28.setDate(Math.min(_28.getDate(),_23(_28.getMonth(),_28.getFullYear()+1))); -d=_28.setFullYear(_28.getFullYear()+1); +_27.setDate(Math.min(_27.getDate(),_22(_27.getMonth(),_27.getFullYear()+1))); +d=_27.setFullYear(_27.getFullYear()+1); }else{ d+=7*24*61*60*1000; } @@ -266,22 +266,35 @@ var m=d.getMonth()+n; this.setMonth(m); return false; },onchange:function(){ +if(this.options.InputMode=="TextBox"){ this.control.value=this.formatDate(); +}else{ +var day=$(this.options.ID+"_day"); +var _34=$(this.options.ID+"_month"); +var _35=$(this.options.ID+"_year").options; +var _36=this.selectedDate; +day.selectedIndex=_36.getDate()-1; +_34.selectedIndex=_36.getMonth(); +var _37=_36.getFullYear(); +for(var i=0;i<_35.length;i++){ +_35[i].selected=_35[i].value.toInteger()==_37; +} +} },formatDate:function(){ return this.selectedDate?this.selectedDate.SimpleFormat(this.Format):""; -},newDate:function(_34){ -if(!_34){ -_34=new Date(); +},newDate:function(_38){ +if(!_38){ +_38=new Date(); } -if(isString(_34)||isNumber(_34)){ -_34=new Date(_34); +if(isString(_38)||isNumber(_38)){ +_38=new Date(_38); } -return new Date(_34.getFullYear(),_34.getMonth(),_34.getDate(),0,0,0); -},setSelectedDate:function(_35){ -if(_35==null){ +return new Date(_38.getFullYear(),_38.getMonth(),_38.getDate(),0,0,0); +},setSelectedDate:function(_39){ +if(_39==null){ return; } -this.selectedDate=this.newDate(_35); +this.selectedDate=this.newDate(_39); this.updateHeader(); this.update(); if(isFunction(this.onchange)){ @@ -291,13 +304,13 @@ this.onchange(); return this._calDiv; },getSelectedDate:function(){ return isNull(this.selectedDate)?null:this.newDate(this.selectedDate); -},setYear:function(_36){ +},setYear:function(_40){ var d=this.newDate(this.selectedDate); -d.setFullYear(_36); +d.setFullYear(_40); this.setSelectedDate(d); -},setMonth:function(_37){ +},setMonth:function(_41){ var d=this.newDate(this.selectedDate); -d.setMonth(_37); +d.setMonth(_41); this.setSelectedDate(d); },nextMonth:function(){ this.setMonth(this.selectedDate.getMonth()+1); @@ -306,7 +319,11 @@ this.setMonth(this.selectedDate.getMonth()-1); },show:function(){ if(!this.showing){ var pos=Position.cumulativeOffset(this.control); +if(this.options.InputMode=="TextBox"){ pos[1]+=this.control.offsetHeight; +}else{ +pos[1]+=$(this.options.ID+"_day").offsetHeight-1; +} this._calDiv.style.display="block"; this._calDiv.style.top=(pos[1]-1)+"px"; this._calDiv.style.left=pos[0]+"px"; @@ -314,30 +331,40 @@ this.ieHack(false); this.documentClickEvent=this.hideOnClick.bindEvent(this); this.documentKeyDownEvent=this.keyPressed.bindEvent(this); Event.observe(document.body,"click",this.documentClickEvent); -var _39=Date.SimpleParse(Form.Element.getValue(this.control),this.Format); -if(!isNull(_39)){ -this.selectedDate=_39; -this.setSelectedDate(_39); +var _43=this.getDateFromInput(); +if(!isNull(_43)){ +this.selectedDate=_43; +this.setSelectedDate(_43); } Event.observe(document,"keydown",this.documentKeyDownEvent); this.showing=true; } +},getDateFromInput:function(){ +if(this.options.InputMode=="TextBox"){ +return Date.SimpleParse($F(this.control),this.Format); +}else{ +var day=$F(this.options.ID+"_day"); +var _44=$F(this.options.ID+"_month"); +var _45=$F(this.options.ID+"_year"); +var _46=new Date(_45,_44,day,0,0,0); +return _46; +} },hideOnClick:function(ev){ if(!this.showing){ return; } var el=Event.element(ev); -var _40=false; +var _47=false; do{ -_40=_40||el.className==this.ClassName; -_40=_40||el==this.trigger; -_40=_40||el==this.control; -if(_40){ +_47=_47||el.className==this.ClassName; +_47=_47||el==this.trigger; +_47=_47||el==this.control; +if(_47){ break; } el=el.parentNode; }while(el); -if(!_40){ +if(!_47){ this.hide(); } },hide:function(){ @@ -351,61 +378,61 @@ Event.stopObserving(document.body,"click",this.documentClickEvent); Event.stopObserving(document,"keydown",this.documentKeyDownEvent); } },update:function(){ -var _41=this.selectedDate; -var _42=(this.newDate()).toISODate(); -var _43=_41.toISODate(); -var d1=new Date(_41.getFullYear(),_41.getMonth(),1); -var d2=new Date(_41.getFullYear(),_41.getMonth()+1,1); -var _46=Math.round((d2-d1)/(24*60*60*1000)); -var _47=(d1.getDay()-this.FirstDayOfWeek)%7; -if(_47<0){ -_47+=7; -} -var _48=0; -while(_48<_47){ -this.dateSlot[_48].value=-1; -this.dateSlot[_48].data.data=String.fromCharCode(160); -this.dateSlot[_48].data.parentNode.className="empty"; -_48++; -} -for(i=1;i<=_46;i++,_48++){ -var _49=this.dateSlot[_48]; -var _50=_49.data.parentNode; -_49.value=i; -_49.data.data=i; -_50.className="date"; -if(d1.toISODate()==_42){ -_50.className+=" today"; -} -if(d1.toISODate()==_43){ -_50.className+=" selected"; +var _48=this.selectedDate; +var _49=(this.newDate()).toISODate(); +var _50=_48.toISODate(); +var d1=new Date(_48.getFullYear(),_48.getMonth(),1); +var d2=new Date(_48.getFullYear(),_48.getMonth()+1,1); +var _53=Math.round((d2-d1)/(24*60*60*1000)); +var _54=(d1.getDay()-this.FirstDayOfWeek)%7; +if(_54<0){ +_54+=7; +} +var _55=0; +while(_55<_54){ +this.dateSlot[_55].value=-1; +this.dateSlot[_55].data.data=String.fromCharCode(160); +this.dateSlot[_55].data.parentNode.className="empty"; +_55++; +} +for(i=1;i<=_53;i++,_55++){ +var _56=this.dateSlot[_55]; +var _57=_56.data.parentNode; +_56.value=i; +_56.data.data=i; +_57.className="date"; +if(d1.toISODate()==_49){ +_57.className+=" today"; +} +if(d1.toISODate()==_50){ +_57.className+=" selected"; } d1=new Date(d1.getFullYear(),d1.getMonth(),d1.getDate()+1); } -var _51=_48; -while(_48<42){ -this.dateSlot[_48].value=-1; -this.dateSlot[_48].data.data=String.fromCharCode(160); -this.dateSlot[_48].data.parentNode.className="empty"; -++_48; +var _58=_55; +while(_55<42){ +this.dateSlot[_55].value=-1; +this.dateSlot[_55].data.data=String.fromCharCode(160); +this.dateSlot[_55].data.parentNode.className="empty"; +++_55; } },hover:function(ev){ Element.condClassName(Event.element(ev),"hover",ev.type=="mouseover"); },updateHeader:function(){ -var _52=this._monthSelect.options; +var _59=this._monthSelect.options; var m=this.selectedDate.getMonth(); -for(var i=0;i<_52.length;++i){ -_52[i].selected=false; -if(_52[i].value==m){ -_52[i].selected=true; -} -} -_52=this._yearSelect.options; -var _53=this.selectedDate.getFullYear(); -for(var i=0;i<_52.length;++i){ -_52[i].selected=false; -if(_52[i].value==_53){ -_52[i].selected=true; +for(var i=0;i<_59.length;++i){ +_59[i].selected=false; +if(_59[i].value==m){ +_59[i].selected=true; +} +} +_59=this._yearSelect.options; +var _60=this.selectedDate.getFullYear(); +for(var i=0;i<_59.length;++i){ +_59[i].selected=false; +if(_59[i].value==_60){ +_59[i].selected=true; } } }}; diff --git a/framework/Web/Javascripts/js/validator.js b/framework/Web/Javascripts/js/validator.js index f5ca2c8b..e1d0806a 100644 --- a/framework/Web/Javascripts/js/validator.js +++ b/framework/Web/Javascripts/js/validator.js @@ -243,20 +243,29 @@ var _55=_54||this.attr.refresh=="1"; var _56=this.getMessages(); if(_56.length<=0||!this.visible||!this.enabled){ if(_55){ +if(this.attr.display=="None"||this.attr.display=="Dynamic"){ Element.hide(this.div); +}else{ +this.div.style.visibility="hidden"; +} } return; } if(Prado.Validation.HasTargetGroup){ if(Prado.Validation.CurrentTargetGroup!=this.group){ if(_55){ +if(this.attr.display=="None"||this.attr.display=="Dynamic"){ Element.hide(this.div); +}else{ +this.div.style.visibility="hidden"; +} } return; } } if(this.attr.showsummary!="False"&&_55){ this.div.style.display="block"; +this.div.style.visibility="visible"; while(this.div.childNodes.length>0){ this.div.removeChild(this.div.lastChild); } diff --git a/framework/Web/Javascripts/prado/prado.js b/framework/Web/Javascripts/prado/prado.js index 2cb422e1..e63c2718 100644 --- a/framework/Web/Javascripts/prado/prado.js +++ b/framework/Web/Javascripts/prado/prado.js @@ -1,7 +1,17 @@ + var Prado = { Version: '3.0a', + /** + * Returns browser information. Example + * + * var browser = Prado.Browser(); + * alert(browser.ie); //should ouput true if IE, false otherwise + * + * @param ${parameter} + * @return ${return} + */ Browser : function() { var info = { Version : "1.0" }; diff --git a/framework/Web/Javascripts/prado/validation.js b/framework/Web/Javascripts/prado/validation.js index 29f1ce82..e7e45b2c 100644 --- a/framework/Web/Javascripts/prado/validation.js +++ b/framework/Web/Javascripts/prado/validation.js @@ -485,7 +485,12 @@ Prado.Validation.Summary.prototype = if(messages.length <= 0 || !this.visible || !this.enabled) { if(refresh) - Element.hide(this.div); + { + if(this.attr.display == "None" || this.attr.display == "Dynamic") + Element.hide(this.div); + else + this.div.style.visibility="hidden"; + } return; } @@ -494,8 +499,13 @@ Prado.Validation.Summary.prototype = if(Prado.Validation.CurrentTargetGroup != this.group) { if(refresh) - Element.hide(this.div); - return; + { + if(this.attr.display == "None" || this.attr.display == "Dynamic") + Element.hide(this.div); + else + this.div.style.visibility="hidden"; + } + return; } } @@ -503,6 +513,7 @@ Prado.Validation.Summary.prototype = { //Element.show(this.div); this.div.style.display = "block"; + this.div.style.visibility = "visible"; while(this.div.childNodes.length > 0) this.div.removeChild(this.div.lastChild); new Insertion.Bottom(this.div, this.formatSummary(messages)); diff --git a/framework/Web/Javascripts/prado/validators.js b/framework/Web/Javascripts/prado/validators.js index d1c45f32..5aa732b4 100644 --- a/framework/Web/Javascripts/prado/validators.js +++ b/framework/Web/Javascripts/prado/validators.js @@ -1,4 +1,8 @@ - +/** + * Validates that a given field has some input, + * @param ${parameter} + * @return ${return} + */ Prado.Validation.TRequiredFieldValidator=function(){ var inputType = this.control.getAttribute("type"); if(inputType == 'file'){ diff --git a/framework/Web/UI/THtmlWriter.php b/framework/Web/UI/THtmlWriter.php index 2f1f8c1a..613d58dc 100644 --- a/framework/Web/UI/THtmlWriter.php +++ b/framework/Web/UI/THtmlWriter.php @@ -175,11 +175,23 @@ class THtmlWriter extends TApplicationComponent implements ITextWriter $this->_attributes[$name]=isset(self::$_attrEncode[$name])?THttpUtility::htmlEncode($value):$value; } + public function removeAttribute($name) + { + if(isset($this->_attributes[$name])) + unset($this->_attributes[$name]); + } + public function addStyleAttribute($name,$value) { $this->_styles[$name]=isset(self::$_styleEncode[$name])?THttpUtility::htmlEncode($value):$value; } + public function removeStyleAttribute($name) + { + if(isset($this->_styles[$name])) + unset($this->_styles[$name]); + } + public function flush() { $this->_writer->flush(); diff --git a/framework/Web/UI/WebControls/TCompareValidator.php b/framework/Web/UI/WebControls/TCompareValidator.php index 39086b48..853cff17 100644 --- a/framework/Web/UI/WebControls/TCompareValidator.php +++ b/framework/Web/UI/WebControls/TCompareValidator.php @@ -208,7 +208,7 @@ class TCompareValidator extends TBaseValidator $dateFormat = $this->getDateFormat(); if (strlen($dateFormat)) { - $formatter = Prado::createComponent('System.Data.TDateTimeSimpleFormatter', $dateFormat); + $formatter = Prado::createComponent('System.Data.TSimpleDateFormatter', $dateFormat); return array($formatter->parse($value1), $formatter->parse($value2)); } else diff --git a/framework/Web/UI/WebControls/TDatePicker.php b/framework/Web/UI/WebControls/TDatePicker.php index a70e25b3..f563e36e 100644 --- a/framework/Web/UI/WebControls/TDatePicker.php +++ b/framework/Web/UI/WebControls/TDatePicker.php @@ -49,6 +49,11 @@ * for the date picker panel. CalendarStyle property sets the packages * styles available. E.g. default. * + * The InputMode property can be set to "TextBox" or "DropDownList" with + * default as "TextBox". + * In DropDownList mode, in addition to the popup date picker, three + * drop down list (day, month and year) are presented to select the date . + * * @author Wei Zhuo * @version $Revision: $ $Date: $ * @package System.Web.UI.WebControls @@ -108,6 +113,16 @@ class TDatePicker extends TTextBox $this->setViewState('Culture', $value, ''); } + public function setInputMode($value) + { + $this->setViewState('InputMode', TPropertyValue::ensureEnum($value, 'TextBox', 'DropDownList'), 'TextBox'); + } + + public function getInputMode() + { + return $this->getViewState('InputMode', 'TextBox'); + } + /** * @param string calendar UI mode, "Basic", "Button" or "ImageButton" */ @@ -220,12 +235,105 @@ class TDatePicker extends TTextBox return $this->getViewState('UpToYear', intval(@date('Y'))+10); } + /** + * @return integer current selected date from the date picker as timestamp. + */ + public function getDate() + { + $date = $this->getDateFromText(); + return $date[0]; + } + + /** + * Sets the date for the date picker using timestamp. + * @param integer time stamp for the date picker + */ + public function setDate($value) + { + $date = TPropertyValue::ensureInteger($value); + $formatter = Prado::createComponent('System.Data.TSimpleDateFormatter', + $this->getDateFormat()); + $this->setText($formatter->format($date)); + } + + /** + * Publish the date picker Css asset files. + */ + public function onPreRender($param) + { + parent::onPreRender($param); + $this->publishCalendarStyle(); + } + + /** + * Renders body content. + * This method overrides parent implementation by adding + * additional date picker button if Mode is "Button" or "ImageButton". + * @param THtmlWriter writer + */ + public function render($writer) + { + if($this->getInputMode() == 'TextBox') + parent::render($writer); + else + $this->renderDropDownListCalendar($writer); + + if($this->getShowCalendar()) + { + switch ($this->getMode()) + { + case 'Button': $this->renderButtonDatePicker($writer); break; + case 'ImageButton' : $this->renderImageButtonDatePicker($writer); break; + } + } + } + + /** + * Loads user input data. Override parent implementation, when InputMode + * is DropDownList call getDateFromPostData to get date data. + * This method is primarly used by framework developers. + * @param string the key that can be used to retrieve data from the input data collection + * @param array the input data collection + * @return boolean whether the data of the component has been changed + */ public function loadPostData($key,$values) + { + if($this->getInputMode() == "TextBox") + return parent::loadPostData($key, $values); + $value = $this->getDateFromPostData($key, $values); + if(!$this->getReadOnly() && $this->getText()!==$value) + { + $this->setText($value); + return true; + } + else + return false; + } + + /** + * Loads date from drop down list data. + * @param string the key that can be used to retrieve data from the input data collection + * @param array the input data collection + * @return array the date selected + */ + protected function getDateFromPostData($key, $values) + { + $day = $values[$key.'$day']; + $month = $values[$key.'$month']; + $year = $values[$key.'$year']; + $date = @mktime(0, 0, 0, $month+1, $day, $year); + $formatter = Prado::createComponent('System.Data.TSimpleDateFormatter', + $this->getDateFormat()); + return $formatter->format($date); + } + /** * Get javascript date picker options. * @return array date picker client-side options */ protected function getDatePickerOptions() { + $options['ID'] = $this->getClientID(); + $options['InputMode'] = $this->getInputMode(); $options['Format'] = $this->getDateFormat(); $options['FirstDayOfWeek'] = $this->getFirstDayOfWeek(); if(($cssClass=$this->getCssClass())!=='') @@ -245,45 +353,151 @@ class TDatePicker extends TTextBox */ protected function getCulturalOptions() { - $app = $this->getApplication()->getGlobalization(); - $culture = $this->getCulture() == '' ? $app->getCulture() : $this->getCulture(); - if($culture == 'en') return array(); + if($this->getCurrentCulture() == 'en') + return array(); - //expensive operations - Prado::using('System.I18N.core.DateTimeFormatInfo'); - $info = Prado::createComponent('System.I18N.core.CultureInfo', $culture); - $date = $info->getDateTimeFormat(); + $date = $this->getLocalizedCalendarInfo(); $options['MonthNames'] = TJavaScript::encode($date->getMonthNames(),false); $options['ShortWeekDayNames'] = TJavaScript::encode($date->getAbbreviatedDayNames(),false); + return $options; } /** - * Publish the date picker Css asset files. + * @return string the current culture, falls back to application if culture is not set. */ - public function onPreRender($param) + protected function getCurrentCulture() { - parent::onPreRender($param); - $this->publishCalendarStyle(); + $app = $this->getApplication()->getGlobalization(); + return $this->getCulture() == '' ? $app->getCulture() : $this->getCulture(); } /** - * Renders body content. - * This method overrides parent implementation by adding - * additional date picker button if Mode is "Button" or "ImageButton". - * @param THtmlWriter writer + * @return DateTimeFormatInfo date time format information for the current culture. */ - public function render($writer) + protected function getLocalizedCalendarInfo() { - parent::render($writer); - switch ($this->getMode()) - { - case 'Button': $this->renderButtonDatePicker($writer); break; - case 'ImageButton' : $this->renderImageButtonDatePicker($writer); break; + //expensive operations + $culture = $this->getCurrentCulture(); + Prado::using('System.I18N.core.DateTimeFormatInfo'); + $info = Prado::createComponent('System.I18N.core.CultureInfo', $culture); + return $info->getDateTimeFormat(); + } + + /** + * Renders the drop down list date picker. + */ + protected function renderDropDownListCalendar($writer) + { + if($this->getMode() == 'Basic') + $this->setMode('ImageButton'); + parent::addAttributesToRender($writer); + $writer->removeAttribute('name'); + $writer->removeAttribute('type'); + $writer->addAttribute('id', $this->getClientID()); + + if(strlen($class = $this->getCssClass()) > 0) + $writer->addAttribute('class', $class); + $writer->renderBeginTag('span'); + + $date = $this->getDateFromText(); + + //renders the 3 drop down lists + $this->renderCalendarDayOptions($writer,$date['mday']); + $this->renderCalendarMonthOptions($writer,$date['mon']-1); + $this->renderCalendarYearOptions($writer,$date['year']); + + //render a hidden input field + $writer->addAttribute('name', $this->getUniqueID()); + $writer->addAttribute('type', 'hidden'); + $writer->addAttribute('value', $this->getText()); + $writer->renderBeginTag('input'); + + $this->registerCalendarClientScript(); + $writer->renderEndTag(); + } + + /** + * Gets the date from the text input using TSimpleDateFormatter + * @return array current selected date + */ + protected function getDateFromText() + { + $formatter = Prado::createComponent('System.Data.TSimpleDateFormatter', + $this->getDateFormat()); + return $formatter->parse($this->getText()); + } + /** + * Renders a drop down lists. + * @param THtmlWriter the writer used for the rendering purpose + * @param array list of selection options + * @param mixed selected key. + */ + private function renderDropDownListOptions($writer,$options,$selected=null) + { + foreach($options as $k => $v) + { + $writer->addAttribute('value', $k); + if($k == $selected) + $writer->addAttribute('selected', 'selected'); + $writer->renderBeginTag('option'); + $writer->write($v); + $writer->renderEndTag(); } } + /** + * Renders the day drop down list options. + * @param THtmlWriter the writer used for the rendering purpose + * @param mixed selected day. + */ + protected function renderCalendarDayOptions($writer, $selected=null) + { + $days = array(); for($i=1;$i<=31;$i++) $days[$i] = $i; + $writer->addAttribute('id', $this->getClientID().'_day'); + $writer->addAttribute('name', $this->getUniqueID().'$day'); + $writer->addAttribute('class', 'datepicker_day_options'); + $writer->renderBeginTag('select'); + $this->renderDropDownListOptions($writer, $days, $selected); + $writer->renderEndTag(); + } + + /** + * Renders the month drop down list options. + * @param THtmlWriter the writer used for the rendering purpose + * @param mixed selected month. + */ + protected function renderCalendarMonthOptions($writer, $selected=null) + { + $info = $this->getLocalizedCalendarInfo(); + $writer->addAttribute('id', $this->getClientID().'_month'); + $writer->addAttribute('name', $this->getUniqueID().'$month'); + $writer->addAttribute('class', 'datepicker_month_options'); + $writer->renderBeginTag('select'); + $this->renderDropDownListOptions($writer, + $info->getMonthNames(), $selected); + $writer->renderEndTag(); + } + + /** + * Renders the year drop down list options. + * @param THtmlWriter the writer used for the rendering purpose + * @param mixed selected year. + */ + protected function renderCalendarYearOptions($writer, $selected=null) + { + $years = array(); + for($i = $this->getFromYear(); $i <= $this->getUpToYear(); $i++) + $years[$i] = $i; + $writer->addAttribute('id', $this->getClientID().'_year'); + $writer->addAttribute('name', $this->getUniqueID().'$year'); + $writer->renderBeginTag('select'); + $writer->addAttribute('class', 'datepicker_year_options'); + $this->renderDropDownListOptions($writer, $years, $selected); + $writer->renderEndTag(); + } + /** * Gets the ID for the date picker trigger button. * @return string unique button ID @@ -354,23 +568,31 @@ class TDatePicker extends TTextBox } /** - * Registers the javascript code to initialize the date picker. - * Must use "Event.OnLoad" to initialize the date picker when the - * full page is loaded, otherwise IE will throw an error. + * Add the client id to the input textbox, and register the client scripts. * @param THtmlWriter writer */ protected function addAttributesToRender($writer) { parent::addAttributesToRender($writer); $writer->addAttribute('id',$this->getClientID()); + $this->registerCalendarClientScript(); + } + + + /** + * Registers the javascript code to initialize the date picker. + * Must use "Event.OnLoad" to initialize the date picker when the + * full page is loaded, otherwise IE will throw an error. + */ + protected function registerCalendarClientScript() + { if($this->getShowCalendar()) { $scripts = $this->getPage()->getClientScript(); $scripts->registerPradoScript("datepicker"); $options = TJavaScript::encode($this->getDatePickerOptions()); - $id = $this->getClientID(); - $code = "Event.OnLoad(function(){ new Prado.WebUI.TDatePicker('$id', $options); });"; - $scripts->registerEndScript("prado:$id", $code); + $code = "Event.OnLoad(function(){ new Prado.WebUI.TDatePicker($options); });"; + $scripts->registerEndScript("prado:".$this->getClientID(), $code); } } } diff --git a/framework/Web/UI/WebControls/TValidationSummary.php b/framework/Web/UI/WebControls/TValidationSummary.php index e7115c99..61a4415c 100644 --- a/framework/Web/UI/WebControls/TValidationSummary.php +++ b/framework/Web/UI/WebControls/TValidationSummary.php @@ -36,6 +36,25 @@ */ class TValidationSummary extends TWebControl { + /** + * @return string the display behavior (None, Static, Dynamic) of the error message in a validation summary component. + */ + public function getDisplay() + { + return $this->getViewState('Display','Static'); + } + + /** + * Sets the display behavior (None, Static, Dynamic) of the error message in a validation summary component. + * @param string the display behavior (None, Static, Dynamic) + */ + public function setDisplay($value) + { + if($value!='None' && $value!='Dynamic') + $value='Static'; + $this->setViewState('Display',$value,'Static'); + } + /** * @return string the header text displayed at the top of the summary */ @@ -170,6 +189,15 @@ class TValidationSummary extends TWebControl protected function addAttributesToRender($writer) { + $display=$this->getDisplay(); + $visible=$this->getEnabled(true) && count($this->getErrorMessages()) > 0; + if(!$visible) + { + if($display==='None' || $display==='Dynamic') + $writer->addStyleAttribute('display','none'); + else + $writer->addStyleAttribute('visibility','hidden'); + } $writer->addAttribute('id',$this->getClientID()); parent::addAttributesToRender($writer); } @@ -205,6 +233,7 @@ class TValidationSummary extends TWebControl $options['refresh'] = $this->getAutoUpdate(); $options['validationgroup'] = $this->getValidationGroup(); + $options['display'] = $this->getDisplay(); return $options; } diff --git a/framework/Web/UI/WebControls/TValueTypeValidator.php b/framework/Web/UI/WebControls/TValueTypeValidator.php index f0f61d52..ca4a01ca 100644 --- a/framework/Web/UI/WebControls/TValueTypeValidator.php +++ b/framework/Web/UI/WebControls/TValueTypeValidator.php @@ -65,7 +65,7 @@ class TValueTypeValidator $dateFormat = $this->getDateFormat(); if(strlen($dateFormat)) { - $formatter = Prado::createComponent('System.Data.TDateTimeSimpleFormatter',$dateFormat); + $formatter = Prado::createComponent('System.Data.TSimpleDateFormatter',$dateFormat); return $formatter->isValidDate($value); } else -- cgit v1.2.3