summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes9
-rw-r--r--HISTORY7
-rw-r--r--buildscripts/classtree/build.php4
-rw-r--r--demos/quickstart/protected/controls/DocLink.php3
-rw-r--r--demos/quickstart/protected/pages/Advanced/Themes.page3
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.page41
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.php23
-rw-r--r--demos/quickstart/protected/pages/Controls/Validation.page35
-rw-r--r--demos/quickstart/protected/pages/Search.php10
-rw-r--r--framework/Exceptions/messages.txt3
-rw-r--r--framework/I18N/TGlobalization.php27
-rw-r--r--framework/I18N/core/Gettext/MO.php1
-rw-r--r--framework/I18N/core/Gettext/PO.php1
-rw-r--r--framework/I18N/core/MessageSource_XLIFF.php7
-rw-r--r--framework/I18N/core/MessageSource_gettext.php6
-rw-r--r--framework/IO/TTarFileExtractor.php2
-rw-r--r--framework/PradoBase.php2
-rw-r--r--framework/TApplication.php3
-rw-r--r--framework/Util/TSimpleDateFormatter.php5
-rw-r--r--framework/Web/Javascripts/js/validator.js9
-rw-r--r--framework/Web/Javascripts/prado/validation3.js14
-rw-r--r--framework/Web/TAssetManager.php3
-rw-r--r--framework/Web/UI/TClientScriptManager.php34
-rw-r--r--framework/Web/UI/TPage.php21
-rw-r--r--framework/Web/UI/WebControls/TBaseValidator.php4
-rw-r--r--framework/Web/UI/WebControls/TDataGrid.php1
-rw-r--r--framework/Web/UI/WebControls/TDataList.php2
-rw-r--r--framework/Web/UI/WebControls/TDataTypeValidator.php3
-rw-r--r--framework/Web/UI/WebControls/TDatePicker.php3
-rw-r--r--framework/Web/UI/WebControls/TOutputCache.php2
-rw-r--r--framework/Web/UI/WebControls/TPanelStyle.php2
-rw-r--r--framework/Web/UI/WebControls/TStyle.php33
-rw-r--r--framework/Web/UI/WebControls/TStyleSheet.php18
-rw-r--r--framework/Web/UI/WebControls/TWizard.php10
-rwxr-xr-xframework/prado-cli.php4
-rw-r--r--tests/FunctionalTests/features/protected/pages/FocusControl.page46
-rw-r--r--tests/FunctionalTests/features/protected/pages/FocusControl.php17
-rw-r--r--tests/FunctionalTests/tickets/protected/pages/Ticket274.page22
-rw-r--r--tests/FunctionalTests/tickets/protected/pages/Ticket278.page42
-rw-r--r--tests/FunctionalTests/tickets/protected/pages/Ticket278.php23
-rw-r--r--tests/FunctionalTests/tickets/tests/Ticket274TestCase.php24
-rw-r--r--tests/FunctionalTests/tickets/tests/Ticket278TestCase.php54
-rw-r--r--tests/FunctionalTests/validators/tests/DataTypeValidatorTestCase.php2
43 files changed, 535 insertions, 50 deletions
diff --git a/.gitattributes b/.gitattributes
index 140bf48d..61552a8d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -861,6 +861,8 @@ demos/quickstart/protected/pages/Controls/Samples/TCheckBox/Home.page -text
demos/quickstart/protected/pages/Controls/Samples/TCheckBox/Home.php -text
demos/quickstart/protected/pages/Controls/Samples/TCheckBoxList/Home.page -text
demos/quickstart/protected/pages/Controls/Samples/TCheckBoxList/Home.php -text
+demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.page -text
+demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.php -text
demos/quickstart/protected/pages/Controls/Samples/TCompareValidator/Home.page -text
demos/quickstart/protected/pages/Controls/Samples/TCompareValidator/Home.php -text
demos/quickstart/protected/pages/Controls/Samples/TCustomValidator/Home.page -text
@@ -1874,6 +1876,8 @@ tests/FunctionalTests/features/protected/pages/ActiveControls/config.xml -text
tests/FunctionalTests/features/protected/pages/ColorPicker.page -text
tests/FunctionalTests/features/protected/pages/FeatureList.page -text
tests/FunctionalTests/features/protected/pages/FeatureList.php -text
+tests/FunctionalTests/features/protected/pages/FocusControl.page -text
+tests/FunctionalTests/features/protected/pages/FocusControl.php -text
tests/FunctionalTests/features/protected/pages/I18N/BasicI18N.page -text
tests/FunctionalTests/features/protected/pages/I18N/BasicI18N.php -text
tests/FunctionalTests/features/protected/pages/I18N/Home.page -text
@@ -1939,6 +1943,9 @@ tests/FunctionalTests/tickets/protected/pages/Ticket239.page -text
tests/FunctionalTests/tickets/protected/pages/Ticket239.php -text
tests/FunctionalTests/tickets/protected/pages/Ticket269.page -text
tests/FunctionalTests/tickets/protected/pages/Ticket27.page -text
+tests/FunctionalTests/tickets/protected/pages/Ticket274.page -text
+tests/FunctionalTests/tickets/protected/pages/Ticket278.page -text
+tests/FunctionalTests/tickets/protected/pages/Ticket278.php -text
tests/FunctionalTests/tickets/protected/pages/Ticket28.page -text
tests/FunctionalTests/tickets/protected/pages/Ticket28.php -text
tests/FunctionalTests/tickets/protected/pages/Ticket284.page -text
@@ -1965,6 +1972,8 @@ tests/FunctionalTests/tickets/tests/Ticket169TestCase.php -text
tests/FunctionalTests/tickets/tests/Ticket191TestCase.php -text
tests/FunctionalTests/tickets/tests/Ticket21TestCase.php -text
tests/FunctionalTests/tickets/tests/Ticket239TestCase.php -text
+tests/FunctionalTests/tickets/tests/Ticket274TestCase.php -text
+tests/FunctionalTests/tickets/tests/Ticket278TestCase.php -text
tests/FunctionalTests/tickets/tests/Ticket27TestCase.php -text
tests/FunctionalTests/tickets/tests/Ticket284TestCase.php -text
tests/FunctionalTests/tickets/tests/Ticket285TestCase.php -text
diff --git a/HISTORY b/HISTORY
index 43d8764b..38dc7d6e 100644
--- a/HISTORY
+++ b/HISTORY
@@ -14,8 +14,10 @@ Version 3.0.3 August 6, 2006
============================
BUG: Ticket#264 - Typos in some exception throw statements (Knut)
BUG: Ticket#268 - THttpResponse.redirect() may fail for some browsers (Qiang)
+BUG: Ticket#271 - Page method setFocus doesn't work (Wei)
BUG: Ticket#285 - NumberFormat Rounding Bug (Wei)
BUG: Ticket#297 - THttpRequest::constructUrl() encoding bug about array GET parameters (Qiang)
+BUG: Ticket#320 - Typo in calling TDataList::setSelectedItemIndex and a bug in inserting wizard steps (Qiang)
BUG: TDataGrid may complain getting ItemType on a non-object if the grid is not data-bound (Qiang)
BUG: TCheckBox.Value should be converted to string (Qiang)
BUG: Ticket#302 - TDatePicker's bug with AutoPostBack set to "true" (Wei)
@@ -31,9 +33,14 @@ ENH: Ticket#223 - Use TRequiredFieldValidator for TRadioButtons with GroupName p
ENH: StringLength, multi-byte, check in TRangeValidator (Wei)
ENH: Ticket#263 - TListBox and TDropDownList support optgroup now (Qiang)
ENH: Ticket#277 - Added TControl.CustomData property (Qiang)
+ENH: Ticket#278 - client-side validator enable/disable (conditional) (Wei)
ENH: Ticket#287 - TControl::broadcastEvent() may raise events now (Qiang)
ENH: Ticket#292 - Added THttpRequest::parseUrl() so that it is easier to be extended (Qiang)
ENH: Ticket#309 - Added THttpRequest.UrlParamSeparator property (Qiang)
+ENH: Ticket#313 - Added TTableStyle.BorderCollapse property (Qiang)
+ENH: Ticket#316 - Added media type support to CSS files in a theme (Qiang)
+ENH: Validating TDatePicker does not need to explictly specific the DateFormat in validators. (Wei)
+ENH: TRequireFieldValidator can be used to validate a valid date (Wei).
NEW: Added TStyleSheet (Wei)
diff --git a/buildscripts/classtree/build.php b/buildscripts/classtree/build.php
index d7f74828..c0b5ba35 100644
--- a/buildscripts/classtree/build.php
+++ b/buildscripts/classtree/build.php
@@ -6,9 +6,9 @@ require_once($frameworkPath.'/prado.php');
require_once($basePath.'/DWExtension.php');
$exclusions=array(
- 'prado.php',
+// 'prado.php',
'pradolite.php',
- 'PradoBase.php',
+// 'PradoBase.php',
'clientscripts.php',
'.svn',
'/I18N/core',
diff --git a/demos/quickstart/protected/controls/DocLink.php b/demos/quickstart/protected/controls/DocLink.php
index 74398efb..e8ca7dfa 100644
--- a/demos/quickstart/protected/controls/DocLink.php
+++ b/demos/quickstart/protected/controls/DocLink.php
@@ -22,7 +22,8 @@ class DocLink extends THyperLink
{
$classFile=array_pop($paths).'.html';
$this->setNavigateUrl(self::BASE_URL . '/' . implode('.',$paths) . '/' . $classFile);
- $this->setText('API Manual');
+ if($this->getText() === '')
+ $this->setText('API Manual');
}
}
}
diff --git a/demos/quickstart/protected/pages/Advanced/Themes.page b/demos/quickstart/protected/pages/Advanced/Themes.page
index 5ba0a121..07435928 100644
--- a/demos/quickstart/protected/pages/Advanced/Themes.page
+++ b/demos/quickstart/protected/pages/Advanced/Themes.page
@@ -28,6 +28,9 @@ This will apply the 'Blue' skin to the button. Note, the initial property values
<p>
To use the Javascript files and CSS files contained in a theme, a <tt>THead</tt> control must be placed on the page template. This is because the theme will register those files with the page and <tt>THead</tt> is the right place to load those files.
</p>
+<p>
+It is possible to specify media types of CSS files contained in a theme. By default, a CSS file applies to all media types. If the CSS file is named like <tt>mystyle.print.css</tt>, it will be applied only to <tt>print</tt> media type. As another example, <tt>mystyle.screen.css</tt> applies to <tt>screen</tt> media only, and <tt>mystyle.css</tt> applies to all media types.
+</p>
<h2 id="5905">Theme Storage</h2>
<p>
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.page b/demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.page
new file mode 100644
index 00000000..e96e7c12
--- /dev/null
+++ b/demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.page
@@ -0,0 +1,41 @@
+<com:TContent ID="body">
+ <h1>Validator Toggle - Server and Client Side</h1>
+ <com:TLabel ForControl="text1" Text="Text 1:" />
+ <com:TTextBox ID="text1" />
+ <com:TRequiredFieldValidator
+ ID="validator1"
+ ControlToValidate="text1"
+ ErrorMessage="Text 1 is required" />
+ <div>
+ <com:TCheckBox ID="check1" Text="More..." />
+ </div>
+
+ <com:TPanel ID="panel1" Style="display:none" >
+ <com:TLabel ForControl="text2" Text="Text 2:" />
+ <com:TTextBox ID="text2" />
+
+ <com:TRequiredFieldValidator
+ ID="validator2"
+ ControlToValidate="text2"
+ OnValidate="validator2_onValidate"
+ OnPreRender="validate2_onPostValidate"
+ ErrorMessage="Text 2 is required">
+ <prop:ClientSide.OnValidate>
+ validator.enabled = $("<%= $this->check1->ClientID %>").checked;
+ </prop:ClientSide.OnValidate>
+ </com:TRequiredFieldValidator>
+
+ </com:TPanel>
+
+ <com:TButton ID="button1" Text="Submit!" />
+
+ <com:TClientScript>
+ Event.OnLoad(function()
+ {
+ Event.observe("<%= $this->check1->ClientID %>", "click", function(ev)
+ {
+ $("<%= $this->panel1->ClientID %>").toggle();
+ });
+ });
+ </com:TClientScript>
+</com:TContent> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.php b/demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.php
new file mode 100644
index 00000000..c5440996
--- /dev/null
+++ b/demos/quickstart/protected/pages/Controls/Samples/TClientSideValidator/Home.php
@@ -0,0 +1,23 @@
+<?php
+
+class Home extends TPage
+{
+ function validator2_onValidate($sender, $param)
+ {
+ $sender->Enabled = $this->check1->Checked;
+ }
+
+ function validate2_onPostValidate($sender, $param)
+ {
+ $sender->Enabled = true;
+ }
+
+ function onPreRender($param)
+ {
+ parent::onPreRender($param);
+ $this->panel1->Style =
+ $this->check1->Checked ? "display:block" : "display:none";
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/Controls/Validation.page b/demos/quickstart/protected/pages/Controls/Validation.page
index 12836b8c..2241f346 100644
--- a/demos/quickstart/protected/pages/Controls/Validation.page
+++ b/demos/quickstart/protected/pages/Controls/Validation.page
@@ -151,4 +151,39 @@ The summary can be displayed as a list, a bulleted list, or a single paragraph b
</p>
<com:RunBar PagePath="Controls.Samples.TValidationSummary.Home" />
+<h2>Client and Server Side Conditional Validation</h2>
+<p>
+ All validators contains the following events.
+ <ul>
+ <li>The <tt>OnValidate</tt> event is raise before the validator validation functions are called.</li>
+ <li>The <tt>OnSuccess</tt> event is raised after the validator has successfully validate the control.</li>
+ <li>The <tt>OnError</tt> event is raised after the validator fails validation.</li>
+ </ul>
+ The corresponding events for the client side is available as sub-properties
+ of the <tt>ClientSide</tt> property of the validator.
+</p>
+<p>The following example pop-up a message saying "hello" when the validator fails on the client-side.
+<com:TTextHighlighter Language="prado" CssClass="source">
+&lt;com:TRequiredFieldValidator ... &gt;
+ &lt;prop:ClientSide.OnError&gt;
+ alert("hello");
+ &lt;/prop:ClientSide.OnError&gt;
+&lt;/com:TRequiredFieldValidator&gt;
+</com:TTextHighlighter>
+The resulting client-side event callback function is of the following form.
+<com:TTextHighlighter Language="javascript" CssClass="source">
+function onErrorHandler(validator, sender)
+{
+ alert("hello");
+}
+</com:TTextHighlighter>
+Where <tt>validator</tt> is the current client-side validator and <tt>sender</tt>
+is the control that invoked the validator.
+</p>
+<h3>Conditional Validation Example</h3>
+<p>
+The following example show the use of client-side and server side validator events. The example
+demonstrates conditional validation.
+<com:RunBar PagePath="Controls.Samples.TClientSideValidator.Home" />
+</p>
</com:TContent> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/Search.php b/demos/quickstart/protected/pages/Search.php
index f1d07ffa..d2dfa7da 100644
--- a/demos/quickstart/protected/pages/Search.php
+++ b/demos/quickstart/protected/pages/Search.php
@@ -13,11 +13,11 @@ class Search extends TPage
$hits_1 = $quickstart->find($text);
$this->quickstart_results->setDataSource($hits_1);
$this->quickstart_results->dataBind();
-
+
$this->emptyResult->setVisible(!count($hits_1));
}
}
-
+
public function highlightSearch($text)
{
$words = str_word_count($text, 1);
@@ -33,7 +33,7 @@ class Search extends TPage
break;
}
}
-
+
$min = $where - 15 < 0 ? 0 : $where - 15;
$max = $where + 15 > $t ? $t : $where + 15;
$subtext = array_splice($words, $min, $max-$min);
@@ -41,13 +41,13 @@ class Search extends TPage
$suffix = $max == $t ? '' : '...';
return $prefix.implode(' ', $subtext).$suffix;
}
-
+
protected function containsKeys($word, $keys)
{
foreach($keys as $key)
{
if(is_int(strpos($word, $key)))
- return true;
+ return true;
}
return false;
}
diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt
index 630f7b50..39d304be 100644
--- a/framework/Exceptions/messages.txt
+++ b/framework/Exceptions/messages.txt
@@ -323,7 +323,8 @@ databoundcontrol_datamember_invalid = databoundcontrol_datamember_invalid
clientscript_invalid_file_position = Invalid file position '{1}' for TClientScript control '{0}', must be 'Head', 'Here' or 'Begin'.
tdatepicker_autopostback_unsupported = '{0}' does not support AutoPostBack.
-
+globalization_cache_path_failed = Unable to create translation message cache path '{0}'. Make sure the parent directory exists and is writable by the Web process.
+globalization_source_path_failed = Unable to create translation message path '{0}'. Make sure the parent directory exists and is writable by the Web process.
callback_not_support_no_priority_state_update = Callback request does not support unprioritized pagestate update.
callback_invalid_callback_options = '{1}' is not a valid TCallbackOptions control for Callback control '{0}'.
callback_invalid_clientside_options = Callback ClientSide property must be either a string that is the ID of a TCallbackOptions control or an instance of TCallbackClientSideOptions.=======
diff --git a/framework/I18N/TGlobalization.php b/framework/I18N/TGlobalization.php
index aa545d21..1ea7ce2b 100644
--- a/framework/I18N/TGlobalization.php
+++ b/framework/I18N/TGlobalization.php
@@ -168,12 +168,33 @@ class TGlobalization extends TModule
{
if($config['type'] == 'XLIFF' || $config['type'] == 'gettext')
{
- $config['source'] = Prado::getPathOfNamespace($config['source']);
- if($config['source']===null || !is_dir($config['source']))
- throw new TException("invalid source dir '{$config['source']}'");
+ if($config['source'])
+ {
+ $config['source'] = Prado::getPathOfNamespace($config['source']);
+ if(!is_dir($config['source']))
+ {
+ if(@mkdir($config['source'])===false)
+ throw new TConfigurationException('globalization_source_path_failed',
+ $config['source']);
+ chmod($config['source'], 0777); //make it deletable
+ }
+ }
+ else
+ {
+ throw new TConfigurationException("invalid source dir '{$config['source']}'");
+ }
}
if($config['cache'])
+ {
$config['cache'] = $this->getApplication()->getRunTimePath().'/i18n';
+ if(!is_dir($config['cache']))
+ {
+ if(@mkdir($config['cache'])===false)
+ throw new TConfigurationException('globalization_cache_path_failed',
+ $config['cache']);
+ chmod($config['cache'], 0777); //make it deletable
+ }
+ }
$this->_translation = $config;
}
diff --git a/framework/I18N/core/Gettext/MO.php b/framework/I18N/core/Gettext/MO.php
index 5ee0057f..9f2d5799 100644
--- a/framework/I18N/core/Gettext/MO.php
+++ b/framework/I18N/core/Gettext/MO.php
@@ -349,6 +349,7 @@ class TGettext_MO extends TGettext
// done
@flock($this->_handle, LOCK_UN);
@fclose($this->_handle);
+ chmod($file,0777);
return true;
}
}
diff --git a/framework/I18N/core/Gettext/PO.php b/framework/I18N/core/Gettext/PO.php
index 015747a0..3a5fda04 100644
--- a/framework/I18N/core/Gettext/PO.php
+++ b/framework/I18N/core/Gettext/PO.php
@@ -154,6 +154,7 @@ class TGettext_PO extends TGettext
//done
@flock($fh, LOCK_UN);
@fclose($fh);
+ chmod($file,0777);
return true;
}
}
diff --git a/framework/I18N/core/MessageSource_XLIFF.php b/framework/I18N/core/MessageSource_XLIFF.php
index 2194ca41..7f2f27c5 100644
--- a/framework/I18N/core/MessageSource_XLIFF.php
+++ b/framework/I18N/core/MessageSource_XLIFF.php
@@ -473,10 +473,15 @@ class MessageSource_XLIFF extends MessageSource
$variant = array_shift($variants);
$file = $this->getSource($variant);
$dir = dirname($file);
- if(!is_dir($dir)) @mkdir($dir);
+ if(!is_dir($dir))
+ {
+ @mkdir($dir);
+ @chmod($dir,0777);
+ }
if(!is_dir($dir))
throw new TException("Unable to create directory $dir");
file_put_contents($file, $this->getTemplate($catalogue));
+ chmod($file, 0777);
return array($variant, $file);
}
diff --git a/framework/I18N/core/MessageSource_gettext.php b/framework/I18N/core/MessageSource_gettext.php
index 78fa5259..c92577d4 100644
--- a/framework/I18N/core/MessageSource_gettext.php
+++ b/framework/I18N/core/MessageSource_gettext.php
@@ -431,7 +431,11 @@ class MessageSource_gettext extends MessageSource
$po_file = $this->getPOFile($mo_file);
$dir = dirname($mo_file);
- if(!is_dir($dir)) @mkdir($dir);
+ if(!is_dir($dir))
+ {
+ @mkdir($dir);
+ @chmod($dir,0777);
+ }
if(!is_dir($dir))
throw new TException("Unable to create directory $dir");
diff --git a/framework/IO/TTarFileExtractor.php b/framework/IO/TTarFileExtractor.php
index 9f61026d..1bd245ca 100644
--- a/framework/IO/TTarFileExtractor.php
+++ b/framework/IO/TTarFileExtractor.php
@@ -460,6 +460,7 @@ class TTarFileExtractor
.$v_header['filename'].'}');
return false;
}
+ chmod($v_header['filename'], 0777);
}
} else {
if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) {
@@ -549,6 +550,7 @@ class TTarFileExtractor
$this->_error("Unable to create directory '$p_dir'");
return false;
}
+ chmod($p_dir,0777);
return true;
}
diff --git a/framework/PradoBase.php b/framework/PradoBase.php
index 50e4ac82..4685ce83 100644
--- a/framework/PradoBase.php
+++ b/framework/PradoBase.php
@@ -516,7 +516,7 @@ class PradoBase
*/
public static function varDump($var,$depth=10,$highlight=false)
{
- require_once(PRADO_DIR.'/Util/TVarDumper.php');
+ Prado::using('System.Util.TVarDumper');
return TVarDumper::dump($var,$depth,$highlight);
}
diff --git a/framework/TApplication.php b/framework/TApplication.php
index ef2fd1a1..68064072 100644
--- a/framework/TApplication.php
+++ b/framework/TApplication.php
@@ -310,8 +310,11 @@ class TApplication extends TComponent
$subdir=basename($this->_configFile);
$this->_runtimePath.='/'.$subdir;
if(!is_dir($this->_runtimePath))
+ {
if(@mkdir($this->_runtimePath)===false)
throw new TConfigurationException('application_runtimepath_failed',$this->_runtimePath);
+ chmod($this->_runtimePath, 0777); //make it deletable
+ }
}
}
else
diff --git a/framework/Util/TSimpleDateFormatter.php b/framework/Util/TSimpleDateFormatter.php
index 971225b5..03ae7b7d 100644
--- a/framework/Util/TSimpleDateFormatter.php
+++ b/framework/Util/TSimpleDateFormatter.php
@@ -185,7 +185,10 @@ class TSimpleDateFormatter
*/
public function isValidDate($value)
{
- return !is_null($this->parse($value, false));
+ if(is_null($value))
+ return false;
+ else
+ return !is_null($this->parse($value, false));
}
/**
diff --git a/framework/Web/Javascripts/js/validator.js b/framework/Web/Javascripts/js/validator.js
index 5e896aa1..711c996e 100644
--- a/framework/Web/Javascripts/js/validator.js
+++ b/framework/Web/Javascripts/js/validator.js
@@ -97,7 +97,8 @@ control.addClassName(CssClass);}},hide:function()
{this.isValid=true;this.updateControl();this.visible=false;},validate:function(invoker)
{if(typeof(this.options.OnValidate)=="function")
this.options.OnValidate(this,invoker);if(this.enabled)
-this.isValid=this.evaluateIsValid();if(this.isValid)
+this.isValid=this.evaluateIsValid();else
+this.isValid=true;if(this.isValid)
{if(typeof(this.options.OnSuccess)=="function")
{this.visible=true;this.message.style.visibility="visible";this.updateControlCssClass(this.control,this.isValid);this.options.OnSuccess(this,invoker);}
else
@@ -126,7 +127,11 @@ return value;},getValidationValue:function(control)
control=this.control
switch(this.options.ControlType)
{case'TDatePicker':if(control.type=="text")
-return this.trim($F(control));else
+{value=this.trim($F(control));if(this.options.DateFormat)
+{date=value.toDate(this.options.DateFormat);return date==null?'':date;}
+else
+return value;}
+else
{this.observeDatePickerChanges();return Prado.WebUI.TDatePicker.getDropDownDate(control).getTime();}
case'THtmlArea':if(typeof tinyMCE!="undefined")
tinyMCE.triggerSave();return this.trim($F(control));case'TRadioButton':if(this.options.GroupName)
diff --git a/framework/Web/Javascripts/prado/validation3.js b/framework/Web/Javascripts/prado/validation3.js
index 1dba23da..7df6efeb 100644
--- a/framework/Web/Javascripts/prado/validation3.js
+++ b/framework/Web/Javascripts/prado/validation3.js
@@ -661,6 +661,8 @@ Prado.WebUI.TBaseValidator.prototype =
if(this.enabled)
this.isValid = this.evaluateIsValid();
+ else
+ this.isValid = true;
if(this.isValid)
{
@@ -776,7 +778,17 @@ Prado.WebUI.TBaseValidator.prototype =
{
case 'TDatePicker':
if(control.type == "text")
- return this.trim($F(control));
+ {
+ value = this.trim($F(control));
+
+ if(this.options.DateFormat)
+ {
+ date = value.toDate(this.options.DateFormat);
+ return date == null ? '' : date;
+ }
+ else
+ return value;
+ }
else
{
this.observeDatePickerChanges();
diff --git a/framework/Web/TAssetManager.php b/framework/Web/TAssetManager.php
index f9fe156f..f6384a08 100644
--- a/framework/Web/TAssetManager.php
+++ b/framework/Web/TAssetManager.php
@@ -199,7 +199,10 @@ class TAssetManager extends TModule
protected function copyFile($src,$dst)
{
if(!is_dir($dst))
+ {
@mkdir($dst);
+ @chmod($dst, 0777);
+ }
$dstFile=$dst.'/'.basename($src);
if(@filemtime($dstFile)<@filemtime($src))
{
diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php
index 540ea01e..d1f3f457 100644
--- a/framework/Web/UI/TClientScriptManager.php
+++ b/framework/Web/UI/TClientScriptManager.php
@@ -145,7 +145,7 @@ class TClientScriptManager extends TApplicationComponent
}
}
- /**
+ /**
* Renders the <script> tag that will load the javascript library files.
* @param THtmlWriter writer that renders the <script> tag.
*/
@@ -163,7 +163,7 @@ class TClientScriptManager extends TApplicationComponent
}
}
- /**
+ /**
* Returns javascript statement that create a new callback request object.
* @param ICallbackEventHandler callback response handler
* @param array additional callback options
@@ -244,8 +244,11 @@ class TClientScriptManager extends TApplicationComponent
*/
public function registerFocusControl($target)
{
- $this->registerPradoScriptInternal('prado');
- $this->_endScripts['prado:focus']='Prado.Focus.setFocus("'.TJavaScript::quoteString($target).'");';
+ $this->registerPradoScriptInternal('effects');
+ if($target instanceof TControl)
+ $target=$target->getClientID();
+ $id = TJavaScript::quoteString($target);
+ $this->_endScripts['prado:focus'] = 'new Effect.ScrollTo("'.$id.'"); Prado.Element.focus("'.$id.'");';
$params=func_get_args();
$this->_page->registerCachingAction('Page.ClientScript','registerFocusControl',$params);
@@ -268,10 +271,14 @@ class TClientScriptManager extends TApplicationComponent
* Registers a CSS file to be rendered in the page head
* @param string a unique key identifying the file
* @param string URL to the CSS file
+ * @param string media type of the CSS (such as 'print', 'screen', etc.). Defaults to empty, meaning the CSS applies to all media types.
*/
- public function registerStyleSheetFile($key,$url)
+ public function registerStyleSheetFile($key,$url,$media='')
{
- $this->_styleSheetFiles[$key]=$url;
+ if($media==='')
+ $this->_styleSheetFiles[$key]=$url;
+ else
+ $this->_styleSheetFiles[$key]=array($url,$media);
$params=func_get_args();
$this->_page->registerCachingAction('Page.ClientScript','registerStyleSheetFile',$params);
@@ -282,7 +289,7 @@ class TClientScriptManager extends TApplicationComponent
* @param string a unique key identifying the CSS block
* @param string CSS block
*/
- public function registerStyleSheet($key,$css)
+ public function registerStyleSheet($key,$css,$media='')
{
$this->_styleSheets[$key]=$css;
@@ -431,7 +438,7 @@ class TClientScriptManager extends TApplicationComponent
{
return isset($this->_endScripts[$key]);
}
-
+
/**
* @return boolean true if any end scripts are registered.
*/
@@ -439,7 +446,7 @@ class TClientScriptManager extends TApplicationComponent
{
return count($this->_endScripts) > 0;
}
-
+
/**
* @return boolean true if any begin scripts are registered.
*/
@@ -464,7 +471,12 @@ class TClientScriptManager extends TApplicationComponent
{
$str='';
foreach($this->_styleSheetFiles as $url)
- $str.="<link rel=\"stylesheet\" type=\"text/css\" href=\"".THttpUtility::htmlEncode($url)."\" />\n";
+ {
+ if(is_array($url))
+ $str.="<link rel=\"stylesheet\" type=\"text/css\" media=\"{$url[1]}\" href=\"".THttpUtility::htmlEncode($url[0])."\" />\n";
+ else
+ $str.="<link rel=\"stylesheet\" type=\"text/css\" href=\"".THttpUtility::htmlEncode($url)."\" />\n";
+ }
$writer->write($str);
}
@@ -620,4 +632,4 @@ abstract class TClientSideOptions extends TComponent
}
}
-?> \ No newline at end of file
+?>
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
index 22aee89f..60586fab 100644
--- a/framework/Web/UI/TPage.php
+++ b/framework/Web/UI/TPage.php
@@ -637,20 +637,37 @@ class TPage extends TTemplateControl
if($this->_theme instanceof ITheme)
{
foreach($this->_theme->getStyleSheetFiles() as $url)
- $cs->registerStyleSheetFile($url,$url);
+ $cs->registerStyleSheetFile($url,$url,$this->getCssMediaType($url));
foreach($this->_theme->getJavaScriptFiles() as $url)
$cs->registerHeadScriptFile($url,$url);
}
if($this->_styleSheet instanceof ITheme)
{
foreach($this->_styleSheet->getStyleSheetFiles() as $url)
- $cs->registerStyleSheetFile($url,$url);
+ $cs->registerStyleSheetFile($url,$url,$this->getCssMediaType($url));
foreach($this->_styleSheet->getJavaScriptFiles() as $url)
$cs->registerHeadScriptFile($url,$url);
}
}
/**
+ * Determines the media type of the CSS file.
+ * The media type is determined according to the following file name pattern:
+ * xxx.media-type.extension
+ * For example, 'mystyle.print.css' means its media type is 'print'.
+ * @param string CSS URL
+ * @return string media type of the CSS file
+ */
+ private function getCssMediaType($url)
+ {
+ $segs=explode('.',basename($url));
+ if(isset($segs[2]))
+ return $segs[count($segs)-2];
+ else
+ return '';
+ }
+
+ /**
* Raises OnSaveStateComplete event.
* This method is invoked right after {@link onSaveState OnSaveState} stage.
* You may override this method to provide additional logic after page state is saved.
diff --git a/framework/Web/UI/WebControls/TBaseValidator.php b/framework/Web/UI/WebControls/TBaseValidator.php
index 6660184e..ff026b49 100644
--- a/framework/Web/UI/WebControls/TBaseValidator.php
+++ b/framework/Web/UI/WebControls/TBaseValidator.php
@@ -167,6 +167,10 @@ abstract class TBaseValidator extends TLabel implements IValidator
$options['ControlCssClass'] = $this->getControlCssClass();
$options['ControlType'] = $this->getClientControlClass($control);
+
+ //get date format from date picker target control
+ if($control instanceof TDatePicker)
+ $options['DateFormat'] = $control->getDateFormat();
if(!is_null($this->_clientSide))
$options = array_merge($options,$this->_clientSide->getOptions()->toArray());
diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php
index 2687ac35..e27f6ead 100644
--- a/framework/Web/UI/WebControls/TDataGrid.php
+++ b/framework/Web/UI/WebControls/TDataGrid.php
@@ -278,6 +278,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer
$style=new TTableStyle;
$style->setGridLines('Both');
$style->setCellSpacing(0);
+ $style->setBorderCollapse(true);
return $style;
}
diff --git a/framework/Web/UI/WebControls/TDataList.php b/framework/Web/UI/WebControls/TDataList.php
index 42c47f86..22bec07e 100644
--- a/framework/Web/UI/WebControls/TDataList.php
+++ b/framework/Web/UI/WebControls/TDataList.php
@@ -1357,7 +1357,7 @@ class TDataListItem extends TWebControl implements INamingContainer
/**
* Creates a style object for the control.
- * This method creates a {@link TTableStyle} to be used by checkbox list.
+ * This method creates a {@link TTableItemStyle} to be used by a datalist item.
* @return TStyle control style to be used
*/
protected function createStyle()
diff --git a/framework/Web/UI/WebControls/TDataTypeValidator.php b/framework/Web/UI/WebControls/TDataTypeValidator.php
index bd7569fc..3e91ec15 100644
--- a/framework/Web/UI/WebControls/TDataTypeValidator.php
+++ b/framework/Web/UI/WebControls/TDataTypeValidator.php
@@ -89,6 +89,9 @@ class TDataTypeValidator extends TBaseValidator
*/
protected function evaluateDataTypeCheck($value)
{
+ if($value=='')
+ return true;
+
switch($this->getDataType())
{
case 'Integer':
diff --git a/framework/Web/UI/WebControls/TDatePicker.php b/framework/Web/UI/WebControls/TDatePicker.php
index 42cb305e..001c7c46 100644
--- a/framework/Web/UI/WebControls/TDatePicker.php
+++ b/framework/Web/UI/WebControls/TDatePicker.php
@@ -296,7 +296,8 @@ class TDatePicker extends TTextBox
{
if($this->getText() === '')
return '';
- return $this->getTimeStamp();
+ $date = $this->getTimeStamp();
+ return $date == null ? '' : $date;
}
/**
diff --git a/framework/Web/UI/WebControls/TOutputCache.php b/framework/Web/UI/WebControls/TOutputCache.php
index 20c04f7c..ff07a6db 100644
--- a/framework/Web/UI/WebControls/TOutputCache.php
+++ b/framework/Web/UI/WebControls/TOutputCache.php
@@ -37,7 +37,7 @@
* to respond to the {@link onCheckDependency OnCheckDependency} event and set
* the event parameter's {@link TOutputCacheCheckDependencyEventParameter::getIsValid IsValid}
* property to indicate whether the cached data remains valid or not.
- * One can also extend TOutputCache and override its {@link getCacheDependency CacheDependency}
+ * One can also extend TOutputCache and override its {@link getCacheDependency}
* function. While the former is easier to use, the latter offers more extensibility.
*
* The content fetched from cache may be variated with respect to
diff --git a/framework/Web/UI/WebControls/TPanelStyle.php b/framework/Web/UI/WebControls/TPanelStyle.php
index 02f366b8..dc20806e 100644
--- a/framework/Web/UI/WebControls/TPanelStyle.php
+++ b/framework/Web/UI/WebControls/TPanelStyle.php
@@ -171,7 +171,7 @@ class TPanelStyle extends TStyle
/**
* Sets the style attributes to default values.
* This method overrides the parent implementation by
- * resetting additional TTableStyle specific attributes.
+ * resetting additional TPanelStyle specific attributes.
*/
public function reset()
{
diff --git a/framework/Web/UI/WebControls/TStyle.php b/framework/Web/UI/WebControls/TStyle.php
index 597229ea..d4cb6154 100644
--- a/framework/Web/UI/WebControls/TStyle.php
+++ b/framework/Web/UI/WebControls/TStyle.php
@@ -403,6 +403,10 @@ class TTableStyle extends TStyle
* @var string grid line setting of the table
*/
private $_gridLines=null;
+ /**
+ * @var boolean whether the table border should be collapsed
+ */
+ private $_borderCollapse=null;
/**
* Sets the style attributes to default values.
@@ -416,6 +420,7 @@ class TTableStyle extends TStyle
$this->_cellPadding=null;
$this->_cellSpacing=null;
$this->_gridLines=null;
+ $this->_borderCollapse=null;
}
/**
@@ -439,6 +444,8 @@ class TTableStyle extends TStyle
$this->_cellSpacing=$style->_cellSpacing;
if($style->_gridLines!==null)
$this->_gridLines=$style->_gridLines;
+ if($style->_borderCollapse!==null)
+ $this->_borderCollapse=$style->_borderCollapse;
}
}
@@ -463,6 +470,8 @@ class TTableStyle extends TStyle
$this->_cellSpacing=$style->_cellSpacing;
if($this->_gridLines===null && $style->_gridLines!==null)
$this->_gridLines=$style->_gridLines;
+ if($this->_borderCollapse===null && $style->_borderCollapse!==null)
+ $this->_borderCollapse=$style->_borderCollapse;
}
}
@@ -484,11 +493,10 @@ class TTableStyle extends TStyle
$writer->addAttribute('cellpadding',"$cellPadding");
if(($cellSpacing=$this->getCellSpacing())>=0)
- {
$writer->addAttribute('cellspacing',"$cellSpacing");
- if($this->getCellSpacing()===0)
- $writer->addStyleAttribute('border-collapse','collapse');
- }
+
+ if($this->getBorderCollapse())
+ $writer->addStyleAttribute('border-collapse','collapse');
switch($this->getGridLines())
{
@@ -588,6 +596,23 @@ class TTableStyle extends TStyle
{
$this->_gridLines=TPropertyValue::ensureEnum($value,array('None', 'Horizontal', 'Vertical', 'Both'));
}
+
+
+ /**
+ * @return boolean whether the table borders should be collapsed. Defaults to false.
+ */
+ public function getBorderCollapse()
+ {
+ return $this->_borderCollapse===null?false:$this->_borderCollapse;
+ }
+
+ /**
+ * @param boolean whether the table borders should be collapsed.
+ */
+ public function setBorderCollapse($value)
+ {
+ $this->_borderCollapse=TPropertyValue::ensureBoolean($value);
+ }
}
/**
diff --git a/framework/Web/UI/WebControls/TStyleSheet.php b/framework/Web/UI/WebControls/TStyleSheet.php
index 5925645c..3e172697 100644
--- a/framework/Web/UI/WebControls/TStyleSheet.php
+++ b/framework/Web/UI/WebControls/TStyleSheet.php
@@ -46,6 +46,22 @@ class TStyleSheet extends TControl
}
/**
+ * @return string media type of the CSS (such as 'print', 'screen', etc.). Defaults to empty, meaning the CSS applies to all media types.
+ */
+ public function getMediaType()
+ {
+ return $this->getViewState('MediaType','');
+ }
+
+ /**
+ * @param string media type of the CSS (such as 'print', 'screen', etc.). If empty, it means the CSS applies to all media types.
+ */
+ public function setMediaType($value)
+ {
+ $this->setViewState('MediaType',$value,'');
+ }
+
+ /**
* Registers the stylesheet file and content to be rendered.
* This method overrides the parent implementation and is invoked right before rendering.
* @param mixed event parameter
@@ -53,7 +69,7 @@ class TStyleSheet extends TControl
public function onPreRender($param)
{
if(($url=$this->getStyleSheetUrl())!=='')
- $this->getPage()->getClientScript()->registerStyleSheetFile($url,$url);
+ $this->getPage()->getClientScript()->registerStyleSheetFile($url,$url,$this->getMediaType());
}
/**
diff --git a/framework/Web/UI/WebControls/TWizard.php b/framework/Web/UI/WebControls/TWizard.php
index fa0fd92a..684ef5dc 100644
--- a/framework/Web/UI/WebControls/TWizard.php
+++ b/framework/Web/UI/WebControls/TWizard.php
@@ -715,9 +715,11 @@ class TWizard extends TWebControl implements INamingContainer
}
/**
+ * Returns the multiview that holds the wizard steps.
+ * This method should only be used by control developers.
* @return TMultiView the multiview holding wizard steps
*/
- protected function getMultiView()
+ public function getMultiView()
{
if($this->_multiView===null)
{
@@ -740,7 +742,6 @@ class TWizard extends TWebControl implements INamingContainer
if(($wizard=$step->getWizard())!==null)
$wizard->getWizardSteps()->remove($step);
$step->setWizard($this);
- $this->getMultiView()->getViews()->add($step);
$this->wizardStepsChanged();
}
@@ -752,7 +753,6 @@ class TWizard extends TWebControl implements INamingContainer
*/
public function removedWizardStep($step)
{
- $this->getMultiView()->getViews()->remove($step);
$step->setWizard(null);
$this->wizardStepsChanged();
}
@@ -1262,7 +1262,7 @@ class TWizard extends TWebControl implements INamingContainer
if($this->_sideBarDataList!==null)
{
$this->_sideBarDataList->setDataSource($this->getWizardSteps());
- $this->_sideBarDataList->setSelectedIndex($this->getActiveStepIndex());
+ $this->_sideBarDataList->setSelectedItemIndex($this->getActiveStepIndex());
$this->_sideBarDataList->dataBind();
}
}
@@ -1816,6 +1816,7 @@ class TWizardStepCollection extends TList
if($item instanceof TWizardStep)
{
parent::insertAt($index,$item);
+ $this->_wizard->getMultiView()->getViews()->insertAt($index,$item);
$this->_wizard->addedWizardStep($item);
}
else
@@ -1830,6 +1831,7 @@ class TWizardStepCollection extends TList
public function removeAt($index)
{
$step=parent::removeAt($index);
+ $this->_wizard->getMultiView()->getViews()->remove($step);
$this->_wizard->removedWizardStep($step);
return $step;
}
diff --git a/framework/prado-cli.php b/framework/prado-cli.php
index 1a0e5498..36739ad2 100755
--- a/framework/prado-cli.php
+++ b/framework/prado-cli.php
@@ -65,10 +65,6 @@ function create_new_prado_project($dir)
create_directory($runtimePath,0777);
create_directory($pagesPath,0755);
- create_directory($tests,0755);
- create_directory($unit_tests,0755);
- create_directory($functional_tests,0755);
-
create_file($indexFile, render_index_file());
create_file($htaccessFile, render_htaccess_file());
create_file($defaultPageFile, render_default_page());
diff --git a/tests/FunctionalTests/features/protected/pages/FocusControl.page b/tests/FunctionalTests/features/protected/pages/FocusControl.page
new file mode 100644
index 00000000..af414c3a
--- /dev/null
+++ b/tests/FunctionalTests/features/protected/pages/FocusControl.page
@@ -0,0 +1,46 @@
+<com:TContent ID="Content">
+
+<com:TRadioButtonList ID="list">
+ <com:TListItem Text="Button 1" />
+ <com:TListItem Text="Button 2" />
+ <com:TListItem Text="Button 3" Selected="true"/>
+ <com:TListItem Text="Button 4" />
+ <com:TListItem Text="Button 5" />
+</com:TRadioButtonList>
+
+<com:TButton Text="Focus" OnClick="doFocus" />
+
+<p style="height: 400px; background-color: #fc0; font-size: 10em">
+a
+<com:TButton ID="button1" Text="Button 1" />
+</p>
+
+<p style="height: 400px; background-color: #fcc; font-size: 10em">
+b
+<com:TButton ID="button2" Text="Button 2" />
+</p>
+
+<p style="height: 400px; background-color: #ccf; font-size: 10em">
+c
+<com:TButton ID="button3" Text="Button 3" />
+</p>
+
+<p style="height: 400px; background-color: #cf0; font-size: 10em">
+d
+</p>
+
+<p style="height: 400px; background-color: #ffc; font-size: 10em">
+e
+<com:TButton ID="button4" Text="Button 4" />
+</p>
+
+<p style="height: 400px; background-color: #f0f; font-size: 10em">
+f
+</p>
+
+<p style="height: 400px; background-color: #0cf; font-size: 10em">
+g
+<com:TButton ID="button5" Text="Button 5" />
+</p>
+
+</com:TContent> \ No newline at end of file
diff --git a/tests/FunctionalTests/features/protected/pages/FocusControl.php b/tests/FunctionalTests/features/protected/pages/FocusControl.php
new file mode 100644
index 00000000..d78f28c4
--- /dev/null
+++ b/tests/FunctionalTests/features/protected/pages/FocusControl.php
@@ -0,0 +1,17 @@
+<?php
+
+class FocusControl extends TPage
+{
+ function doFocus($sender, $param)
+ {
+ $selected = $this->list->SelectedIndex;
+ if($selected >= 0)
+ {
+ $id = "button".($selected+1);
+ $controlID = $this->{$id}->ClientID;
+ $this->ClientScript->registerFocusControl($controlID);
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket274.page b/tests/FunctionalTests/tickets/protected/pages/Ticket274.page
new file mode 100644
index 00000000..4e1441ed
--- /dev/null
+++ b/tests/FunctionalTests/tickets/protected/pages/Ticket274.page
@@ -0,0 +1,22 @@
+<com:TContent ID="Content">
+
+<com:TDatePicker ID="MyDate"
+ DateFormat="dd/MM/yyyy"
+ Mode="ImageButton" />
+ <com:TRequiredFieldValidator
+ ID="validator1"
+ ControlToValidate="MyDate"
+ EnableClientScript="false"
+ ErrorMessage="date required (dd/MM/yyyy)" />
+
+ <com:TDataTypeValidator
+ ID="validator2"
+ DataType="Date"
+ DateFormat="dd/MM/yyyy"
+ ControlToValidate="MyDate"
+ EnableClientScript="false"
+ ErrorMessage="date must be of the form dd/MM/yyyy" />
+
+ <com:TButton ID="button1" Text="Submit!" />
+
+</com:TContent> \ No newline at end of file
diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket278.page b/tests/FunctionalTests/tickets/protected/pages/Ticket278.page
new file mode 100644
index 00000000..75aed4d9
--- /dev/null
+++ b/tests/FunctionalTests/tickets/protected/pages/Ticket278.page
@@ -0,0 +1,42 @@
+<com:TContent ID="Content">
+
+ <com:TLabel ForControl="text1" Text="Text 1:" />
+ <com:TTextBox ID="text1" />
+ <com:TRequiredFieldValidator
+ ID="validator1"
+ ControlToValidate="text1"
+ ErrorMessage="Text 1 is required" />
+ <div>
+ <com:TCheckBox ID="check1" Text="More..." />
+ </div>
+
+ <com:TPanel ID="panel1" Style="display:none" >
+ <com:TLabel ForControl="text2" Text="Text 2:" />
+ <com:TTextBox ID="text2" />
+
+ <com:TRequiredFieldValidator
+ ID="validator2"
+ ControlToValidate="text2"
+ OnValidate="validator2_onValidate"
+ OnPreRender="validate2_onPostValidate"
+ ErrorMessage="Text 2 is required">
+ <prop:ClientSide.OnValidate>
+ validator.enabled = $("<%= $this->check1->ClientID %>").checked;
+ </prop:ClientSide.OnValidate>
+ </com:TRequiredFieldValidator>
+
+ </com:TPanel>
+
+ <com:TButton ID="button1" Text="Submit!" />
+
+ <com:TClientScript>
+ Event.OnLoad(function()
+ {
+ Event.observe("<%= $this->check1->ClientID %>", "click", function(ev)
+ {
+ $("<%= $this->panel1->ClientID %>").toggle();
+ });
+ });
+ </com:TClientScript>
+
+</com:TContent> \ No newline at end of file
diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket278.php b/tests/FunctionalTests/tickets/protected/pages/Ticket278.php
new file mode 100644
index 00000000..1aadee77
--- /dev/null
+++ b/tests/FunctionalTests/tickets/protected/pages/Ticket278.php
@@ -0,0 +1,23 @@
+<?php
+
+class Ticket278 extends TPage
+{
+ function validator2_onValidate($sender, $param)
+ {
+ $sender->Enabled = $this->check1->Checked;
+ }
+
+ function validate2_onPostValidate($sender, $param)
+ {
+ $sender->Enabled = true;
+ }
+
+ function onPreRender($param)
+ {
+ parent::onPreRender($param);
+ $this->panel1->Style =
+ $this->check1->Checked ? "display:block" : "display:none";
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/tickets/tests/Ticket274TestCase.php b/tests/FunctionalTests/tickets/tests/Ticket274TestCase.php
new file mode 100644
index 00000000..ae976a7f
--- /dev/null
+++ b/tests/FunctionalTests/tickets/tests/Ticket274TestCase.php
@@ -0,0 +1,24 @@
+<?php
+
+class Ticket274TestCase extends SeleniumTestCase
+{
+ function test()
+ {
+ $base = 'ctl0_Content_';
+ $this->open('tickets/index.php?page=Ticket274');
+ $this->assertTitle('Verifying Ticket 274');
+ $this->assertNotVisible($base.'validator1');
+ $this->assertNotVisible($base.'validator2');
+
+ $this->click($base.'button1');
+ $this->assertVisible($base.'validator1');
+ $this->assertNotVisible($base.'validator2');
+
+ $this->type($base.'MyDate', 'asd');
+ $this->click($base.'button1');
+ $this->assertVisible($base.'validator1');
+ $this->assertNotVisible($base.'validator2');
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/tickets/tests/Ticket278TestCase.php b/tests/FunctionalTests/tickets/tests/Ticket278TestCase.php
new file mode 100644
index 00000000..bd631c14
--- /dev/null
+++ b/tests/FunctionalTests/tickets/tests/Ticket278TestCase.php
@@ -0,0 +1,54 @@
+<?php
+
+class Ticket278TestCase extends SeleniumTestCase
+{
+ function test()
+ {
+ $base = 'ctl0_Content_';
+ $this->open('tickets/index.php?page=Ticket278');
+ $this->assertTitle('Verifying Ticket 278');
+ $this->assertNotVisible($base.'validator1');
+ $this->assertNotVisible($base.'validator2');
+ $this->assertNotVisible($base.'panel1');
+
+ $this->click($base.'button1');
+ $this->assertVisible($base.'validator1');
+ $this->assertNotVisible($base.'validator2');
+
+ $this->type($base.'text1', 'asd');
+ $this->clickAndWait($base.'button1');
+ $this->assertNotVisible($base.'validator1');
+ $this->assertNotVisible($base.'validator2');
+ $this->assertNotVisible($base.'panel1');
+
+ $this->click($base.'check1');
+ $this->click($base.'button1');
+ $this->assertNotVisible($base.'validator1');
+ $this->assertVisible($base.'validator2');
+ $this->assertVisible($base.'panel1');
+
+
+ $this->type($base.'text1', '');
+ $this->type($base.'text2', 'asd');
+ $this->click($base.'button1');
+ $this->assertVisible($base.'validator1');
+ $this->assertNotVisible($base.'validator2');
+ $this->assertVisible($base.'panel1');
+
+
+ $this->type($base.'text1', 'asd');
+ $this->clickAndWait($base.'button1');
+ $this->assertNotVisible($base.'validator1');
+ $this->assertNotVisible($base.'validator2');
+ $this->assertVisible($base.'panel1');
+
+ $this->type($base.'text1', '');
+ $this->type($base.'text2', '');
+ $this->click($base.'button1');
+ $this->assertVisible($base.'validator1');
+ $this->assertVisible($base.'validator2');
+ $this->assertVisible($base.'panel1');
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/validators/tests/DataTypeValidatorTestCase.php b/tests/FunctionalTests/validators/tests/DataTypeValidatorTestCase.php
index 1ca3de5d..153be373 100644
--- a/tests/FunctionalTests/validators/tests/DataTypeValidatorTestCase.php
+++ b/tests/FunctionalTests/validators/tests/DataTypeValidatorTestCase.php
@@ -10,7 +10,7 @@ class DataTypeValidatorTestCase extends SeleniumTestCase
$base = "ctl0_Content_";
$this->open("validators/index.php?page=DataTypeValidator", "");
$this->verifyTextPresent("Data Type Validator Tests", "");
- $this->clickAndWait("//input[@type='submit' and @value='submit!']", "");
+ $this->click("//input[@type='submit' and @value='submit!']", "");
$this->assertNotVisible("{$base}validator1");
$this->assertNotVisible("{$base}validator2");