From 66e71b1d5ff97e04311f8b761cc040b1188437d3 Mon Sep 17 00:00:00 2001 From: wei <> Date: Tue, 13 Dec 2005 01:42:19 +0000 Subject: Adding client side javascript validators. --- framework/Web/UI/TClientScriptManager.php | 1092 +++++++++++++---------- framework/Web/UI/WebControls/TBaseValidator.php | 654 +++++++------- 2 files changed, 989 insertions(+), 757 deletions(-) (limited to 'framework/Web/UI') diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php index cc5289c5..ca28751f 100644 --- a/framework/Web/UI/TClientScriptManager.php +++ b/framework/Web/UI/TClientScriptManager.php @@ -1,457 +1,637 @@ -_actionUrl; - } - - public function setActionUrl($value) - { - $this->_actionUrl=THttpUtility::quoteJavaScriptString($value); - } - - public function getAutoPostBack() - { - return $this->_autoPostBack; - } - - public function setAutoPostBack($value) - { - $this->_autoPostBack=$value; - } - - public function getClientSubmit() - { - return $this->_clientSubmit; - } - - public function setClientSubmit($value) - { - $this->_clientSubmit=$value; - } - - public function getPerformValidation() - { - return $this->_performValidation; - } - - public function setPerformValidation($value) - { - $this->_performValidation=$value; - } - - public function getValidationGroup() - { - return $this->_validationGroup; - } - - public function setValidationGroup($value) - { - $this->_validationGroup=$value; - } - - public function getTrackFocus() - { - return $this->_trackFocus; - } - - public function setTrackFocus($value) - { - $this->_trackFocus=$value; - } -} - -class TClientScriptManager extends TComponent -{ - const SCRIPT_DIR='Web/Javascripts/js'; - const POSTBACK_FUNC='Prado.doPostBack'; - private $_page; - private $_hiddenFields=array(); - private $_beginScripts=array(); - private $_endScripts=array(); - private $_scriptFiles=array(); - private $_headScriptFiles=array(); - private $_headScripts=array(); - private $_styleSheetFiles=array(); - private $_styleSheets=array(); - private $_onSubmitStatements=array(); - private $_arrayDeclares=array(); - private $_expandoAttributes=array(); - private $_postBackScriptRegistered=false; - private $_focusScriptRegistered=false; - private $_scrollScriptRegistered=false; - private $_publishedScriptFiles=array(); - - public function __construct(TPage $owner) - { - $this->_page=$owner; - } - - public function getPostBackEventReference($control,$parameter='',$options=null,$javascriptPrefix=true) - { - if(!$options || (!$options->getPerformValidation() && !$options->getTrackFocus() && $options->getClientSubmit() && $options->getActionUrl()=='')) - { - $this->registerPostBackScript(); - if(($form=$this->_page->getForm())!==null) - $formID=$form->getClientID(); - else - throw new TInvalidConfigurationException('clientscriptmanager_form_required'); - $postback=self::POSTBACK_FUNC.'(\''.$formID.'\',\''.$control->getUniqueID().'\',\''.THttpUtility::quoteJavaScriptString($parameter).'\')'; - if($options && $options->getAutoPostBack()) - $postback='setTimeout(\''.THttpUtility::quoteJavaScriptString($postback).'\',0)'; - return $javascriptPrefix?'javascript:'.$postback:$postback; - } - $opt=''; - $flag=false; - if($options->getPerformValidation()) - { - $flag=true; - $this->registerValidationScript(); - $opt.=',true,'; - } - else - $opt.=',false,'; - if($options->getValidationGroup()!=='') - { - $flag=true; - $opt.='"'.$options->getValidationGroup().'",'; - } - else - $opt.='\'\','; - if($options->getActionUrl()!=='') - { - $flag=true; - $this->_page->setCrossPagePostBack(true); - $opt.='"'.$options->getActionUrl().'",'; - } - else - $opt.='null,'; - if($options->getTrackFocus()) - { - $flag=true; - $this->registerFocusScript(); - $opt.='true,'; - } - else - $opt.='false,'; - if($options->getClientSubmit()) - { - $flag=true; - $opt.='true'; - } - else - $opt.='false'; - if(!$flag) - return ''; - $this->registerPostBackScript(); - if(($form=$this->_page->getForm())!==null) - $formID=$form->getClientID(); - else - throw new TInvalidConfigurationException('clientscriptmanager_form_required'); - $postback=self::POSTBACK_FUNC.'(\''.$formID.'\',\''.$control->getUniqueID().'\',\''.THttpUtility::quoteJavaScriptString($parameter).'\''.$opt.')'; - if($options && $options->getAutoPostBack()) - $postback='setTimeout(\''.THttpUtility::quoteJavaScriptString($postback).'\',0)'; - return $javascriptPrefix?'javascript:'.$postback:$postback; - } - - public function registerPradoScript($scriptFile) - { - if(isset($this->_publishedScriptFiles[$scriptFile])) - $url=$this->_publishedScriptFiles[$scriptFile]; - else - { - $url=$this->_page->getService()->getAssetManager()->publishFilePath(Prado::getFrameworkPath().'/'.self::SCRIPT_DIR.'/'.$scriptFile); - $this->_publishedScriptFiles[$scriptFile]=$url; - $this->registerScriptFile('prado:'.$scriptFile,$url); - } - return $url; - } - - protected function registerPostBackScript() - { - if(!$this->_postBackScriptRegistered) - { - $this->_postBackScriptRegistered=true; - $this->registerHiddenField(TPage::FIELD_POSTBACK_TARGET,''); - $this->registerHiddenField(TPage::FIELD_POSTBACK_PARAMETER,''); - $this->registerPradoScript('base.js'); - } - } - - public function registerFocusScript($target) - { - if(!$this->_focusScriptRegistered) - { - $this->_focusScriptRegistered=true; - $this->registerPradoScript('base.js'); - $this->registerEndScript('prado:focus','Prado.Focus.setFocus("'.THttpUtility::quoteJavaScriptString($target).'");'); - } - } - - public function registerScrollScript($x,$y) - { - if(!$this->_scrollScriptRegistered) - { - $this->_scrollScriptRegistered=true; - $this->registerHiddenField(TPage::FIELD_SCROLL_X,$x); - $this->registerHiddenField(TPage::FIELD_SCROLL_Y,$y); - // TBD, need scroll.js - } - } - - public function registerDefaultButtonScript($button) - { - $this->registerPradoScript('base.js'); - return 'return Prado.Button.fireButton(event,\''.$button->getClientID().'\')'; - } - - public function registerValidationScript() - { - } - - public function isHiddenFieldRegistered($key) - { - return isset($this->_hiddenFields[$key]); - } - - public function isScriptRegistered($key) - { - return isset($this->_scripts[$key]); - } - - public function isScriptFileRegistered($key) - { - return isset($this->_scriptFiles[$key]); - } - - public function isBeginScriptRegistered($key) - { - return isset($this->_beginScripts[$key]); - } - - public function isEndScriptRegistered($key) - { - return isset($this->_endScripts[$key]); - } - - public function isHeadScriptFileRegistered($key) - { - return isset($this->_headScriptFiles[$key]); - } - - public function isHeadScriptRegistered($key) - { - return isset($this->_headScripts[$key]); - } - - public function isStyleSheetFileRegistered($key) - { - return isset($this->_styleSheetFiles[$key]); - } - - public function isStyleSheetRegistered($key) - { - return isset($this->_styleSheets[$key]); - } - - public function isOnSubmitStatementRegistered($key) - { - return isset($this->_onSubmitStatements[$key]); - } - - public function registerArrayDeclaration($name,$value) - { - $this->_arrayDeclares[$name][]=$value; - } - - public function registerScriptFile($key,$url) - { - $this->_scriptFiles[$key]=$url; - } - - public function registerHiddenField($name,$value) - { - // if the named hidden field exists and has a value null, it means the hidden field is rendered already - if(!isset($this->_hiddenFields[$name]) || $this->_hiddenFields[$name]!==null) - $this->_hiddenFields[$name]=$value; - } - - public function registerOnSubmitStatement($key,$script) - { - $this->_onSubmitStatements[$key]=$script; - } - - public function registerBeginScript($key,$script) - { - $this->_beginScripts[$key]=$script; - } - - public function registerEndScript($key,$script) - { - $this->_endScripts[$key]=$script; - } - - public function registerHeadScriptFile($key,$url) - { - $this->_headScriptFiles[$key]=$url; - } - - public function registerHeadScript($key,$script) - { - $this->_headScripts[$key]=$script; - } - - public function registerStyleSheetFile($key,$url) - { - $this->_styleSheetFiles[$key]=$url; - } - - public function registerStyleSheet($key,$css) - { - $this->_styleSheets[$key]=$css; - } - - public function registerExpandoAttribute($controlID,$name,$value) - { - $this->_expandoAttributes[$controlID][$name]=$value; - } - - public function renderArrayDeclarations($writer) - { - if(count($this->_arrayDeclares)) - { - $str="\n"; - $writer->write($str); - } - } - - public function renderScriptFiles($writer) - { - $str=''; - foreach($this->_scriptFiles as $include) - $str.="\n"; - $writer->write($str); - } - - public function renderOnSubmitStatements($writer) - { - // ??? - } - - public function renderBeginScripts($writer) - { - if(count($this->_beginScripts)) - $writer->write("\n"); - } - - public function renderEndScripts($writer) - { - if(count($this->_endScripts)) - $writer->write("\n"); - } - - public function renderHiddenFields($writer) - { - $str=''; - foreach($this->_hiddenFields as $name=>$value) - { - if($value!==null) - { - $value=THttpUtility::htmlEncode($value); - $str.="\n"; - // set hidden field value to null to indicate this field is rendered - // Note, hidden field rendering is invoked twice (at the beginning and ending of TForm) - $this->_hiddenFields[$name]=null; - } - } - if($str!=='') - $writer->write("
\n".$str."
\n"); - } - - public function renderExpandoAttributes($writer) - { - if(count($this->_expandoAttributes)) - { - $str="\n"; - $writer->write($str); - } - } - - public function renderHeadScriptFiles($writer) - { - $str=''; - foreach($this->_headScriptFiles as $url) - $str.="\n"; - $writer->write($str); - } - - public function renderHeadScripts($writer) - { - if(count($this->_headScripts)) - $writer->write("\n"); - } - - public function renderStyleSheetFiles($writer) - { - $str=''; - foreach($this->_styleSheetFiles as $url) - { - $str.="\n"; - } - $writer->write($str); - } - - public function renderStyleSheets($writer) - { - if(count($this->_styleSheets)) - $writer->write("\n"); - } - - public function getHasHiddenFields() - { - return count($this->_hiddenFields)>0; - } - - public function getHasSubmitStatements() - { - return count($this->_onSubmitStatements)>0; - } - - - /* - private void EnsureEventValidationFieldLoaded(); - internal string GetEventValidationFieldValue(); - public string GetWebResourceUrl(Type type, string resourceName); - public void RegisterClientScriptResource(Type type, string resourceName); - internal void RegisterDefaultButtonScript(Control button, $writer, bool useAddAttribute); - public function SaveEventValidationField(); - public void ValidateEvent(string uniqueId, string argument); - public function getCallbackEventReference() - */ -} - +_actionUrl; + } + + public function setActionUrl($value) + { + $this->_actionUrl=THttpUtility::quoteJavaScriptString($value); + } + + public function getAutoPostBack() + { + return $this->_autoPostBack; + } + + public function setAutoPostBack($value) + { + $this->_autoPostBack=$value; + } + + public function getClientSubmit() + { + return $this->_clientSubmit; + } + + public function setClientSubmit($value) + { + $this->_clientSubmit=$value; + } + + public function getPerformValidation() + { + return $this->_performValidation; + } + + public function setPerformValidation($value) + { + $this->_performValidation=$value; + } + + public function getValidationGroup() + { + return $this->_validationGroup; + } + + public function setValidationGroup($value) + { + $this->_validationGroup=$value; + } + + public function getTrackFocus() + { + return $this->_trackFocus; + } + + public function setTrackFocus($value) + { + $this->_trackFocus=$value; + } +} + +class TClientScriptManager extends TComponent +{ + const SCRIPT_DIR='Web/Javascripts/js'; + const POSTBACK_FUNC='Prado.doPostBack'; + private $_page; + private $_hiddenFields=array(); + private $_beginScripts=array(); + private $_endScripts=array(); + private $_scriptFiles=array(); + private $_headScriptFiles=array(); + private $_headScripts=array(); + private $_styleSheetFiles=array(); + private $_styleSheets=array(); + private $_onSubmitStatements=array(); + private $_arrayDeclares=array(); + private $_expandoAttributes=array(); + private $_postBackScriptRegistered=false; + private $_focusScriptRegistered=false; + private $_scrollScriptRegistered=false; + private $_publishedScriptFiles=array(); + + public function __construct(TPage $owner) + { + $this->_page=$owner; + } + + public function getPostBackEventReference($control,$parameter='',$options=null,$javascriptPrefix=true) + { + if(!$options || (!$options->getPerformValidation() && !$options->getTrackFocus() && $options->getClientSubmit() && $options->getActionUrl()=='')) + { + $this->registerPostBackScript(); + if(($form=$this->_page->getForm())!==null) + $formID=$form->getClientID(); + else + throw new TInvalidConfigurationException('clientscriptmanager_form_required'); + $postback=self::POSTBACK_FUNC.'(\''.$formID.'\',\''.$control->getUniqueID().'\',\''.THttpUtility::quoteJavaScriptString($parameter).'\')'; + if($options && $options->getAutoPostBack()) + $postback='setTimeout(\''.THttpUtility::quoteJavaScriptString($postback).'\',0)'; + return $javascriptPrefix?'javascript:'.$postback:$postback; + } + $opt=''; + $flag=false; + if($options->getPerformValidation()) + { + $flag=true; + $this->registerValidationScript(); + $opt.=',true,'; + } + else + $opt.=',false,'; + if($options->getValidationGroup()!=='') + { + $flag=true; + $opt.='"'.$options->getValidationGroup().'",'; + } + else + $opt.='\'\','; + if($options->getActionUrl()!=='') + { + $flag=true; + $this->_page->setCrossPagePostBack(true); + $opt.='"'.$options->getActionUrl().'",'; + } + else + $opt.='null,'; + if($options->getTrackFocus()) + { + $flag=true; + $this->registerFocusScript(); + $opt.='true,'; + } + else + $opt.='false,'; + if($options->getClientSubmit()) + { + $flag=true; + $opt.='true'; + } + else + $opt.='false'; + if(!$flag) + return ''; + $this->registerPostBackScript(); + if(($form=$this->_page->getForm())!==null) + $formID=$form->getClientID(); + else + throw new TInvalidConfigurationException('clientscriptmanager_form_required'); + $postback=self::POSTBACK_FUNC.'(\''.$formID.'\',\''.$control->getUniqueID().'\',\''.THttpUtility::quoteJavaScriptString($parameter).'\''.$opt.')'; + if($options && $options->getAutoPostBack()) + $postback='setTimeout(\''.THttpUtility::quoteJavaScriptString($postback).'\',0)'; + return $javascriptPrefix?'javascript:'.$postback:$postback; + } + + public function registerPradoScript($script) + { + foreach(TPradoClientScript::getScript($script) as $scriptFile) + { + if(isset($this->_publishedScriptFiles[$scriptFile])) + $url=$this->_publishedScriptFiles[$scriptFile]; + else + { + $url=$this->_page->getService()->getAssetManager()->publishFilePath(Prado::getFrameworkPath().'/'.self::SCRIPT_DIR.'/'.$scriptFile); + $this->_publishedScriptFiles[$scriptFile]=$url; + $this->registerScriptFile('prado:'.$scriptFile,$url); + } + } + //return $url; + } + + protected function registerPostBackScript() + { + if(!$this->_postBackScriptRegistered) + { + $this->_postBackScriptRegistered=true; + $this->registerHiddenField(TPage::FIELD_POSTBACK_TARGET,''); + $this->registerHiddenField(TPage::FIELD_POSTBACK_PARAMETER,''); + $this->registerPradoScript('base'); + } + } + + public function registerFocusScript($target) + { + if(!$this->_focusScriptRegistered) + { + $this->_focusScriptRegistered=true; + $this->registerPradoScript('base'); + $this->registerEndScript('prado:focus','Prado.Focus.setFocus("'.THttpUtility::quoteJavaScriptString($target).'");'); + } + } + + public function registerScrollScript($x,$y) + { + if(!$this->_scrollScriptRegistered) + { + $this->_scrollScriptRegistered=true; + $this->registerHiddenField(TPage::FIELD_SCROLL_X,$x); + $this->registerHiddenField(TPage::FIELD_SCROLL_Y,$y); + // TBD, need scroll.js + } + } + + public function registerDefaultButtonScript($button) + { + $this->registerPradoScript('base'); + return 'return Prado.Button.fireButton(event,\''.$button->getClientID().'\')'; + } + + public function registerValidationScript() + { + } + + public function isHiddenFieldRegistered($key) + { + return isset($this->_hiddenFields[$key]); + } + + public function isScriptRegistered($key) + { + return isset($this->_scripts[$key]); + } + + public function isScriptFileRegistered($key) + { + return isset($this->_scriptFiles[$key]); + } + + public function isBeginScriptRegistered($key) + { + return isset($this->_beginScripts[$key]); + } + + public function isEndScriptRegistered($key) + { + return isset($this->_endScripts[$key]); + } + + public function isHeadScriptFileRegistered($key) + { + return isset($this->_headScriptFiles[$key]); + } + + public function isHeadScriptRegistered($key) + { + return isset($this->_headScripts[$key]); + } + + public function isStyleSheetFileRegistered($key) + { + return isset($this->_styleSheetFiles[$key]); + } + + public function isStyleSheetRegistered($key) + { + return isset($this->_styleSheets[$key]); + } + + public function isOnSubmitStatementRegistered($key) + { + return isset($this->_onSubmitStatements[$key]); + } + + public function registerArrayDeclaration($name,$value) + { + $this->_arrayDeclares[$name][]=$value; + } + + public function registerScriptFile($key,$url) + { + $this->_scriptFiles[$key]=$url; + } + + public function registerHiddenField($name,$value) + { + // if the named hidden field exists and has a value null, it means the hidden field is rendered already + if(!isset($this->_hiddenFields[$name]) || $this->_hiddenFields[$name]!==null) + $this->_hiddenFields[$name]=$value; + } + + public function registerOnSubmitStatement($key,$script) + { + $this->_onSubmitStatements[$key]=$script; + } + + public function registerBeginScript($key,$script) + { + $this->_beginScripts[$key]=$script; + } + + public function registerEndScript($key,$script) + { + $this->_endScripts[$key]=$script; + } + + public function registerHeadScriptFile($key,$url) + { + $this->_headScriptFiles[$key]=$url; + } + + public function registerHeadScript($key,$script) + { + $this->_headScripts[$key]=$script; + } + + public function registerStyleSheetFile($key,$url) + { + $this->_styleSheetFiles[$key]=$url; + } + + public function registerStyleSheet($key,$css) + { + $this->_styleSheets[$key]=$css; + } + + public function registerExpandoAttribute($controlID,$name,$value) + { + $this->_expandoAttributes[$controlID][$name]=$value; + } + + public function renderArrayDeclarations($writer) + { + if(count($this->_arrayDeclares)) + { + $str="\n"; + $writer->write($str); + } + } + + public function renderScriptFiles($writer) + { + $str=''; + foreach($this->_scriptFiles as $include) + $str.="\n"; + $writer->write($str); + } + + public function renderOnSubmitStatements($writer) + { + // ??? + } + + public function renderBeginScripts($writer) + { + if(count($this->_beginScripts)) + $writer->write("\n"); + } + + public function renderEndScripts($writer) + { + if(count($this->_endScripts)) + $writer->write("\n"); + } + + public function renderHiddenFields($writer) + { + $str=''; + foreach($this->_hiddenFields as $name=>$value) + { + if($value!==null) + { + $value=THttpUtility::htmlEncode($value); + $str.="\n"; + // set hidden field value to null to indicate this field is rendered + // Note, hidden field rendering is invoked twice (at the beginning and ending of TForm) + $this->_hiddenFields[$name]=null; + } + } + if($str!=='') + $writer->write("
\n".$str."
\n"); + } + + public function renderExpandoAttributes($writer) + { + if(count($this->_expandoAttributes)) + { + $str="\n"; + $writer->write($str); + } + } + + public function renderHeadScriptFiles($writer) + { + $str=''; + foreach($this->_headScriptFiles as $url) + $str.="\n"; + $writer->write($str); + } + + public function renderHeadScripts($writer) + { + if(count($this->_headScripts)) + $writer->write("\n"); + } + + public function renderStyleSheetFiles($writer) + { + $str=''; + foreach($this->_styleSheetFiles as $url) + { + $str.="\n"; + } + $writer->write($str); + } + + public function renderStyleSheets($writer) + { + if(count($this->_styleSheets)) + $writer->write("\n"); + } + + public function getHasHiddenFields() + { + return count($this->_hiddenFields)>0; + } + + public function getHasSubmitStatements() + { + return count($this->_onSubmitStatements)>0; + } + + + /* + private void EnsureEventValidationFieldLoaded(); + internal string GetEventValidationFieldValue(); + public string GetWebResourceUrl(Type type, string resourceName); + public void RegisterClientScriptResource(Type type, string resourceName); + internal void RegisterDefaultButtonScript(Control button, $writer, bool useAddAttribute); + public function SaveEventValidationField(); + public void ValidateEvent(string uniqueId, string argument); + public function getCallbackEventReference() + */ +} + +/** + * TJavascript class file. Javascript utilties, converts basic PHP types into + * appropriate javascript types. + * + * Example: + * + * $options['onLoading'] = "doit"; + * $options['onComplete'] = "more"; + * $js = TJavascript::toList($options); + * //expects the following javascript code + * // {'onLoading':'doit','onComplete':'more'} + * + * + * Namespace: System.Web.UI + * + * @author Wei Zhuo + * @version $Revision: 1.3 $ $Date: 2005/11/10 23:43:26 $ + * @package System.Web.UI + */ +class TJavascript +{ + /** + * Coverts PHP arrays (only the array values) into javascript array. + * @param array the array data to convert + * @param string append additional javascript array data + * @param boolean if true empty string and empty array will be converted + * @return string javascript array as string. + */ + public static function toArray($array,$append=null,$strict=false) + { + $results = array(); + $converter = new TJavascript(); + foreach($array as $v) + { + if($strict || (!$strict && $v !== '' && $v !== array())) + { + $type = 'to_'.gettype($v); + if($type == 'to_array') + $results[] = $converter->toArray($v, $append, $strict); + else + $results[] = $converter->{$type}($v); + } + } + $extra = ''; + if(strlen($append) > 0) + $extra .= count($results) > 0 ? ','.$append : $append; + return '['.implode(',', $results).$extra.']'; + } + + /** + * Coverts PHP arrays (both key and value) into javascript objects. + * @param array the array data to convert + * @param string append additional javascript object data + * @param boolean if true empty string and empty array will be converted + * @return string javascript object as string. + */ + public static function toList($array,$append=null, $strict=false) + { + $results = array(); + $converter = new TJavascript(); + foreach($array as $k => $v) + { + if($strict || (!$strict && $v !== '' && $v !== array())) + { + $type = 'to_'.gettype($v); + if($type == 'to_array') + $results[] = "'{$k}':".$converter->toList($v, $append, $strict); + else + $results[] = "'{$k}':".$converter->{$type}($v); + } + } + $extra = ''; + if(strlen($append) > 0) + $extra .= count($results) > 0 ? ','.$append : $append; + + return '{'.implode(',', $results).$extra.'}'; + } + + public function to_boolean($v) + { + return $v ? 'true' : 'false'; + } + + public function to_integer($v) + { + return "{$v}"; + } + + public function to_double($v) + { + return "{$v}"; + } + + /** + * If string begins with [ and ends ], or begins with { and ends } + * it is assumed to be javascript arrays or objects and no further + * conversion is applied. + */ + public function to_string($v) + { + if(strlen($v)>1) + { + $first = $v{0}; $last = $v{strlen($v)-1}; + if($first == '[' && $last == ']' || + ($first == '{' && $last == '}')) + return $v; + } + return "'".addslashes($v)."'"; + } + + public function to_array($v) + { + return TJavascript::toArray($v); + } + + public function to_null($v) + { + return 'null'; + } +} + +/** + * PradoClientScript class. + * + * Resolves Prado client script dependencies. e.g. TPradoClientScript::getScripts("dom"); + * + * - base basic javascript utilities, e.g. $() + * - dom DOM and Form functions, e.g. $F(inputID) to retrive form input values. + * - effects Effects such as fade, shake, move + * - controls Prado client-side components, e.g. Slider, AJAX components + * - validator Prado client-side validators. + * - ajax Prado AJAX library including Prototype's AJAX and JSON. + * + * Dependencies for each library are automatically resolved. + * + * Namespace: System.Web.UI + * + * @author Wei Zhuo + * @version $Revision: 1.1 $ $Date: 2005/11/06 23:02:33 $ + * @package System.Web.UI + */ +class TPradoClientScript +{ + /** + * Client-side javascript library dependencies + * @var array + */ + protected static $dependencies = array( + 'base' => array('base'), + 'dom' => array('base', 'dom'), + 'effects' => array('base', 'dom', 'effects'), + 'controls' => array('base', 'dom', 'effects', 'controls'), + 'validator' => array('base', 'dom', 'validator'), + 'logger' => array('base', 'dom', 'logger'), + 'ajax' => array('base', 'dom', 'ajax') + ); + + /** + * Resolve dependencies for the given library. + * @param array list of libraries to load. + * @return array list of libraries including its dependencies. + */ + protected static function getScripts($scripts) + { + $files = array(); + if(!is_array($scripts)) $scripts = array($scripts); + foreach($scripts as $script) + { + if(isset(self::$dependencies[$script])) + $files = array_merge($files, self::$dependencies[$script]); + $files[] = $script; + } + $files = array_unique($files); + return $files; + } +} + ?> \ No newline at end of file diff --git a/framework/Web/UI/WebControls/TBaseValidator.php b/framework/Web/UI/WebControls/TBaseValidator.php index f4627986..ab314087 100644 --- a/framework/Web/UI/WebControls/TBaseValidator.php +++ b/framework/Web/UI/WebControls/TBaseValidator.php @@ -1,302 +1,354 @@ - - * @link http://www.pradosoft.com/ - * @copyright Copyright © 2005 PradoSoft - * @license http://www.pradosoft.com/license/ - * @version $Revision: $ $Date: $ - * @package System.Web.UI.WebControls - */ - -/** - * TBaseValidator class - * - * TBaseValidator serves as the base class for validator controls. - * - * Validation is performed when a button control, such a TButton, a TLinkButton - * or a TImageButton is clicked and the CausesValidation of these controls is true. - * You can also manually perform validation by using the validate() method of the TPage class. - * - * Validator controls always validate the associated input control on the server. - * TValidation controls also have complete client-side implementation that allow - * DHTML supported browsers to perform validation on the client via Javascript. - * Client-side validation will validate user input before it is sent to the server. - * The form data will not be submitted if any error is detected. This avoids - * the round-trip of information necessary for server-side validation. - * - * You can use multiple validator controls to validate an individual input control, - * each responsible for validating different criteria. For example, on a user registration - * form, you may want to make sure the user enters a value in the username text box, - * and the input must consist of only word characters. You can use a TRequiredFieldValidator - * to ensure the input of username and a TRegularExpressionValidator to ensure the proper - * input. - * - * If an input control fails validation, the text specified by the ErrorMessage - * property is displayed in the validation control. If the Text property is set - * it will be displayed instead, however. If both ErrorMessage and Text - * are empty, the body content of the validator will be displayed. - * - * You can also place a TValidationSummary control on the page to display error messages - * from the validators together. In this case, only the ErrorMessage property of the - * validators will be displayed in the TValidationSummary control. - * - * Note, the IsValid property of the current TPage instance will be automatically - * updated by the validation process which occurs after OnLoad of TPage and - * before the postback events. Therefore, if you use the IsValid - * property in the OnLoad event of TPage, you must first explicitly call - * the validate() method of TPage. As an alternative, you can place your code - * in the postback event handler, such as OnClick or OnCommand, - * instead of OnLoad event. - * - * Note, to use validators derived from this control, you have to - * copy the file "/js/prado_validator.js" to the "js" directory - * which should be under the directory containing the entry script file. - * - * Notes to Inheritors When you inherit from the TBaseValidator class, - * you must override the method {@link evaluateIsValid}. - * - * Namespace: System.Web.UI.WebControls - * - * Properties - * - EnableClientScript, boolean, default=true, kept in viewstate - *
Gets or sets a value indicating whether client-side validation is enabled. - * - Display, string, default=Static, kept in viewstate - *
Gets or sets the display behavior (None, Static, Dynamic) of the error message in a validation control. - * - ControlToValidate, string, kept in viewstate - *
Gets or sets the input control to validate. This property must be set to - * the ID path of an input control. The ID path is the dot-connected IDs of - * the controls reaching from the validator's parent control to the target control. - * For example, if HomePage is the parent of Validator and SideBar controls, and - * SideBar is the parent of UserName control, then the ID path for UserName - * would be "SideBar.UserName" if UserName is to be validated by Validator. - * - Text, string, kept in viewstate - *
Gets or sets the text of TBaseValidator control. - * - ErrorMessage, string, kept in viewstate - *
Gets or sets the text for the error message. - * - EncodeText, boolean, default=true, kept in viewstate - *
Gets or sets the value indicating whether Text and ErrorMessage should be HTML-encoded when rendering. - * - IsValid, boolean, default=true - *
Gets or sets a value that indicates whether the associated input control passes validation. - * - * @author Qiang Xue - * @version $Revision: $ $Date: $ - * @package System.Web.UI.WebControls - * @since 3.0 - */ -abstract class TBaseValidator extends TLabel implements IValidator -{ - /** - * whether the validation succeeds - * @var boolean - */ - private $_isValid=true; - - public function __construct() - { - parent::__construct(); - $this->setForeColor('red'); - } - - /** - * Adds attributes to renderer. - * @param THtmlWriter the renderer - */ - protected function addAttributesToRender($writer) - { - } - - /** - * This method overrides the parent implementation to forbid setting AssociatedControlID. - * @param string the associated control ID - * @throws TNotSupportedException whenever this method is called - */ - public function setAssociatedControlID($value) - { - throw new TNotSupportedException('basevalidator_associatedcontrolid_unsupported',get_class($this)); - } - - /** - * This method overrides parent's implementation by setting {@link setIsValid IsValid} to true if disabled. - * @param boolean whether the validator is enabled. - */ - public function setEnabled($value) - { - $value=TPropertyValue::ensureBoolean($value); - parent::setEnabled($value); - if(!$value) - $this->_isValid=true; - } - - /** - * @return string the display behavior (None, Static, Dynamic) of the error message in a validation control. Defaults to Static. - */ - public function getDisplay() - { - return $this->getViewState('Display','Static'); - } - - /** - * Sets the display behavior (None, Static, Dynamic) of the error message in a validation control. - * @param string the display behavior (None, Static, Dynamic) - */ - public function setDisplay($value) - { - $this->setViewState('Display',TPropertyValue::ensureEnum($value,array('None','Static','Dynamic')),'Static'); - } - - /** - * @return boolean whether client-side validation is enabled. - */ - public function getEnableClientScript() - { - return $this->getViewState('EnableClientScript',true); - } - - /** - * Sets the value indicating whether client-side validation is enabled. - * @param boolean whether client-side validation is enabled. - */ - public function setEnableClientScript($value) - { - $this->setViewState('EnableClientScript',TPropertyValue::ensureBoolean($value),true); - } - - /** - * @return string the text for the error message. - */ - public function getErrorMessage() - { - return $this->getViewState('ErrorMessage',''); - } - - /** - * Sets the text for the error message. - * @param string the error message - */ - public function setErrorMessage($value) - { - $this->setViewState('ErrorMessage',$value,''); - } - - /** - * @return string the ID path of the input control to validate - */ - public function getControlToValidate() - { - return $this->getViewState('ControlToValidate',''); - } - - /** - * Sets the ID path of the input control to validate - * @param string the ID path - */ - public function setControlToValidate($value) - { - $this->setViewState('ControlToValidate',$value,''); - } - - /** - * @return boolean whether to set focus at the validating place if the validation fails. Defaults to true. - */ - public function getFocusOnError() - { - return $this->getViewState('FocusOnError',true); - } - - /** - * @param boolean whether to set focus at the validating place if the validation fails - */ - public function setFocusOnError($value) - { - $this->setViewState('FocusOnError',TPropertyValue::ensureBoolean($value),true); - } - - /** - * Gets the ID of the HTML element that will receive focus if validation fails and {@link getFocusOnError FocusOnError} is true. - * Defaults to the client ID of the {@link getControlToValidate ControlToValidate}. - * @return string the ID of the HTML element to receive focus - */ - public function getFocusElementID() - { - // TODO: identify the ControlToValidate - return $this->getViewState('FocusElementID', ''); - } - - /** - * Sets the ID of the HTML element that will receive focus if validation fails and {@link getFocusOnError FocusOnError} is true. - * @param string the ID of the HTML element to receive focus - */ - public function setFocusElementID($value) - { - $this->setViewState('FocusElementID', $value, ''); - } - - /** - * @return string the group which this validator belongs to - */ - public function getValidationGroup() - { - return $this->getViewState('ValidationGroup',''); - } - - /** - * @param string the group which this validator belongs to - */ - public function setValidationGroup($value) - { - $this->setViewState('ValidationGroup',$value,''); - } - - /** - * @return boolean whether the validation succeeds - */ - public function getIsValid() - { - return $this->_isValid; - } - - /** - * Sets the value indicating whether the validation succeeds - * @param boolean whether the validation succeeds - */ - public function setIsValid($value) - { - $this->_isValid=TPropertyValue::ensureBoolean($value); - } - - /** - * Validates the specified control. - * Do not override this method. Override {@link evaluateIsValid} instead. - * @return boolean whether the validation succeeds - */ - public function validate() - { - $this->setIsValid(true); - if($this->getVisible(true) && $this->getEnabled()) - { - $valid=$this->evaluateIsValid(); - $this->setValid($valid); - } - if($this->isVisible() && $this->isEnabled() && strlen($this->getControlToValidate())) - { - $valid=$this->evaluateIsValid(); - $this->setValid($valid); - return $valid; - } - else - { - $this->setValid(true); - return true; - } - } - - /** - * This is the major method for validation. - * Derived classes should implement this method to provide customized validation. - * @return boolean whether the validation succeeds - */ - abstract protected function evaluateIsValid(); -} + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ + * @package System.Web.UI.WebControls + */ + +/** + * TBaseValidator class + * + * TBaseValidator serves as the base class for validator controls. + * + * Validation is performed when a button control, such a TButton, a TLinkButton + * or a TImageButton is clicked and the CausesValidation of these controls is true. + * You can also manually perform validation by using the validate() method of the TPage class. + * + * Validator controls always validate the associated input control on the server. + * TValidation controls also have complete client-side implementation that allow + * DHTML supported browsers to perform validation on the client via Javascript. + * Client-side validation will validate user input before it is sent to the server. + * The form data will not be submitted if any error is detected. This avoids + * the round-trip of information necessary for server-side validation. + * + * You can use multiple validator controls to validate an individual input control, + * each responsible for validating different criteria. For example, on a user registration + * form, you may want to make sure the user enters a value in the username text box, + * and the input must consist of only word characters. You can use a TRequiredFieldValidator + * to ensure the input of username and a TRegularExpressionValidator to ensure the proper + * input. + * + * If an input control fails validation, the text specified by the ErrorMessage + * property is displayed in the validation control. If the Text property is set + * it will be displayed instead, however. If both ErrorMessage and Text + * are empty, the body content of the validator will be displayed. + * + * You can also place a TValidationSummary control on the page to display error messages + * from the validators together. In this case, only the ErrorMessage property of the + * validators will be displayed in the TValidationSummary control. + * + * Note, the IsValid property of the current TPage instance will be automatically + * updated by the validation process which occurs after OnLoad of TPage and + * before the postback events. Therefore, if you use the IsValid + * property in the OnLoad event of TPage, you must first explicitly call + * the validate() method of TPage. As an alternative, you can place your code + * in the postback event handler, such as OnClick or OnCommand, + * instead of OnLoad event. + * + * Note, to use validators derived from this control, you have to + * copy the file "/js/prado_validator.js" to the "js" directory + * which should be under the directory containing the entry script file. + * + * Notes to Inheritors When you inherit from the TBaseValidator class, + * you must override the method {@link evaluateIsValid}. + * + * Namespace: System.Web.UI.WebControls + * + * Properties + * - EnableClientScript, boolean, default=true, kept in viewstate + *
Gets or sets a value indicating whether client-side validation is enabled. + * - Display, string, default=Static, kept in viewstate + *
Gets or sets the display behavior (None, Static, Dynamic) of the error message in a validation control. + * - ControlToValidate, string, kept in viewstate + *
Gets or sets the input control to validate. This property must be set to + * the ID path of an input control. The ID path is the dot-connected IDs of + * the controls reaching from the validator's parent control to the target control. + * For example, if HomePage is the parent of Validator and SideBar controls, and + * SideBar is the parent of UserName control, then the ID path for UserName + * would be "SideBar.UserName" if UserName is to be validated by Validator. + * - Text, string, kept in viewstate + *
Gets or sets the text of TBaseValidator control. + * - ErrorMessage, string, kept in viewstate + *
Gets or sets the text for the error message. + * - EncodeText, boolean, default=true, kept in viewstate + *
Gets or sets the value indicating whether Text and ErrorMessage should be HTML-encoded when rendering. + * - IsValid, boolean, default=true + *
Gets or sets a value that indicates whether the associated input control passes validation. + * + * @author Qiang Xue + * @version $Revision: $ $Date: $ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +abstract class TBaseValidator extends TLabel implements IValidator +{ + /** + * whether the validation succeeds + * @var boolean + */ + private $_isValid=true; + + public function __construct() + { + parent::__construct(); + $this->setForeColor('red'); + } + + /** + * Adds attributes to renderer. + * @param THtmlWriter the renderer + */ + protected function addAttributesToRender($writer) + { + } + + /** + * Returns an array of javascript validator options. + * @return array javascript validator options. + */ + protected function getClientScriptAttributes() + { + $options['ID'] = $this->getClientID(); + $options['Display'] = $this->getDisplay(); + $options['ErrorMessage'] = $this->getErrorMessage(); + $options['FocusOnError'] = $this->getFocusOnError(); + $options['FocusElementID'] = $this->getFocusElementID(); + $options['ValidationGroup'] = $this->getValidationGroup(); + $options['ControlToValidate'] = $this->getControlToValidate(); + return $options; + } + + /** + * Renders the javascript code to the end script. + * If you override this method, be sure to call the parent implementation + * so that the event handlers can be invoked. + * @param TEventParameter event parameter to be passed to the event handlers + */ + protected function onPreRender($param) + { + $scripts = $this->getPage()->getClientScript(); + $scriptKey = "prado:".get_class($this); + if($this->getEnableClientScript() + && !$script->isEndScriptRegistered($scriptKey)) + { + $scripts->registerPradoScript('validator'); + $js = "Prado.Validation.AddForm('{$this->Page->Form->ClientID}');"; + $scripts->registerEndScript($scriptKey, $js); + } + parent::onPreRender($param); + } + + /** + * Renders the individual validator client-side javascript code. + */ + protected function renderClientScriptValidator() + { + if($this->getEnabled(true) && $this->getEnableClientScript()) + { + $class = get_class($this); + $scriptKey = "prado:".$this->getClientID(); + $scripts = $this->getPage()->getClientScript(); + $option = TJavascript::toList($this->getClientScriptAttributes()); + $js = "new Prado.Validation(Prado.Validation.{$class}, {$option});"; + $scripts->registerEndScript($scriptKey, $js); + } + } + + /** + * This method overrides the parent implementation to forbid setting AssociatedControlID. + * @param string the associated control ID + * @throws TNotSupportedException whenever this method is called + */ + public function setAssociatedControlID($value) + { + throw new TNotSupportedException('basevalidator_associatedcontrolid_unsupported',get_class($this)); + } + + /** + * This method overrides parent's implementation by setting {@link setIsValid IsValid} to true if disabled. + * @param boolean whether the validator is enabled. + */ + public function setEnabled($value) + { + $value=TPropertyValue::ensureBoolean($value); + parent::setEnabled($value); + if(!$value) + $this->_isValid=true; + } + + /** + * @return string the display behavior (None, Static, Dynamic) of the error message in a validation control. Defaults to Static. + */ + public function getDisplay() + { + return $this->getViewState('Display','Static'); + } + + /** + * Sets the display behavior (None, Static, Dynamic) of the error message in a validation control. + * @param string the display behavior (None, Static, Dynamic) + */ + public function setDisplay($value) + { + $this->setViewState('Display',TPropertyValue::ensureEnum($value,array('None','Static','Dynamic')),'Static'); + } + + /** + * @return boolean whether client-side validation is enabled. + */ + public function getEnableClientScript() + { + return $this->getViewState('EnableClientScript',true); + } + + /** + * Sets the value indicating whether client-side validation is enabled. + * @param boolean whether client-side validation is enabled. + */ + public function setEnableClientScript($value) + { + $this->setViewState('EnableClientScript',TPropertyValue::ensureBoolean($value),true); + } + + /** + * @return string the text for the error message. + */ + public function getErrorMessage() + { + return $this->getViewState('ErrorMessage',''); + } + + /** + * Sets the text for the error message. + * @param string the error message + */ + public function setErrorMessage($value) + { + $this->setViewState('ErrorMessage',$value,''); + } + + /** + * @return string the ID path of the input control to validate + */ + public function getControlToValidate() + { + return $this->getViewState('ControlToValidate',''); + } + + /** + * Sets the ID path of the input control to validate + * @param string the ID path + */ + public function setControlToValidate($value) + { + $this->setViewState('ControlToValidate',$value,''); + } + + /** + * @return boolean whether to set focus at the validating place if the validation fails. Defaults to true. + */ + public function getFocusOnError() + { + return $this->getViewState('FocusOnError',true); + } + + /** + * @param boolean whether to set focus at the validating place if the validation fails + */ + public function setFocusOnError($value) + { + $this->setViewState('FocusOnError',TPropertyValue::ensureBoolean($value),true); + } + + /** + * Gets the ID of the HTML element that will receive focus if validation fails and {@link getFocusOnError FocusOnError} is true. + * Defaults to the client ID of the {@link getControlToValidate ControlToValidate}. + * @return string the ID of the HTML element to receive focus + */ + public function getFocusElementID() + { + // TODO: identify the ControlToValidate + return $this->getViewState('FocusElementID', ''); + } + + /** + * Sets the ID of the HTML element that will receive focus if validation fails and {@link getFocusOnError FocusOnError} is true. + * @param string the ID of the HTML element to receive focus + */ + public function setFocusElementID($value) + { + $this->setViewState('FocusElementID', $value, ''); + } + + /** + * @return string the group which this validator belongs to + */ + public function getValidationGroup() + { + return $this->getViewState('ValidationGroup',''); + } + + /** + * @param string the group which this validator belongs to + */ + public function setValidationGroup($value) + { + $this->setViewState('ValidationGroup',$value,''); + } + + /** + * @return boolean whether the validation succeeds + */ + public function getIsValid() + { + return $this->_isValid; + } + + /** + * Sets the value indicating whether the validation succeeds + * @param boolean whether the validation succeeds + */ + public function setIsValid($value) + { + $this->_isValid=TPropertyValue::ensureBoolean($value); + } + + /** + * Validates the specified control. + * Do not override this method. Override {@link evaluateIsValid} instead. + * @return boolean whether the validation succeeds + */ + public function validate() + { + $this->setIsValid(true); + if($this->getVisible(true) && $this->getEnabled()) + { + $valid=$this->evaluateIsValid(); + $this->setValid($valid); + } + if($this->isVisible() && $this->isEnabled() && strlen($this->getControlToValidate())) + { + $valid=$this->evaluateIsValid(); + $this->setValid($valid); + return $valid; + } + else + { + $this->setValid(true); + return true; + } + } + + /** + * This is the major method for validation. + * Derived classes should implement this method to provide customized validation. + * @return boolean whether the validation succeeds + */ + abstract protected function evaluateIsValid(); +} ?> \ No newline at end of file -- cgit v1.2.3