summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwei <>2006-02-18 23:41:16 +0000
committerwei <>2006-02-18 23:41:16 +0000
commit270282e3a26b21184a2051995cb5b9a2755b823d (patch)
tree761d82ad761996f329d63acc770fc5a0bce9d5a2
parentf1cc3c880b564362e7f00b18326e116884879231 (diff)
Update some javascript code.
-rw-r--r--.gitattributes2
-rw-r--r--demos/quickstart/protected/pages/Advanced/I18N.page4
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TCompareValidator/Home.page10
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TEmailAddressValidator/Home.page8
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TRegularExpressionValidator/Home.page21
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TValidationSummary/Home.page89
-rw-r--r--framework/Data/TSimpleDateFormatter.php (renamed from framework/Data/TDateTimeSimpleFormatter.php)28
-rw-r--r--framework/Web/Javascripts/colorpicker/colorpicker.js4
-rw-r--r--framework/Web/Javascripts/datepicker/datepicker.js57
-rw-r--r--framework/Web/Javascripts/extended/event.js137
-rw-r--r--framework/Web/Javascripts/extended/string.js60
-rw-r--r--framework/Web/Javascripts/extended/util.js4
-rw-r--r--framework/Web/Javascripts/js/colorpicker.js4
-rw-r--r--framework/Web/Javascripts/js/datepicker.js323
-rw-r--r--framework/Web/Javascripts/js/validator.js9
-rw-r--r--framework/Web/Javascripts/prado/prado.js10
-rw-r--r--framework/Web/Javascripts/prado/validation.js17
-rw-r--r--framework/Web/Javascripts/prado/validators.js6
-rw-r--r--framework/Web/UI/THtmlWriter.php12
-rw-r--r--framework/Web/UI/WebControls/TCompareValidator.php2
-rw-r--r--framework/Web/UI/WebControls/TDatePicker.php276
-rw-r--r--framework/Web/UI/WebControls/TValidationSummary.php29
-rw-r--r--framework/Web/UI/WebControls/TValueTypeValidator.php2
-rw-r--r--tests/FunctionalTests/protected/pages/UI/DatePicker.page3
-rw-r--r--tests/FunctionalTests/protected/pages/UI/testHtmlArea.page2
25 files changed, 842 insertions, 277 deletions
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
<p>Where the second parameter in <tt>localize</tt> takes an associative array with the key as the substitution to find in the text and replaced it with the associated value.
The <tt>localize</tt> function does not solve the problem of localizing languages that have plural forms, the solution is to use <a href="#choice-format">TChoiceFormat</a>.</p>
+<p>The following sample demonstrates the basics of localization in Prado.</p>
+<com:RunBar PagePath="Advanced.Samples.I18N.Home" />
+
<h1>I18N Components</h1>
<a name="ttranslate"></a>
<h2>TTranslate</h2>
@@ -225,4 +228,5 @@ is "One Apple". If the <tt>Value</tt> was "2", then it will show "Two Apples".</
<p>Any non-empty combinations of the delimiters of square and round brackets are acceptable.
The string chosen for display depends on the <tt>Value</tt> property. The <tt>Value</tt> is evaluated for each set until the <tt>Value</tt> is found to belong to a particular set.</p>
+
</com:TContent> \ 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 @@
<com:TContent ID="body">
<h1>TCompareValidator Samples</h1>
+<p><strong>Note:</strong>TCompareValidator will start
+to validate only if both inputs are not empty.</p>
<table class="sampletable">
@@ -9,8 +11,8 @@
Compare validator with default settings:
</td>
<td class="sampleaction">
-<com:TTextBox ID="TextBox1" />
-<com:TTextBox ID="TextBox11" />
+<com:TTextBox ID="TextBox1" Text="a1" />
+<com:TTextBox ID="TextBox11" Text="a2"/>
<com:TCompareValidator
ValidationGroup="Group1"
ControlToValidate="TextBox1"
@@ -25,8 +27,8 @@ Compare validator with default settings:
Compare validator with client-side validation disabled:
</td>
<td class="sampleaction">
-<com:TTextBox ID="TextBox2" />
-<com:TTextBox ID="TextBox22" />
+<com:TTextBox ID="TextBox2" Text="b1"/>
+<com:TTextBox ID="TextBox22" Text="b2" />
<com:TCompareValidator
ValidationGroup="Group2"
EnableClientScript="false"
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TEmailAddressValidator/Home.page b/demos/quickstart/protected/pages/Controls/Samples/TEmailAddressValidator/Home.page
index bbeef3fd..db63a0a9 100644
--- a/demos/quickstart/protected/pages/Controls/Samples/TEmailAddressValidator/Home.page
+++ b/demos/quickstart/protected/pages/Controls/Samples/TEmailAddressValidator/Home.page
@@ -1,6 +1,8 @@
<com:TContent ID="body">
<h1>TEmailAddressValidator Samples</h1>
+<p><strong>Note:</strong>TEmailAddressValidator will start
+to validate only if the input is not empty.</p>
<table class="sampletable">
@@ -9,7 +11,7 @@
Email address validator with default settings:
</td>
<td class="sampleaction">
-<com:TTextBox ID="TextBox1" />
+<com:TTextBox ID="TextBox1" Text="a"/>
<com:TEmailAddressValidator
ValidationGroup="Group1"
ControlToValidate="TextBox1"
@@ -23,7 +25,7 @@ Email address validator with default settings:
Email address validator with client-side validation disabled:
</td>
<td class="sampleaction">
-<com:TTextBox ID="TextBox2" />
+<com:TTextBox ID="TextBox2" Text="b"/>
<com:TEmailAddressValidator
ValidationGroup="Group2"
EnableClientScript="false"
@@ -38,7 +40,7 @@ Email address validator with client-side validation disabled:
Email address validator with focus-on-error enabled and dynamic display:
</td>
<td class="sampleaction">
-<com:TTextBox ID="TextBox3" />
+<com:TTextBox ID="TextBox3" Text="c"/>
<com:TEmailAddressValidator
ValidationGroup="Group3"
ControlToValidate="TextBox3"
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TRegularExpressionValidator/Home.page b/demos/quickstart/protected/pages/Controls/Samples/TRegularExpressionValidator/Home.page
index ac93715d..5ce43fda 100644
--- a/demos/quickstart/protected/pages/Controls/Samples/TRegularExpressionValidator/Home.page
+++ b/demos/quickstart/protected/pages/Controls/Samples/TRegularExpressionValidator/Home.page
@@ -1,7 +1,8 @@
<com:TContent ID="body">
<h1>TRegularExpressionValidator Samples</h1>
-
+<p><strong>Note:</strong>TRegularExpressionValidator will start
+to validate only if the input is not empty.</p>
<table class="sampletable">
<tr>
@@ -9,12 +10,12 @@
Regular expression validator with default settings:
</td>
<td class="sampleaction">
-<com:TTextBox ID="TextBox1" />
+<com:TTextBox ID="TextBox1" Text="a"/>
<com:TRegularExpressionValidator
ValidationGroup="Group1"
ControlToValidate="TextBox1"
- RegularExpression="\w+"
- Text="Only word characters are allowed." />
+ RegularExpression="\d+"
+ Text="Only digits are allowed." />
<com:TButton Text="Submit" ValidationGroup="Group1" />
</td>
</tr>
@@ -24,13 +25,13 @@ Regular expression validator with default settings:
Regular expression validator with client-side validation disabled:
</td>
<td class="sampleaction">
-<com:TTextBox ID="TextBox2" />
+<com:TTextBox ID="TextBox2" Text="b"/>
<com:TRegularExpressionValidator
ValidationGroup="Group2"
EnableClientScript="false"
ControlToValidate="TextBox2"
- RegularExpression="\w+"
- Text="Only word characters are allowed." />
+ RegularExpression="\d+"
+ Text="Only digits are allowed." />
<com:TButton Text="Submit" ValidationGroup="Group2" />
</td>
</tr>
@@ -40,13 +41,13 @@ Regular expression validator with client-side validation disabled:
Regular expression validator with focus-on-error enabled and dynamic display:
</td>
<td class="sampleaction">
-<com:TTextBox ID="TextBox3" />
+<com:TTextBox ID="TextBox3" Text="c"/>
<com:TRegularExpressionValidator
ValidationGroup="Group3"
ControlToValidate="TextBox3"
Display="Dynamic"
- RegularExpression="\w+"
- Text="Only word characters are allowed." />
+ RegularExpression="\d+"
+ Text="Only digits are allowed." />
<com:TButton Text="Submit" ValidationGroup="Group3" />
</td>
</tr>
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 @@
<h1>TValidationSummary Samples</h1>
-<table class="sampletable">
-
-<tr>
-<td class="samplenote">
-Required field validator with default settings:
-</td>
-<td class="sampleaction">
-<com:TValidationSummary ValidationGroup="Group1" />
-<com:TTextBox ID="TextBox1" />
+
+<fieldset id="quickRegistration">
+ <legend>Create New Account</legend>
+
+<div class="username">
+ Username:
+ <com:TTextBox ID="Username" />
+ <com:TRequiredFieldValidator
+ ID="UsernameVal"
+ ControlToValidate="Username"
+ Display="None"
+ ValidationGroup="Group1"
+ ErrorMessage="a username is required." />
+</div>
+<div class="password">
+ Password
+ <com:TTextBox ID="Password" TextMode="Password" />
+</div>
<com:TRequiredFieldValidator
+ ID="PasswordVal"
+ ControlToValidate="Password"
+ Display="None"
ValidationGroup="Group1"
- ControlToValidate="TextBox1"
- Text="Field required." />
-<com:TButton Text="Submit" ValidationGroup="Group1" />
-</td>
-</tr>
+ ErrorMessage="a password is required." />
+
+<div class="create">
+ <com:TButton ID="Create" ValidationGroup="Group1" Text="Create New Account"/>
+</div>
+
+
+<div class="registrationSummary">
+ <com:TValidationSummary
+ ValidationGroup="Group1"
+ Display="None"
+ HeaderText="Unable to create new account because" />
+</div>
+
+</fieldset>
+
+
+<fieldset id="LoginForm">
+ <legend>Sign In</legend>
+
+<div class="username">
+ Login Name:
+ <com:TTextBox ID="UserID" />
+
+ <com:TRequiredFieldValidator
+ ID="UserVal1"
+ ControlToValidate="UserID"
+ Display="None"
+ ValidationGroup="Group2"
+ ErrorMessage="the username or email was not provided" />
+</div>
+
+<div class="password" >
+ Password:
+ <com:TTextBox ID="Pass" TextMode="Password" />
+ <com:TRequiredFieldValidator
+ ID="loginValidator3"
+ ControlToValidate="Pass"
+ Display="None"
+ ValidationGroup="Group2"
+ ErrorMessage="the password was not provided" />
+</div>
+
+<com:TButton ID="login" ValidationGroup="Group2" CssClass="button" Text="Sign In" />
+<div class="validation">
+ <com:TValidationSummary
+ ValidationGroup="Group2"
+ AutoUpdate="false"
+ Display="None"
+ ShowMessageBox="true"
+ HeaderText="You could not login because" />
+</div>
-</table>
+</fieldset>
</com:TContent> \ No newline at end of file
diff --git a/framework/Data/TDateTimeSimpleFormatter.php b/framework/Data/TSimpleDateFormatter.php
index ac5fb685..d2f78b37 100644
--- a/framework/Data/TDateTimeSimpleFormatter.php
+++ b/framework/Data/TSimpleDateFormatter.php
@@ -1,6 +1,6 @@
<?php
/**
- * TDateTimeSimpleFormatter class file
+ * TSimpleDateFormatter class file
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @link http://www.pradosoft.com/
@@ -11,7 +11,7 @@
*/
/**
- * TDateTimeSimpleFormatter class.
+ * TSimpleDateFormatter class.
*
* Formats and parses dates using the SimpleDateFormat pattern.
* This pattern is compatible with the I18N and java's SimpleDateFormatter.
@@ -29,13 +29,13 @@
*
* Usage example, to format a date
* <code>
- * $formatter = new TDateTimeSimpleFormatter("dd/MM/yyy");
+ * $formatter = new TSimpleDateFormatter("dd/MM/yyy");
* echo $formatter->format(time());
* </code>
*
* To parse the date string into a date timestamp.
* <code>
- * $formatter = new TDateTimeSimpleFormatter("d-M-yyy");
+ * $formatter = new TSimpleDateFormatter("d-M-yyy");
* echo $formatter->parse("24-6-2005");
* </code>
*
@@ -44,7 +44,7 @@
* @package System.Data
* @since 3.0
*/
-class TDateTimeSimpleFormatter
+class TSimpleDateFormatter
{
/**
* Formatting pattern.
@@ -129,11 +129,11 @@ class TDateTimeSimpleFormatter
private function getDate($value)
{
if(is_int($value))
- return getdate($value);
+ return @getdate($value);
$date = @strtotime($value);
if($date < 0)
throw new TInvalidDataValueException('invalid_date', $value);
- return getdate($date);
+ return @getdate($date);
}
/**
@@ -150,12 +150,18 @@ class TDateTimeSimpleFormatter
* @return int date time stamp
* @throws TInvalidDataValueException if date string is malformed.
*/
- public function parse($value,$defaulToCurrentTime=true)
+ 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;
@@ -165,8 +171,8 @@ class TDateTimeSimpleFormatter
$token='';
$x=null; $y=null;
- $date = $this->getDate(time());
- if($defaulToCurrentTime)
+
+ if($defaultToCurrentTime)
{
$year = "{$date['year']}";
$month = $date['mon'];
@@ -242,7 +248,7 @@ class TDateTimeSimpleFormatter
if(!$defaultToCurrentTime && (is_null($month) || is_null($day) || is_null($year)))
return null;
else
- return mktime(0, 0, 0, $month, $day, $year);
+ return $this->getDate(@mktime(0, 0, 0, $month, $day, $year));
}
/**
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.
+ * <code>
+ * Event.OnLoad(function(){ alert("Page Loaded!"); });
+ * </code>
+ *
+ * @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; i<elements.length; i++)
- this.__observe(elements[i], name, observer, useCapture);
- },
- __observe: function(element, name, observer, useCapture) {
- var element = $(element);
- useCapture = useCapture || false;
+
+ /**
+ * Adds the specified event listener function to the set of
+ * listeners registered on given element to handle events of the
+ * specified type. If <tt>useCapture</tt> is <tt>true</tt>, the
+ * listener is registered as a capturing event listener. If
+ * <tt>useCapture</tt> is <tt>false</tt>, it is registered as a
+ * normal event listener.
+ *
+ * <tt>Event.observe</tt> 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.
+ * <code>
+ * var link1_clicked = function()
+ * {
+ * alert("Clicked!");
+ * };
+ * Event.observe("link1", "click", link1_clicked);
+ * </code>
+ *
+ * @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 <tt>false</tt> 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<elements.length; i++)
+ this.__observe(elements[i], name, observer, useCapture);
+ },
+
+ /**
+ * Register event listeners.
+ * @private
+ */
+ __observe: function(element, name, observer, useCapture)
+ {
+ var element = $(element);
+ useCapture = useCapture || false;
- if (name == 'keypress' &&
- ((navigator.appVersion.indexOf('AppleWebKit') > 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 <tt>type</tt> on a DOM
+ * <tt>element</tt>. 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. <b>Internationalization
* is not supported</b>
- * @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.
* <i>The currency input format is <b>very</b> strict, null will be returned if
* the pattern does not match</i>.
- * @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
+ * <code>
+ * var browser = Prado.Browser();
+ * alert(browser.ie); //should ouput true if IE, false otherwise
+ * </code>
+ * @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. <b>CalendarStyle</b> property sets the packages
* styles available. E.g. <b>default</b>.
*
+ * The <b>InputMode</b> property can be set to "TextBox" or "DropDownList" with
+ * default as "TextBox".
+ * In <tt>DropDownList</tt> 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 <weizhuo[at]gmail[dot]com>
* @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"
*/
@@ -221,11 +236,104 @@ class TDatePicker extends TTextBox
}
/**
+ * @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,46 +353,152 @@ 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
@@ -37,6 +37,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
*/
public function getHeaderText()
@@ -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<br/>
dv<br/>
as<br/>
d<br/>
+<com:TDatePicker ID="Picker1" InputMode="DropDownList"/>
+<com:TButton Text="Update" />
+<%= $this->Page->Picker1->Text %>
as<br/>
d<br/>
asd<br/>
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" %>
<com:TContent ID="Content">
-<com:TForm>
<com:THtmlArea>
<prop:Options>
@@ -8,5 +7,4 @@
language: "zh_CN"
</prop:Options>
</com:THtmlArea>
-</com:TForm>
</com:TContent> \ No newline at end of file