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. --- .gitattributes | 2 +- .../quickstart/protected/pages/Advanced/I18N.page | 4 + .../Controls/Samples/TCompareValidator/Home.page | 10 +- .../Samples/TEmailAddressValidator/Home.page | 8 +- .../Samples/TRegularExpressionValidator/Home.page | 21 +- .../Controls/Samples/TValidationSummary/Home.page | 89 +++++- framework/Data/TDateTimeSimpleFormatter.php | 304 ------------------- framework/Data/TSimpleDateFormatter.php | 310 ++++++++++++++++++++ .../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 +- .../protected/pages/UI/DatePicker.page | 3 + .../protected/pages/UI/testHtmlArea.page | 2 - 26 files changed, 1135 insertions(+), 570 deletions(-) delete mode 100644 framework/Data/TDateTimeSimpleFormatter.php create mode 100644 framework/Data/TSimpleDateFormatter.php diff --git a/.gitattributes b/.gitattributes index 576c3796..5a91ab0c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -268,8 +268,8 @@ framework/Collections/TPagedDataSource.php -text framework/Data/TAPCCache.php -text framework/Data/TCache.php -text framework/Data/TDataFieldAccessor.php -text -framework/Data/TDateTimeSimpleFormatter.php -text framework/Data/TMemCache.php -text +framework/Data/TSimpleDateFormatter.php -text framework/Data/TSqliteCache.php -text framework/Data/TTarFileExtractor.php -text framework/Data/TXmlDocument.php -text diff --git a/demos/quickstart/protected/pages/Advanced/I18N.page b/demos/quickstart/protected/pages/Advanced/I18N.page index 1bb5a9a0..db97c25c 100644 --- a/demos/quickstart/protected/pages/Advanced/I18N.page +++ b/demos/quickstart/protected/pages/Advanced/I18N.page @@ -134,6 +134,9 @@ $message = localize("There are {num_users} users online.", array('num_users'=>$n

Where the second parameter in localize takes an associative array with the key as the substitution to find in the text and replaced it with the associated value. The localize function does not solve the problem of localizing languages that have plural forms, the solution is to use TChoiceFormat.

+

The following sample demonstrates the basics of localization in Prado.

+ +

I18N Components

TTranslate

@@ -225,4 +228,5 @@ is "One Apple". If the Value was "2", then it will show "Two Apples".Any non-empty combinations of the delimiters of square and round brackets are acceptable. The string chosen for display depends on the Value property. The Value is evaluated for each set until the Value is found to belong to a particular set.

+ \ No newline at end of file diff --git a/demos/quickstart/protected/pages/Controls/Samples/TCompareValidator/Home.page b/demos/quickstart/protected/pages/Controls/Samples/TCompareValidator/Home.page index 7abed86a..ab99436a 100644 --- a/demos/quickstart/protected/pages/Controls/Samples/TCompareValidator/Home.page +++ b/demos/quickstart/protected/pages/Controls/Samples/TCompareValidator/Home.page @@ -1,6 +1,8 @@

TCompareValidator Samples

+

Note:TCompareValidator will start +to validate only if both inputs are not empty.

@@ -9,8 +11,8 @@ Compare validator with default settings:
- - + + - - + +

TEmailAddressValidator Samples

+

Note:TEmailAddressValidator will start +to validate only if the input is not empty.

@@ -9,7 +11,7 @@ Email address validator with default settings:
- + - + - +

TRegularExpressionValidator Samples

- +

Note:TRegularExpressionValidator will start +to validate only if the input is not empty.

@@ -9,12 +10,12 @@ Regular expression validator with default settings: @@ -24,13 +25,13 @@ Regular expression validator with default settings: Regular expression validator with client-side validation disabled: @@ -40,13 +41,13 @@ Regular expression validator with client-side validation disabled: Regular expression validator with focus-on-error enabled and dynamic display: diff --git a/demos/quickstart/protected/pages/Controls/Samples/TValidationSummary/Home.page b/demos/quickstart/protected/pages/Controls/Samples/TValidationSummary/Home.page index 75ca9c52..5ac143ae 100644 --- a/demos/quickstart/protected/pages/Controls/Samples/TValidationSummary/Home.page +++ b/demos/quickstart/protected/pages/Controls/Samples/TValidationSummary/Home.page @@ -2,24 +2,83 @@

TValidationSummary Samples

-
- + + RegularExpression="\d+" + Text="Only digits are allowed." />
- + + RegularExpression="\d+" + Text="Only digits are allowed." />
- + + RegularExpression="\d+" + Text="Only digits are allowed." />
- - - - - + ErrorMessage="a password is required." /> + +
+ +
+ + +
+ +
+ + + + +
+ Sign In + +
+ Login Name: + + + +
+ +
+ Password: + + +
+ + +
+ +
-
-Required field validator with default settings: - - - + +
+ Create New Account + +
+ Username: + + +
+
+ Password + +
- -
+ \ No newline at end of file diff --git a/framework/Data/TDateTimeSimpleFormatter.php b/framework/Data/TDateTimeSimpleFormatter.php deleted file mode 100644 index ac5fb685..00000000 --- a/framework/Data/TDateTimeSimpleFormatter.php +++ /dev/null @@ -1,304 +0,0 @@ - - * @link http://www.pradosoft.com/ - * @copyright Copyright © 2006 PradoSoft - * @license http://www.pradosoft.com/license/ - * @version $Revision: $ $Date: $ - * @package System.Data - */ - -/** - * TDateTimeSimpleFormatter class. - * - * Formats and parses dates using the SimpleDateFormat pattern. - * This pattern is compatible with the I18N and java's SimpleDateFormatter. - * - * Pattern | Description - * ---------------------------------------------------- - * d | Day of month 1 to 31, no padding - * dd | Day of monath 01 to 31, zero leading - * M | Month digit 1 to 12, no padding - * MM | Month digit 01 to 12, zero leading - * yy | 2 year digit, e.g., 96, 05 - * yyyy | 4 year digit, e.g., 2005 - * ---------------------------------------------------- - * - * - * Usage example, to format a date - * - * $formatter = new TDateTimeSimpleFormatter("dd/MM/yyy"); - * echo $formatter->format(time()); - * - * - * To parse the date string into a date timestamp. - * - * $formatter = new TDateTimeSimpleFormatter("d-M-yyy"); - * echo $formatter->parse("24-6-2005"); - * - * - * @author Wei Zhuo - * @version $Revision: $ $Date: $ - * @package System.Data - * @since 3.0 - */ -class TDateTimeSimpleFormatter -{ - /** - * Formatting pattern. - * @var string - */ - private $pattern; - - /** - * Charset, default is 'UTF-8' - * @var string - */ - private $charset = 'UTF-8'; - - /** - * Constructor, create a new date time formatter. - * @param string formatting pattern. - * @param string pattern and value charset - */ - public function __construct($pattern, $charset='UTF-8') - { - $this->setPattern($pattern); - $this->setCharset($charset); - } - - /** - * @return string formatting pattern. - */ - public function getPattern() - { - return $this->pattern; - } - - /** - * @param string formatting pattern. - */ - public function setPattern($pattern) - { - $this->pattern = $pattern; - } - - /** - * @return string formatting charset. - */ - public function getCharset() - { - return $this->charset; - } - - /** - * @param string formatting charset. - */ - public function setCharset($charset) - { - $this->charset = $charset; - } - - /** - * Format the date according to the pattern. - * @param string|int the date to format, either integer or a string readable by strtotime. - * @return string formatted date. - */ - public function format($value) - { - $date = $this->getDate($value); - $bits['yyyy'] = $date['year']; - $bits['yy'] = substr("{$date['year']}", -2); - - $bits['MM'] = str_pad("{$date['mon']}", 2, '0', STR_PAD_LEFT); - $bits['M'] = $date['mon']; - - $bits['dd'] = str_pad("{$date['mday']}", 2, '0', STR_PAD_LEFT); - $bits['d'] = $date['mday']; - - return str_replace(array_keys($bits), $bits, $this->pattern); - } - - /** - * Gets the time stamp from string or integer. - * @param string|int date to parse - * @return int parsed date time stamp - */ - private function getDate($value) - { - if(is_int($value)) - return getdate($value); - $date = @strtotime($value); - if($date < 0) - throw new TInvalidDataValueException('invalid_date', $value); - return getdate($date); - } - - /** - * @return boolean true if the given value matches with the date pattern. - */ - public function isValidDate($value) - { - return !is_null($this->parse($value, false)); - } - - /** - * Parse the string according to the pattern. - * @param string date string to parse - * @return int date time stamp - * @throws TInvalidDataValueException if date string is malformed. - */ - public function parse($value,$defaulToCurrentTime=true) - { - if(!is_string($value)) - throw new TInvalidDataValueException('date_to_parse_must_be_string', $value); - if(empty($this->pattern)) return time(); - - $pattern = $this->pattern; - - $i_val = 0; - $i_format = 0; - $pattern_length = $this->length($pattern); - $c = ''; - $token=''; - $x=null; $y=null; - - $date = $this->getDate(time()); - if($defaulToCurrentTime) - { - $year = "{$date['year']}"; - $month = $date['mon']; - $day = $date['mday']; - } - else - { - $year = null; - $month = null; - $day = null; - } - - while ($i_format < $pattern_length) - { - $c = $this->charAt($pattern,$i_format); - $token=''; - while ($this->charEqual($pattern, $i_format, $c) - && ($i_format < $pattern_length)) - { - $token .= $this->charAt($pattern, $i_format++); - } - - if ($token=='yyyy' || $token=='yy' || $token=='y') - { - if ($token=='yyyy') { $x=4;$y=4; } - if ($token=='yy') { $x=2;$y=2; } - if ($token=='y') { $x=2;$y=4; } - $year = $this->getInteger($value,$i_val,$x,$y); - if(is_null($year)) - throw new TInvalidDataValueException('Invalid year', $value); - $i_val += strlen($year); - if(strlen($year) == 2) - { - $iYear = intval($year); - if($iYear > 70) - $year = $iYear + 1900; - else - $year = $iYear + 2000; - } - $year = intval($year); - } - elseif($token=='MM' || $token=='M') - { - $month=$this->getInteger($value,$i_val, - $this->length($token),2); - $iMonth = intval($month); - if(is_null($month) || $iMonth < 1 || $iMonth > 12 ) - throw new TInvalidDataValueException('Invalid month', $value); - $i_val += strlen($month); - $month = $iMonth; - } - elseif ($token=='dd' || $token=='d') - { - $day = $this->getInteger($value,$i_val, - $this->length($token), 2); - $iDay = intval($day); - if(is_null($day) || $iDay < 1 || $iDay >31) - throw new TInvalidDataValueException('Invalid day', $value); - $i_val += strlen($day); - $day = $iDay; - } - else - { - if($this->substring($value, $i_val, $this->length($token)) != $token) - throw new TInvalidDataValueException("Subpattern '{$this->pattern}' mismatch", $value); - else - $i_val += $this->length($token); - } - } - if ($i_val != $this->length($value)) - throw new TInvalidDataValueException("Pattern '{$this->pattern}' mismatch", $value); - - if(!$defaultToCurrentTime && (is_null($month) || is_null($day) || is_null($year))) - return null; - else - return mktime(0, 0, 0, $month, $day, $year); - } - - /** - * Calculate the length of a string, may be consider iconv_strlen? - */ - private function length($string) - { - //use iconv_strlen or just strlen? - return strlen($string); - } - - /** - * Get the char at a position. - */ - private function charAt($string, $pos) - { - return $this->substring($string, $pos, 1); - } - - /** - * Gets a portion of a string, uses iconv_substr. - */ - private function substring($string, $start, $length) - { - return iconv_substr($string, $start, $length); - } - - /** - * Returns true if char at position equals a particular char. - */ - private function charEqual($string, $pos, $char) - { - return $this->charAt($string, $pos) == $char; - } - - /** - * Gets integer from part of a string, allows integers of any length. - * @param string string to retrieve the integer from. - * @param int starting position - * @param int minimum integer length - * @param int maximum integer length - * @return string integer portition of the string, null otherwise - */ - private function getInteger($str,$i,$minlength,$maxlength) - { - //match for digits backwards - for ($x = $maxlength; $x >= $minlength; $x--) - { - $token= $this->substring($str, $i,$x); - if ($this->length($token) < $minlength) - return null; - if (preg_match('/^\d+$/', $token)) - return $token; - } - return null; - } -} - -?> \ No newline at end of file diff --git a/framework/Data/TSimpleDateFormatter.php b/framework/Data/TSimpleDateFormatter.php new file mode 100644 index 00000000..d2f78b37 --- /dev/null +++ b/framework/Data/TSimpleDateFormatter.php @@ -0,0 +1,310 @@ + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2006 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ + * @package System.Data + */ + +/** + * TSimpleDateFormatter class. + * + * Formats and parses dates using the SimpleDateFormat pattern. + * This pattern is compatible with the I18N and java's SimpleDateFormatter. + * + * Pattern | Description + * ---------------------------------------------------- + * d | Day of month 1 to 31, no padding + * dd | Day of monath 01 to 31, zero leading + * M | Month digit 1 to 12, no padding + * MM | Month digit 01 to 12, zero leading + * yy | 2 year digit, e.g., 96, 05 + * yyyy | 4 year digit, e.g., 2005 + * ---------------------------------------------------- + * + * + * Usage example, to format a date + * + * $formatter = new TSimpleDateFormatter("dd/MM/yyy"); + * echo $formatter->format(time()); + * + * + * To parse the date string into a date timestamp. + * + * $formatter = new TSimpleDateFormatter("d-M-yyy"); + * echo $formatter->parse("24-6-2005"); + * + * + * @author Wei Zhuo + * @version $Revision: $ $Date: $ + * @package System.Data + * @since 3.0 + */ +class TSimpleDateFormatter +{ + /** + * Formatting pattern. + * @var string + */ + private $pattern; + + /** + * Charset, default is 'UTF-8' + * @var string + */ + private $charset = 'UTF-8'; + + /** + * Constructor, create a new date time formatter. + * @param string formatting pattern. + * @param string pattern and value charset + */ + public function __construct($pattern, $charset='UTF-8') + { + $this->setPattern($pattern); + $this->setCharset($charset); + } + + /** + * @return string formatting pattern. + */ + public function getPattern() + { + return $this->pattern; + } + + /** + * @param string formatting pattern. + */ + public function setPattern($pattern) + { + $this->pattern = $pattern; + } + + /** + * @return string formatting charset. + */ + public function getCharset() + { + return $this->charset; + } + + /** + * @param string formatting charset. + */ + public function setCharset($charset) + { + $this->charset = $charset; + } + + /** + * Format the date according to the pattern. + * @param string|int the date to format, either integer or a string readable by strtotime. + * @return string formatted date. + */ + public function format($value) + { + $date = $this->getDate($value); + $bits['yyyy'] = $date['year']; + $bits['yy'] = substr("{$date['year']}", -2); + + $bits['MM'] = str_pad("{$date['mon']}", 2, '0', STR_PAD_LEFT); + $bits['M'] = $date['mon']; + + $bits['dd'] = str_pad("{$date['mday']}", 2, '0', STR_PAD_LEFT); + $bits['d'] = $date['mday']; + + return str_replace(array_keys($bits), $bits, $this->pattern); + } + + /** + * Gets the time stamp from string or integer. + * @param string|int date to parse + * @return int parsed date time stamp + */ + private function getDate($value) + { + if(is_int($value)) + return @getdate($value); + $date = @strtotime($value); + if($date < 0) + throw new TInvalidDataValueException('invalid_date', $value); + return @getdate($date); + } + + /** + * @return boolean true if the given value matches with the date pattern. + */ + public function isValidDate($value) + { + return !is_null($this->parse($value, false)); + } + + /** + * Parse the string according to the pattern. + * @param string date string to parse + * @return int date time stamp + * @throws TInvalidDataValueException if date string is malformed. + */ + public function parse($value,$defaultToCurrentTime=true) + { + if(!is_string($value)) + throw new TInvalidDataValueException('date_to_parse_must_be_string', $value); + + if(empty($this->pattern)) return time(); + + $date = $this->getDate(time()); + + if($this->length(trim($value)) < 1) + return $defaultToCurrentTime ? $date : null; + + $pattern = $this->pattern; + + $i_val = 0; + $i_format = 0; + $pattern_length = $this->length($pattern); + $c = ''; + $token=''; + $x=null; $y=null; + + + if($defaultToCurrentTime) + { + $year = "{$date['year']}"; + $month = $date['mon']; + $day = $date['mday']; + } + else + { + $year = null; + $month = null; + $day = null; + } + + while ($i_format < $pattern_length) + { + $c = $this->charAt($pattern,$i_format); + $token=''; + while ($this->charEqual($pattern, $i_format, $c) + && ($i_format < $pattern_length)) + { + $token .= $this->charAt($pattern, $i_format++); + } + + if ($token=='yyyy' || $token=='yy' || $token=='y') + { + if ($token=='yyyy') { $x=4;$y=4; } + if ($token=='yy') { $x=2;$y=2; } + if ($token=='y') { $x=2;$y=4; } + $year = $this->getInteger($value,$i_val,$x,$y); + if(is_null($year)) + throw new TInvalidDataValueException('Invalid year', $value); + $i_val += strlen($year); + if(strlen($year) == 2) + { + $iYear = intval($year); + if($iYear > 70) + $year = $iYear + 1900; + else + $year = $iYear + 2000; + } + $year = intval($year); + } + elseif($token=='MM' || $token=='M') + { + $month=$this->getInteger($value,$i_val, + $this->length($token),2); + $iMonth = intval($month); + if(is_null($month) || $iMonth < 1 || $iMonth > 12 ) + throw new TInvalidDataValueException('Invalid month', $value); + $i_val += strlen($month); + $month = $iMonth; + } + elseif ($token=='dd' || $token=='d') + { + $day = $this->getInteger($value,$i_val, + $this->length($token), 2); + $iDay = intval($day); + if(is_null($day) || $iDay < 1 || $iDay >31) + throw new TInvalidDataValueException('Invalid day', $value); + $i_val += strlen($day); + $day = $iDay; + } + else + { + if($this->substring($value, $i_val, $this->length($token)) != $token) + throw new TInvalidDataValueException("Subpattern '{$this->pattern}' mismatch", $value); + else + $i_val += $this->length($token); + } + } + if ($i_val != $this->length($value)) + throw new TInvalidDataValueException("Pattern '{$this->pattern}' mismatch", $value); + + if(!$defaultToCurrentTime && (is_null($month) || is_null($day) || is_null($year))) + return null; + else + return $this->getDate(@mktime(0, 0, 0, $month, $day, $year)); + } + + /** + * Calculate the length of a string, may be consider iconv_strlen? + */ + private function length($string) + { + //use iconv_strlen or just strlen? + return strlen($string); + } + + /** + * Get the char at a position. + */ + private function charAt($string, $pos) + { + return $this->substring($string, $pos, 1); + } + + /** + * Gets a portion of a string, uses iconv_substr. + */ + private function substring($string, $start, $length) + { + return iconv_substr($string, $start, $length); + } + + /** + * Returns true if char at position equals a particular char. + */ + private function charEqual($string, $pos, $char) + { + return $this->charAt($string, $pos) == $char; + } + + /** + * Gets integer from part of a string, allows integers of any length. + * @param string string to retrieve the integer from. + * @param int starting position + * @param int minimum integer length + * @param int maximum integer length + * @return string integer portition of the string, null otherwise + */ + private function getInteger($str,$i,$minlength,$maxlength) + { + //match for digits backwards + for ($x = $maxlength; $x >= $minlength; $x--) + { + $token= $this->substring($str, $i,$x); + if ($this->length($token) < $minlength) + return null; + if (preg_match('/^\d+$/', $token)) + return $token; + } + return null; + } +} + +?> \ No newline at end of file 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 diff --git a/tests/FunctionalTests/protected/pages/UI/DatePicker.page b/tests/FunctionalTests/protected/pages/UI/DatePicker.page index 5c826a85..09272d15 100644 --- a/tests/FunctionalTests/protected/pages/UI/DatePicker.page +++ b/tests/FunctionalTests/protected/pages/UI/DatePicker.page @@ -6,6 +6,9 @@ as
dv
as
d
+ + +<%= $this->Page->Picker1->Text %> as
d
asd
diff --git a/tests/FunctionalTests/protected/pages/UI/testHtmlArea.page b/tests/FunctionalTests/protected/pages/UI/testHtmlArea.page index fe86d493..5e9665dd 100644 --- a/tests/FunctionalTests/protected/pages/UI/testHtmlArea.page +++ b/tests/FunctionalTests/protected/pages/UI/testHtmlArea.page @@ -1,6 +1,5 @@ <%@ Application.Globalization.Charset="GB2312" %> - @@ -8,5 +7,4 @@ language: "zh_CN" - \ No newline at end of file -- cgit v1.2.3