summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes5
-rw-r--r--buildscripts/texbuilder/Page2Tex.php107
-rw-r--r--buildscripts/texbuilder/quickstart/build.php229
-rw-r--r--buildscripts/texbuilder/quickstart/pages.php12
-rw-r--r--buildscripts/texbuilder/quickstart/quickstart.tex6
-rw-r--r--demos/quickstart/protected/pages/ActiveControls/ActiveCustomValidator.page23
-rw-r--r--demos/quickstart/protected/pages/ActiveControls/Home.page6
-rw-r--r--demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.page22
-rw-r--r--demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.php11
-rw-r--r--framework/Web/Javascripts/extended/string.js3
-rw-r--r--framework/Web/Javascripts/js/compressed/validator.js2
-rw-r--r--framework/Web/Javascripts/js/debug/validator.js2
-rw-r--r--framework/Web/Javascripts/prado/ajax.js427
-rw-r--r--framework/Web/Javascripts/prado/prado.js2
-rw-r--r--framework/Web/Javascripts/prado/validation3.js2
-rw-r--r--framework/Web/UI/ActiveControls/TActiveCustomValidator.php2
-rw-r--r--framework/Web/UI/ActiveControls/TActivePageAdapter.php4
-rw-r--r--tests/FunctionalTests/quickstart/ActiveControls/ActiveCustomValidatorTestCase.php33
18 files changed, 184 insertions, 714 deletions
diff --git a/.gitattributes b/.gitattributes
index 53b3e2b0..b2349fd8 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -763,12 +763,15 @@ demos/quickstart/protected/index/quickstart/deletable -text
demos/quickstart/protected/index/quickstart/segments -text
demos/quickstart/protected/pages/ActiveControls/ActiveButton.page -text
demos/quickstart/protected/pages/ActiveControls/ActiveCheckBox.page -text
+demos/quickstart/protected/pages/ActiveControls/ActiveCustomValidator.page -text
demos/quickstart/protected/pages/ActiveControls/Home.page -text
demos/quickstart/protected/pages/ActiveControls/Introduction.page -text
demos/quickstart/protected/pages/ActiveControls/Samples/TActiveButton/Home.page -text
demos/quickstart/protected/pages/ActiveControls/Samples/TActiveButton/Home.php -text
demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCheckBox/Home.page -text
demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCheckBox/Home.php -text
+demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.page -text
+demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.php -text
demos/quickstart/protected/pages/ActiveControls/Samples/config.xml -text
demos/quickstart/protected/pages/ActiveControls/TActiveButtonClass.png -text
demos/quickstart/protected/pages/ActiveControls/TActiveButtonClass.vsd -text
@@ -1711,7 +1714,6 @@ framework/Web/Javascripts/js/debug/prado.js -text
framework/Web/Javascripts/js/debug/rico.js -text
framework/Web/Javascripts/js/debug/validator.js -text
framework/Web/Javascripts/prado/activecontrols3.js -text
-framework/Web/Javascripts/prado/ajax.js -text
framework/Web/Javascripts/prado/ajax3.js -text
framework/Web/Javascripts/prado/controls.js -text
framework/Web/Javascripts/prado/element.js -text
@@ -1957,6 +1959,7 @@ tests/FunctionalTests/features/protected/pages/ValidatorEffects.page -text
tests/FunctionalTests/index.php -text
tests/FunctionalTests/quickstart/ActiveControls/ActiveButtonTestCase.php -text
tests/FunctionalTests/quickstart/ActiveControls/ActiveCheckBoxTestCase.php -text
+tests/FunctionalTests/quickstart/ActiveControls/ActiveCustomValidatorTestCase.php -text
tests/FunctionalTests/quickstart/Advanced/I18N.php -text
tests/FunctionalTests/quickstart/Controls/BulletedListTestCase.php -text
tests/FunctionalTests/quickstart/Controls/ButtonTestCase.php -text
diff --git a/buildscripts/texbuilder/Page2Tex.php b/buildscripts/texbuilder/Page2Tex.php
index c8cad6c9..feda4873 100644
--- a/buildscripts/texbuilder/Page2Tex.php
+++ b/buildscripts/texbuilder/Page2Tex.php
@@ -1,6 +1,6 @@
<?php
-class Page2Tex
+class Page2Tex
{
private $_current_page;
private static $header_count = 0;
@@ -16,7 +16,7 @@ class Page2Tex
$this->_current_page = $current;
$this->_dir = $dir;
}
-
+
function setCurrentPage($current)
{
$this->_current_page = $current;
@@ -24,22 +24,24 @@ class Page2Tex
function escape_verbatim($matches)
{
- return "\begin{verbatim}".str_replace($this->_verb_find, $this->_verb_replace, $matches[1])."\end{verbatim}\n";
+ return "\begin{small}\begin{verbatim}".
+ str_replace($this->_verb_find, $this->_verb_replace, $matches[1]).
+ "\end{verbatim}\end{small}\n";
}
-
+
function escape_verb($matches)
{
$text = str_replace($this->_verb_find, $this->_verb_replace, $matches[1]);
- return '\verb<'.$text.'<';
+ return '\begin{small}\verb<'.$text.'< \end{small}';
}
-
+
function include_image($matches)
{
-
+
$current_path = $this->_current_page;
-
+
$image = dirname($current_path).'/'.trim($matches[1]);
-
+
$file = realpath($image);
$info = getimagesize($file);
switch($info[2])
@@ -51,7 +53,7 @@ class Page2Tex
case 3: $im = imagecreatefrompng($file); break;
}
$base = $this->_base;
-
+
if(isset($im))
{
$prefix = strtolower(str_replace(realpath($base), '', $file));
@@ -64,7 +66,7 @@ class Page2Tex
return $this->include_figure($info, $filename);
}
}
-
+
function include_figure($info, $filename)
{
$width = sprintf('%0.2f', $info[0]/(135/2.54));
@@ -76,18 +78,18 @@ class Page2Tex
\end{figure}
';
}
-
+
function anchor($matches)
{
$page = $this->get_current_path();
return '\hypertarget{'.$page.'/'.strtolower($matches[1]).'}{}';
}
-
+
function texttt($matches)
{
return '\texttt{'.str_replace(array('#','_'),array('\#','\_'), $matches[1]).'}';
}
-
+
function get_current_path()
{
$current_path = $this->_current_page;
@@ -95,7 +97,7 @@ class Page2Tex
$page = strtolower(substr(str_replace($base, '', $current_path),1));
return $page;
}
-
+
function make_link($matches)
{
if(is_int(strpos($matches[1], '#')))
@@ -120,62 +122,60 @@ class Page2Tex
}
return '\href{'.$matches[1].'}{'.$matches[2].'}';
}
-
+
function parse_html($page,$html)
{
-
-
$html = preg_replace('/<\/?com:TContent[^>]*>/', '', $html);
$html = preg_replace('/<\/?p [^>]*>/', '', $html);
$html = preg_replace('/<\/?p>/', '', $html);
-
+
$html = preg_replace('/(\s+|\(+|\[+)"/', '$1``', $html);
-
+
//escape { and }
$html = preg_replace('/([^\s]+){([^}]*)}([^\s]+)/', '$1\\\{$2\\\}$3', $html);
-
+
$html = preg_replace_callback('/<img\s+src="?<%~([^"]*)%>"?[^>]*\/>/', array($this, 'include_image'), $html);
//escape %
$html = str_replace('%', '\%', $html);
-
+
//codes
$html = str_replace('$', '\$', $html);
-
+
$html = preg_replace_callback('/<com:TTextHighlighter[^>]*>((.|\n)*?)<\/com:TTextHighlighter>/', array($this,'escape_verbatim'), $html);
// $html = preg_replace('/<\/com:TTextHighlighter>/', '`2`', $html);
// $html = preg_replace_callback('/(`1`)([^`]*)(`2`)/m', array($this,'escape_verbatim'), $html);
$html = preg_replace_callback('/(<div class="source">)((.|\n)*?)(<\/div>)/', array($this,'escape_verbatim'), $html);
$html = preg_replace_callback('/(<pre>)([^<]*)(<\/pre>)/', array($this,'escape_verbatim'), $html);
-
+
//<code>
$html = preg_replace_callback('/<code>([^<]*)<\/code>/', array($this,'escape_verb'), $html);
-
+
//runbar
$html = preg_replace('/<com:RunBar\s+PagePath="([^"]*)"\s+\/>/',
'\href{http://www.pradosoft.com/demos/quickstart/index.php?page=$1}{$1 Demo}', $html);
-
+
//DocLink
$html = preg_replace('/<com:DocLink\s+ClassPath="([^"]*)[.]([^.]*)"\s+\/>/',
'\href{http://www.pradosoft.com/docs/manual/$1/$2.html}{$1.$2 API Reference}', $html);
-
+
//text modifiers
- $html = preg_replace('/<b[^>]*>([^<]*)<\/b>/', '\textbf{$1}', $html);
+ $html = preg_replace('/<(b|strong)[^>]*>([^<]*)<\/(b|strong)>/', '\textbf{$2}', $html);
$html = preg_replace('/<i[^>]*>([^<]*)<\/i>/', '\emph{$1}', $html);
$html = preg_replace_callback('/<tt>([^<]*)<\/tt>/', array($this,'texttt'), $html);
-
+
//links
$html = preg_replace_callback('/<a[^>]+href="([^"]*)"[^>]*>([^<]*)<\/a>/',
array($this,'make_link'), $html);
//anchor
$html = preg_replace_callback('/<a[^>]+name="([^"]*)"[^>]*><\/a>/', array($this,'anchor'), $html);
-
+
//description <dl>
$html = preg_replace('/<dt>([^<]*)<\/dt>/', '\item[$1]', $html);
$html = preg_replace('/<\/?dd>/', '', $html);
$html = preg_replace('/<dl>/', '\begin{description}', $html);
$html = preg_replace('/<\/dl>/', '\end{description}', $html);
-
+
//item lists
$html = preg_replace('/<ul[^>]*>/', '\begin{itemize}', $html);
$html = preg_replace('/<\/ul>/', '\end{itemize}', $html);
@@ -183,25 +183,28 @@ class Page2Tex
$html = preg_replace('/<\/ol>/', '\end{enumerate}', $html);
$html = preg_replace('/<li[^>]*>/', '\item ', $html);
$html = preg_replace('/<\/li>/', '', $html);
-
+
//headings
$html = preg_replace('/<h1(\s+id="[^"]+")?>([^<]+)<\/h1>/', '\section{$2}', $html);
$html = preg_replace('/<h2(\s+id="[^"]+")?>([^<]+)<\/h2>/', '\subsection{$2}', $html);
$html = preg_replace('/<h3(\s+id="[^"]+")?>([^<]+)<\/h3>/', '\subsubsection{$2}', $html);
-
+
//div box
$html = preg_replace_callback('/<div class="[tipnofe]*?">((.|\n)*?)<\/div>/',
- array($this, 'mbox'), $html);
-
+ array($this, 'mbox'), $html);
+
//tabular
$html = preg_replace_callback('/<!--\s*tabular:([^-]*)-->\s*<table[^>]*>((.|\n)*?)<\/table>/',
array($this, 'tabular'), $html);
-
+
+ $html = preg_replace('/<!--(.*)-->/', '', $html);
+
+
$html = html_entity_decode($html);
-
+
return $html;
}
-
+
function tabular($matches)
{
$options = array();
@@ -210,13 +213,13 @@ class Page2Tex
$sub = explode('=', trim($string));
$options[trim($sub[0])] = trim($sub[1]);
}
-
+
$widths = explode(' ',preg_replace('/\(|\)/', '', $options['width']));
$this->_tabular_widths = $widths;
-
+
$this->_tabular_total = count($widths);
$this->_tabular_col = 0;
-
+
$begin = "\begin{table}[!hpt]\centering \n \begin{tabular}{".$options['align']."}\\hline";
$end = "\end{tabular} \n \end{table}\n";
$table = preg_replace('/<\/tr>/', '\\\\\\\\ \hline', $matches[2]);
@@ -224,11 +227,11 @@ class Page2Tex
$table = preg_replace('/<th>([^<]+)<\/th>/', '\textbf{$1} &', $table);
$table = preg_replace_callback('/<td>((.|\n)*?)<\/td>/', array($this, 'table_column'), $table);
$table = preg_replace('/<br \/>/', ' \\\\\\\\', $table);
-
+
$table = preg_replace('/&\s*\\\\\\\\/', '\\\\\\\\', $table);
return $begin.$table.$end;
}
-
+
function table_column($matches)
{
$width = $this->_tabular_widths[$this->_tabular_col];
@@ -239,24 +242,24 @@ class Page2Tex
return '\begin{minipage}{'.$width.'\textwidth}\vspace{3mm}'.
$matches[1].'\vspace{3mm}\end{minipage} & ';
}
-
+
function mbox($matches)
{
return "\n\begin{mybox}\n".$matches[1]."\n\end{mybox}\n";
}
-
+
function get_chapter_label($chapter)
{
return '\hypertarget{'.str_replace(' ', '', $chapter).'}{}';
}
-
+
function get_section_label($section)
{
$section = str_replace('.page', '', $section);
return '\hypertarget{'.str_replace('/', '.', $section).'}{}';
}
-
-
+
+
function set_header_id($content, $count)
{
self::$header_count = $count*100;
@@ -265,22 +268,22 @@ class Page2Tex
$content = preg_replace_callback('/<h3>/', array($this,"h3"), $content);
return $content;
}
-
+
function h1($matches)
{
return "<h1 id=\"".(++self::$header_count)."\">";
}
-
+
function h2($matches)
{
return "<h2 id=\"".(++self::$header_count)."\">";
}
-
+
function h3($matches)
{
return "<h3 id=\"".(++self::$header_count)."\">";
}
-
+
}
?> \ No newline at end of file
diff --git a/buildscripts/texbuilder/quickstart/build.php b/buildscripts/texbuilder/quickstart/build.php
index 79d6d7ec..b5ee7841 100644
--- a/buildscripts/texbuilder/quickstart/build.php
+++ b/buildscripts/texbuilder/quickstart/build.php
@@ -10,223 +10,11 @@ $mainTexFile = dirname(__FILE__).'/quickstart.tex';
//page root location
$base = realpath(dirname(__FILE__).'/../../../demos/quickstart/protected/pages/');
-//-------------- END CONFIG ------------------
-
$pages = include('pages.php');
-function escape_verbatim($matches)
-{
- return "\begin{verbatim}".str_replace('\$', '$', $matches[2])."\end{verbatim}\n";
-}
-
-function escape_verb($matches)
-{
- $text = str_replace(array('\{', '\}'), array('{','}'), $matches[1]);
- return '\verb<'.$text.'<';
-}
-
-function include_image($matches)
-{
- global $current_path;
-
- $image = dirname($current_path).'/'.trim($matches[1]);
-
- $file = realpath($image);
- $info = getimagesize($file);
- switch($info[2])
- {
- case 1:
- $im = imagecreatefromgif($file);
- break;
- case 2: $im = imagecreatefromjpeg($file); break;
- case 3: $im = imagecreatefrompng($file); break;
- }
- global $base;
-
- if(isset($im))
- {
- $prefix = strtolower(str_replace(realpath($base), '', $file));
- $filename = preg_replace('/\\\|\//', '_', substr($prefix,1));
- $filename = substr($filename, 0, strrpos($filename,'.')).'.png';
- $newfile = dirname(__FILE__).'/'.$filename;
- imagepng($im,$newfile);
- imagedestroy($im);
-
- return include_figure($info, $filename);
- }
-}
-
-function include_figure($info, $filename)
-{
- $width = sprintf('%0.2f', $info[0]/(135/2.54));
- return '
-\begin{figure}[ht]
- \centering
- \includegraphics[width='.$width.'cm]{'.$filename.'}
- \label{fig:'.$filename.'}
-\end{figure}
-';
-}
-
-function anchor($matches)
-{
- $page = get_current_path();
- return '\hypertarget{'.$page.'/'.strtolower($matches[1]).'}{}';
-}
-
-function texttt($matches)
-{
- return '\texttt{'.str_replace(array('#','_'),array('\#','\_'), $matches[1]).'}';
-}
-
-function get_current_path()
-{
- global $current_path, $base;
- $page = strtolower(substr(str_replace($base, '', $current_path),1));
- return $page;
-}
-
-function make_link($matches)
-{
- if(is_int(strpos($matches[1], '#')))
- {
- if(strpos($matches[1],'?') ===false)
- {
- $target = get_current_path().'/'.substr($matches[1],1);
- return '\hyperlink{'.$target.'}{'.$matches[2].'}';
- }
- else
- {
- $page = strtolower(str_replace('?page=', '', $matches[1]));
- $page = str_replace('.','/',$page);
- $page = str_replace('#','.page/',$page);
- return '\hyperlink{'.$page.'}{'.$matches[2].'}';
- }
- }
- else if(is_int(strpos($matches[1],'?')))
- {
- $page = str_replace('?page=','',$matches[1]);
- return '\hyperlink{'.$page.'}{'.$matches[2].'}';
- }
- return '\href{'.$matches[1].'}{'.$matches[2].'}';
-}
-
-function parse_html($page,$html)
-{
- $html = preg_replace('/<\/?com:TContent[^>]*>/', '', $html);
- $html = preg_replace('/<\/?p>/m', '', $html);
-
- //escape { and }
- $html = preg_replace('/([^\s]+){([^}]*)}([^\s]+)/', '$1\\\{$2\\\}$3', $html);
-
- //codes
- $html = str_replace('$', '\$', $html);
- $html = preg_replace('/<com:TTextHighlighter[^>]*>/', '`1`', $html);
- $html = preg_replace('/<\/com:TTextHighlighter>/', '`2`', $html);
- $html = preg_replace_callback('/(`1`)([^`]*)(`2`)/m', 'escape_verbatim', $html);
- $html = preg_replace_callback('/(<div class="source">)([^<]*)(<\/div>)/', 'escape_verbatim', $html);
- $html = preg_replace_callback('/(<pre>)([^<]*)(<\/pre>)/', 'escape_verbatim', $html);
-
- //<code>
- $html = preg_replace_callback('/<code>([^<]*)<\/code>/', 'escape_verb', $html);
-
- $html = preg_replace_callback('/<img\s+src="?<%~([^"]*)%>"?[^\\/]*\/>/', 'include_image', $html);
-
- //runbar
- $html = preg_replace('/<com:RunBar\s+PagePath="([^"]*)"\s+\/>/',
- '\href{http://www.pradosoft.com/demos/quickstart/index.php?page=$1}{$1 Demo}', $html);
-
- //DocLink
- $html = preg_replace('/<com:DocLink\s+ClassPath="([^"]*)[.]([^.]*)"\s+\/>/',
- '\href{http://www.pradosoft.com/docs/manual/$1/$2.html}{$1.$2 API Reference}', $html);
-
- //text modifiers
- $html = preg_replace('/<b>([^<]*)<\/b>/', '\textbf{$1}', $html);
- $html = preg_replace('/<i>([^<]*)<\/i>/', '\emph{$1}', $html);
- $html = preg_replace_callback('/<tt>([^<]*)<\/tt>/', 'texttt', $html);
-
- //links
- $html = preg_replace_callback('/<a[^>]+href="([^"]*)"[^>]*>([^<]*)<\/a>/',
- 'make_link', $html);
- //anchor
- $html = preg_replace_callback('/<a[^>]+name="([^"]*)"[^>]*><\/a>/', 'anchor', $html);
-
- //description <dl>
- $html = preg_replace('/<dt>([^<]*)<\/dt>/', '\item[$1]', $html);
- $html = preg_replace('/<\/?dd>/', '', $html);
- $html = preg_replace('/<dl>/', '\begin{description}', $html);
- $html = preg_replace('/<\/dl>/', '\end{description}', $html);
-
- //item lists
- $html = preg_replace('/<ul>/', '\begin{itemize}', $html);
- $html = preg_replace('/<\/ul>/', '\end{itemize}', $html);
- $html = preg_replace('/<ol>/', '\begin{enumerate}', $html);
- $html = preg_replace('/<\/ol>/', '\end{enumerate}', $html);
- $html = preg_replace('/<li>/', '\item ', $html);
- $html = preg_replace('/<\/li>/', '', $html);
-
- //headings
- $html = preg_replace('/<h1\s+id="[^"]+">([^<]+)<\/h1>/', '\section{$1}', $html);
- $html = preg_replace('/<h2\s+id="[^"]+">([^<]+)<\/h2>/', '\subsection{$1}', $html);
- $html = preg_replace('/<h3\s+id="[^"]+">([^<]+)<\/h3>/', '\subsubsection{$1}', $html);
-
-
-
- $html = html_entity_decode($html);
-
-
- return $html;
-}
-
-function get_chapter_label($chapter)
-{
- return '\hypertarget{'.str_replace(' ', '', $chapter).'}{}';
-}
-
-function get_section_label($section)
-{
- $section = str_replace('.page', '', $section);
- return '\hypertarget{'.str_replace('/', '.', $section).'}{}';
-}
-
-
-function set_header_id($content, $count)
-{
- global $header_count;
- $header_count = $count*100;
- $content = preg_replace_callback('/<h1>/', "h1", $content);
- $content = preg_replace_callback('/<h2>/', "h2", $content);
- $content = preg_replace_callback('/<h3>/', "h3", $content);
- return $content;
-}
-
-function h1($matches)
-{
- global $header_count;
- return "<h1 id=\"".(++$header_count)."\">";
-}
-
-function h2($matches)
-{
- global $header_count;
- return "<h2 id=\"".(++$header_count)."\">";
-}
-
-function h3($matches)
-{
- global $header_count;
- return "<h3 id=\"".(++$header_count)."\">";
-}
-
-$header_count = 0;
-
-//--------------- BEGIN PROCESSING -------------------
-
-
-//--------------- Indexer -------------------
+//-------------- END CONFIG ------------------
-//require_once('create_index.php');
-//$indexer = new quickstart_index($index_dir);
+include(dirname(__FILE__).'.../../../texbuilder/Page2Tex.php');
// ---------------- Create the Tex files ---------
$count = 1;
@@ -234,9 +22,11 @@ $j = 1;
$current_path = '';
echo "Compiling .page files to Latex files\n\n";
+$parser = new Page2Tex($base, dirname(__FILE__));
+
foreach($pages as $chapter => $sections)
{
- $content = '\chapter{'.$chapter.'}'.get_chapter_label($chapter);
+ $content = '\chapter{'.$chapter.'}'.$parser->get_chapter_label($chapter);
echo "Creating ch{$count}.txt => Chapter {$count}: {$chapter}\n";
echo str_repeat('-',60)."\n";
foreach($sections as $section)
@@ -244,15 +34,16 @@ foreach($pages as $chapter => $sections)
echo " Adding $section\n";
$page = $base.'/'.$section;
$current_path = $page;
+ $parser->setCurrentPage($current_path);
//add id to <h1>, <h2>, <3>
- $tmp_content = set_header_id(file_get_contents($page),$j++);
- file_put_contents($page, $tmp_content);
+ $tmp_content = $parser->set_header_id(file_get_contents($page),$j++);
+// file_put_contents($page, $tmp_content);
- $content .= get_section_label($section);
+ $content .= $parser->get_section_label($section);
$file_content = file_get_contents($page);
$tex =
- $content .= parse_html($page,$file_content);
+ $content .= $parser->parse_html($page,$file_content);
}
//var_dump($content);
diff --git a/buildscripts/texbuilder/quickstart/pages.php b/buildscripts/texbuilder/quickstart/pages.php
index 9b8a97ad..c237a179 100644
--- a/buildscripts/texbuilder/quickstart/pages.php
+++ b/buildscripts/texbuilder/quickstart/pages.php
@@ -1,6 +1,6 @@
<?php
/*
- * Created on 11/05/2006
+ * $Id$
*/
//list page into chapters
@@ -74,6 +74,15 @@ $pages['Control Reference : Data Controls'] = array(
'Controls/DataGrid.page',
'Controls/Repeater.page');
+$pages['Control Reference : Active Controls (AJAX)'] = array(
+ 'ActiveControls/ActiveButton.page',
+ 'ActiveControls/ActiveCheckBox.page',
+ 'ActiveControls/ActiveCustomValidator.page');
+
+$pages['Active Control Overview'] = array(
+ 'ActiveControls/Home.page',
+ 'ActiveControls/Introduction.page');
+
$pages['Write New Controls'] = array(
'Controls/NewControl.page');
@@ -96,7 +105,6 @@ $pages['Client-side Scripting'] = array(
'Advanced/Scripts2.page',
'Advanced/Scripts3.page');
-
return $pages;
//-------------- END CONFIG ----------------
diff --git a/buildscripts/texbuilder/quickstart/quickstart.tex b/buildscripts/texbuilder/quickstart/quickstart.tex
index a0553658..264f9c85 100644
--- a/buildscripts/texbuilder/quickstart/quickstart.tex
+++ b/buildscripts/texbuilder/quickstart/quickstart.tex
@@ -42,7 +42,7 @@
%----------------- TITLE --------------
-\title{\Huge \bfseries PRADO v3.0.3 Quickstart Tutorial
+\title{\Huge \bfseries PRADO v3.1 Quickstart Tutorial
\thanks{Copyright 2005-2006. All Rights Reserved.}
}
\author{Qiang Xue and Wei Zhuo}
@@ -68,7 +68,7 @@ Prado quick start doc
\chapter*{License}
\addcontentsline{toc}{chapter}{License}
PRADO is free software released under the terms of the following BSD license.\\
-Copyright 2004-2006, The PRADO Group (http://www.pradosoft.com)\\
+Copyright 2004-2006, The PRADO Group (http://www.pradosoft.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -118,5 +118,7 @@ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\include{ch11}
\include{ch12}
\include{ch13}
+\include{ch14}
+\include{ch15}
\end{document}
diff --git a/demos/quickstart/protected/pages/ActiveControls/ActiveCustomValidator.page b/demos/quickstart/protected/pages/ActiveControls/ActiveCustomValidator.page
new file mode 100644
index 00000000..f97ea40d
--- /dev/null
+++ b/demos/quickstart/protected/pages/ActiveControls/ActiveCustomValidator.page
@@ -0,0 +1,23 @@
+<com:TContent ID="body">
+<!-- $Id: ActiveCheckBox.page 1405 2006-09-10 01:03:56Z wei $ -->
+<h1>TActiveCustomValidator</h1>
+<com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveCustomValidator" />
+
+<p>Performs custom validation using only server-side <tt>OnServerValidate</tt>
+ validation event. The client-side uses callbacks to raise
+ <tt>onServerValidate</tt> event. The <tt>ClientValidationFunction</tt> property
+ is disabled and will throw an exception if trying to set this property.
+</p>
+
+<p> Beware that the <tt>onServerValidate</tt> may be
+raised when the control to validate on the client side
+changes value, that is, the server validation may be called many times.
+
+After the callback or postback, the {@link onServerValidate onServerValidate}
+is raised once more. The <tt>IsCallback</tt> property of the <tt>TPage</tt> class
+will be true when validation is made during a callback request.
+</p>
+
+<com:RunBar PagePath="ActiveControls.Samples.TActiveCustomValidator.Home" />
+
+</com:TContent>
diff --git a/demos/quickstart/protected/pages/ActiveControls/Home.page b/demos/quickstart/protected/pages/ActiveControls/Home.page
index 9b9e3067..eabb62c9 100644
--- a/demos/quickstart/protected/pages/ActiveControls/Home.page
+++ b/demos/quickstart/protected/pages/ActiveControls/Home.page
@@ -32,7 +32,7 @@ TActiveButton</a> control.</p>
</li>
<li>
- * <a href="?page=ActiveControls.ActiveCustomValidator">TActiveCustomValidator</a>
+ <a href="?page=ActiveControls.ActiveCustomValidator">TActiveCustomValidator</a>
validates a particular control using a callback request.
</li>
@@ -86,7 +86,7 @@ TActiveButton</a> control.</p>
<li>
* <a href="?page=ActiveControls.CallbackOptions">TCallbackOptions</a>
- callback options such as <tt>OnLoading</tt/> client-side event handlers.
+ callback options such as <tt>OnLoading</tt> client-side event handlers.
</li>
</ul>
@@ -159,7 +159,7 @@ TActiveButton</a> control.</p>
<h2>Active Control Abilities</h2>
-<!-- tabular: align=|l|l|l|, width=(0.55 0.15 0.15 0.15) -->
+<!-- tabular: align=|l|l|l|l|, width=(0.35 0.15 0.15 0.15) -->
<table class="tabular">
<tr>
<th>Control Name</th>
diff --git a/demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.page b/demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.page
new file mode 100644
index 00000000..8d5cb24d
--- /dev/null
+++ b/demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.page
@@ -0,0 +1,22 @@
+<com:TContent ID="body">
+<!-- $Id: Home.page 1405 2006-09-10 01:03:56Z wei $ -->
+<h1>TActiveCustomValidator Samples (AJAX)</h1>
+
+<table class="sampletable">
+
+<tr><td class="samplenote">
+Custom validator using callbacks:
+</td><td class="sampleaction">
+<com:TTextBox ID="textbox1" />
+<com:TActiveCustomValidator
+ ID="validator1"
+ ControlToValidate="textbox1"
+ ErrorMessage="Please enter 'Prado'"
+ OnServerValidate="validator1_onvalidate" />
+<com:TButton ID="button1" Text="Submit!" />
+</td></tr>
+</table>
+
+<com:TJavascriptLogger />
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.php b/demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.php
new file mode 100644
index 00000000..102afcb0
--- /dev/null
+++ b/demos/quickstart/protected/pages/ActiveControls/Samples/TActiveCustomValidator/Home.php
@@ -0,0 +1,11 @@
+<?php
+
+class Home extends TPage
+{
+ public function validator1_onvalidate($sender, $param)
+ {
+ $param->IsValid = $this->textbox1->Text == 'Prado';
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/Javascripts/extended/string.js b/framework/Web/Javascripts/extended/string.js
index 5cd1bd8e..2bb40759 100644
--- a/framework/Web/Javascripts/extended/string.js
+++ b/framework/Web/Javascripts/extended/string.js
@@ -1,7 +1,8 @@
/**
* @class String extensions
*/
-Object.extend(String.prototype, {
+Object.extend(String.prototype,
+{
/**
* @param {String} "left" to pad the string on the left, "right" to pad right.
* @param {Number} minimum string length.
diff --git a/framework/Web/Javascripts/js/compressed/validator.js b/framework/Web/Javascripts/js/compressed/validator.js
index ac9c1444..088d6adf 100644
--- a/framework/Web/Javascripts/js/compressed/validator.js
+++ b/framework/Web/Javascripts/js/compressed/validator.js
@@ -187,7 +187,7 @@ return true;switch(this.options.Operator)
{validate=clientFunction.toFunction();return validate(this,value);}
return true;}});Prado.WebUI.TActiveCustomValidator=Class.extend(Prado.WebUI.TBaseValidator,{validatingValue:null,evaluateIsValid:function()
{value=this.getValidationValue();if(!this.requestDispatched&&value!=this.validatingValue)
-{this.validatingValue=value;request=new Prado.CallbackRequest(this.options.EventTarget,this.options);request.setParameter(value);request.setCausesValidation(false);request.options.onSuccess=this.callbackOnSuccess.bind(this);request.options.onFailure=this.callbackOnFailure.bind(this);request.dispatch();this.requestDispatched=true;return false;}
+{this.validatingValue=value;request=new Prado.CallbackRequest(this.options.EventTarget,this.options);request.setCallbackParameter(value);request.setCausesValidation(false);request.options.onSuccess=this.callbackOnSuccess.bind(this);request.options.onFailure=this.callbackOnFailure.bind(this);request.dispatch();this.requestDispatched=true;return false;}
return this.isValid;},callbackOnSuccess:function(request,data)
{this.isValid=data;this.requestDispatched=false;Prado.Validation.validate(this.options.FormID,this.group,null);},callbackOnFailure:function(request,data)
{this.requestDispatched=false;}});Prado.WebUI.TRangeValidator=Class.extend(Prado.WebUI.TBaseValidator,{evaluateIsValid:function()
diff --git a/framework/Web/Javascripts/js/debug/validator.js b/framework/Web/Javascripts/js/debug/validator.js
index dbc180cf..c38ec2e4 100644
--- a/framework/Web/Javascripts/js/debug/validator.js
+++ b/framework/Web/Javascripts/js/debug/validator.js
@@ -1128,7 +1128,7 @@ Prado.WebUI.TActiveCustomValidator = Class.extend(Prado.WebUI.TBaseValidator,
{
this.validatingValue = value;
request = new Prado.CallbackRequest(this.options.EventTarget, this.options);
- request.setParameter(value);
+ request.setCallbackParameter(value);
request.setCausesValidation(false);
request.options.onSuccess = this.callbackOnSuccess.bind(this);
request.options.onFailure = this.callbackOnFailure.bind(this);
diff --git a/framework/Web/Javascripts/prado/ajax.js b/framework/Web/Javascripts/prado/ajax.js
deleted file mode 100644
index 4f1c1ec9..00000000
--- a/framework/Web/Javascripts/prado/ajax.js
+++ /dev/null
@@ -1,427 +0,0 @@
-/**
- * Prado AJAX service. The default service provider is JPSpan.
- */
-Prado.AJAX = { Service : 'Prototype' };
-
-/**
- * Parse and execute javascript embedded in html.
- */
-Prado.AJAX.EvalScript = function(output)
-{
-
- var match = new RegExp(Ajax.Updater.ScriptFragment, 'img');
- var scripts = output.match(match);
- if (scripts)
- {
- match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
- setTimeout((function()
- {
- for (var i = 0; i < scripts.length; i++)
- eval(scripts[i].match(match)[1]);
- }).bind(this), 50);
- }
-}
-
-
-/**
- * AJAX service request using Prototype's AJAX request class.
- */
-Prado.AJAX.Request = Class.create();
-Prado.AJAX.Request.prototype = Object.extend(Ajax.Request.prototype,
-{
- /**
- * Evaluate the respond JSON data, override parent implementing.
- * If default eval fails, try parsing the JSON data (slower).
- */
- evalJSON: function()
- {
- try
- {
- var json = this.transport.getResponseHeader('X-JSON'), object;
- object = eval(json);
- return object;
- }
- catch (e)
- {
- if(isString(json))
- {
- return Prado.AJAX.JSON.parse(json);
- }
- }
- },
-
- respondToReadyState: function(readyState) {
- var event = Ajax.Request.Events[readyState];
- var transport = this.transport, json = this.evalJSON();
-
-
- if(event == 'Complete' && transport.status)
- Ajax.Responders.dispatch('on' + transport.status, this, transport, json);
-
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
-
- if (event == 'Complete')
- (this.options['on' + this.transport.status]
- || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
- || Prototype.emptyFunction)(transport, json);
-
-
- /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
- if (event == 'Complete')
- this.transport.onreadystatechange = Prototype.emptyFunction;
- }
-
-});
-
-Prado.AJAX.Error = function(e, code)
-{
- e.name = 'Prado.AJAX.Error';
- e.code = code;
- return e;
-}
-
-/**
- * Post data builder, serialize the data using JSON.
- */
-Prado.AJAX.RequestBuilder = Class.create();
-Prado.AJAX.RequestBuilder.prototype =
-{
- initialize : function()
- {
- this.body = '';
- this.data = [];
- },
- encode : function(data)
- {
- return Prado.AJAX.JSON.stringify(data);
- },
- build : function(data)
- {
- var sep = '';
- for ( var argName in data)
- {
- if(isFunction(data[argName])) continue;
- try
- {
- this.body += sep + argName + '=';
- this.body += encodeURIComponent(this.encode(data[argName]));
- } catch (e) {
- throw Prado.AJAX.Error(e, 1006);
- }
- sep = '&';
- }
- },
-
- getAll : function()
- {
- this.build(this.data);
- return this.body;
- }
-}
-
-
-Prado.AJAX.RemoteObject = function(){};
-
-/**
- * AJAX service request for Prado RemoteObjects
- */
-Prado.AJAX.RemoteObject.Request = Class.create();
-Prado.AJAX.RemoteObject.Request.prototype = Object.extend(Prado.AJAX.Request.prototype,
-{
- /**
- * Initialize the RemoteObject Request, overrides parent
- * implementation by delaying the request to invokeRemoteObject.
- */
- initialize : function(options)
- {
- this.transport = Ajax.getTransport();
- this.setOptions(options);
- this.post = new Prado.AJAX.RequestBuilder();
- },
-
- /**
- * Call the remote object,
- * @param string the remote server url
- * @param array additional arguments
- */
- invokeRemoteObject : function(url, args)
- {
- this.initParameters(args);
- this.options.postBody = this.post.getAll();
- this.request(url);
- },
-
- /**
- * Set the additional arguments as post data with key '__parameters'
- */
- initParameters : function(args)
- {
- this.post.data['__parameters'] = [];
- for(var i = 0; i<args.length; i++)
- this.post.data['__parameters'][i] = args[i];
- }
-});
-
-/**
- * Base proxy class for Prado RemoteObjects via AJAX.
- * e.g.
- * <code>
- * var TestObject1 = Class.create();
- * TestObject1.prototype = Object.extend(new Prado.AJAX.RemoteObject(),
- * {
- * initialize : function(handlers, options)
- * {
- * this.__serverurl = 'http://127.0.0.1/.....';
- * this.baseInitialize(handlers, options);
- * }
- *
- * method1 : function()
- * {
- * return this.__call(this.__serverurl, 'method1', arguments);
- * }
- * });
- *</code>
- * And client usage,
- * <code>
- * var test1 = new TestObject1(); //create new remote object
- * test1.method1(); //call the method, no onComplete hook
- *
- * var onComplete = { method1 : function(result){ alert(result) } };
- * //create new remote object with onComplete callback
- * var test2 = new TestObject1(onComplete);
- * test2.method1(); //call it, on success, onComplete's method1 is called.
- * </code>
- */
-Prado.AJAX.RemoteObject.prototype =
-{
- baseInitialize : function(handlers, options)
- {
- this.__handlers = handlers || {};
- this.__service = new Prado.AJAX.RemoteObject.Request(options);
- },
-
- __call : function(url, method, args)
- {
- this.__service.options.onSuccess = this.__onSuccess.bind(this);
- this.__callback = method;
- return this.__service.invokeRemoteObject(url+"/"+method, args);
- },
-
- __onSuccess : function(transport, json)
- {
- if(this.__handlers[this.__callback])
- this.__handlers[this.__callback](json, transport.responseText);
- }
-};
-
-/**
- * Respond to Prado AJAX request exceptions.
- */
-Prado.AJAX.Exception =
-{
- /**
- * Server returns 505 exception. Just log it.
- */
- "on505" : function(request, transport, e)
- {
- var msg = 'HTTP '+transport.status+" with response";
- Logger.error(msg, transport.responseText);
- Logger.exception(e);
- },
-
- onComplete : function(request, transport, e)
- {
- if(transport.status != 505)
- {
- var msg = 'HTTP '+transport.status+" with response : \n";
- msg += transport.responseText + "\n";
- msg += "Data : \n"+inspect(e);
- Logger.warn(msg);
- }
- },
-
- format : function(e)
- {
- var msg = e.type + " with message \""+e.message+"\"";
- msg += " in "+e.file+"("+e.line+")\n";
- msg += "Stack trace:\n";
- var trace = e.trace;
- for(var i = 0; i<trace.length; i++)
- {
- msg += " #"+i+" "+trace[i].file;
- msg += "("+trace[i].line+"): ";
- msg += trace[i]["class"]+"->"+trace[i]["function"]+"()"+"\n";
- }
- return msg;
- },
-
- logException : function(e)
- {
- var msg = Prado.AJAX.Exception.format(e);
- Logger.error("Server Error "+e.code, msg);
- }
-}
-
-//Add HTTP exception respones when logger is enabled.
-Event.OnLoad(function()
-{
- if(typeof Logger != "undefined")
- {
- Logger.exception = Prado.AJAX.Exception.logException;
- Ajax.Responders.register(Prado.AJAX.Exception);
- }
-});
-
-/**
- * Prado Callback service that provides component intergration,
- * viewstate (read only), and automatic form data serialization.
- * Usage: <code>new Prado.AJAX.Callback('MyPage.MyComponentID.raiseCallbackEvent', options)</code>
- * These classes should be called by the components developers.
- * For inline callback service, use <t>Prado.Callback(callbackID, params)</t>.
- */
-Prado.AJAX.Callback = Class.create();
-Prado.AJAX.Callback.prototype = Object.extend(new Prado.AJAX.RemoteObject(),
-{
-
- /**
- * Create and request a new Prado callback service.
- * @param string|element the callback ID, must be of the form, <t>ClassName.ComponentID.MethodName</t>
- * @param list options with list key onCallbackReturn, and more.
- *
- */
- initialize : function(ID, options)
- {
- if(!isString(ID) && typeof(ID.id) != "undefined")
- ID = ID.id;
- if(!isString(ID))
- throw new Error('A Control ID must be specified');
- this.baseInitialize(this, options);
- this.options = options || [];
- this.__service.post.data['__ID'] = ID;
- this.requestCallback();
- },
-
- /**
- * Get form data for components that implements IPostBackHandler.
- */
- collectPostData : function()
- {
- var IDs = Prado.AJAX.Callback.IDs;
- this.__service.post.data['__data'] = {};
- for(var i = 0; i<IDs.length; i++)
- {
- var id = IDs[i];
- if(id.indexOf("[]") > -1)
- this.__service.post.data['__data'][id] =
- this.collectArrayPostData(id);
- else if(isObject($(id)))
- this.__service.post.data['__data'][id] = $F(id);
- }
- },
-
- collectArrayPostData : function(name)
- {
- var elements = document.getElementsByName(name);
- var data = [];
- $A(elements).each(function(el)
- {
- if($F(el)) data.push($F(el));
- });
- return data;
- },
-
- /**
- * Prepares and calls the AJAX request.
- * Collects the data from components that implements IPostBackHandler
- * and the viewstate as part of the request payload.
- */
- requestCallback : function()
- {
- this.collectPostData();
- if(Prado.AJAX.Validate(this.options))
- return this.__call(Prado.AJAX.Callback.Server, 'handleCallback', this.options.params);
- },
-
- /**
- * On callback request return, call the onSuccess function.
- */
- handleCallback : function(result, output)
- {
- if(typeof(result) != "undefined" && !isNull(result))
- {
- this.options.onSuccess(result['data'], output);
- if(result['actions'])
- result.actions.each(Prado.AJAX.Callback.Action.__run);
- }
- }
-});
-
-/**
- * Prase and evaluate Callback clien-side actions.
- */
-Prado.AJAX.Callback.Action =
-{
- __run : function(command)
- {
- for(var name in command)
- {
- //first parameter must be a valid element or begins with '@'
- if(command[name][0] && ($(command[name][0]) || command[name][0].indexOf("[]") > -1))
- {
- name.toFunction().apply(this,command[name]);
- }
- }
- }
-};
-
-
-/**
- * Returns false if validation required and validates to false,
- * returns true otherwise.
- * @return boolean true if validation passes.
- */
-Prado.AJAX.Validate = function(options)
-{
- if(options.CausesValidation)
- {
- if(options.ValidatorGroup)
- return Prado.Validation.ValidateValidatorGroup(options.ValidatorGroup);
- else if(options.ValidationGroup)
- return Prado.Validation.ValidateValidationGroup(options.ValidationGroup);
- else
- return Prado.Validation.ValidateNonGroup(options.ValidationForm);
- }
- else
- return true;
-};
-
-
-//Available callback service
-Prado.AJAX.Callback.Server = '';
-
-//List of IDs that implements IPostBackHandler
-Prado.AJAX.Callback.IDs = [];
-
-/**
- * Simple AJAX callback interface, suitable for inline javascript.
- * e.g., <code><a href="..." onclick="Prado.Callback('..', 'Hello');">Click me</a></code>
- * @param {String} callback ID
- * @param {Array} parameters to pass to the callback service
- * @param {Function} on callback success handler method
- * @param {Object} additional callback options
- */
-Prado.Callback = function(ID, params, onSuccess, options)
-{
- var callback =
- {
- 'params' : [params] || [],
- 'onSuccess' : onSuccess || Prototype.emptyFunction,
- 'CausesValidation' : true
- };
-
- Object.extend(callback, options || {});
-
- new Prado.AJAX.Callback(ID, callback);
- return false;
-} \ No newline at end of file
diff --git a/framework/Web/Javascripts/prado/prado.js b/framework/Web/Javascripts/prado/prado.js
index ad51e2f7..dff74f03 100644
--- a/framework/Web/Javascripts/prado/prado.js
+++ b/framework/Web/Javascripts/prado/prado.js
@@ -1,7 +1,7 @@
var Prado =
{
- Version: '3.0.0',
+ Version: '3.1',
/**
* Returns browser information. Example
diff --git a/framework/Web/Javascripts/prado/validation3.js b/framework/Web/Javascripts/prado/validation3.js
index 4e30b0b2..893fceef 100644
--- a/framework/Web/Javascripts/prado/validation3.js
+++ b/framework/Web/Javascripts/prado/validation3.js
@@ -1128,7 +1128,7 @@ Prado.WebUI.TActiveCustomValidator = Class.extend(Prado.WebUI.TBaseValidator,
{
this.validatingValue = value;
request = new Prado.CallbackRequest(this.options.EventTarget, this.options);
- request.setParameter(value);
+ request.setCallbackParameter(value);
request.setCausesValidation(false);
request.options.onSuccess = this.callbackOnSuccess.bind(this);
request.options.onFailure = this.callbackOnFailure.bind(this);
diff --git a/framework/Web/UI/ActiveControls/TActiveCustomValidator.php b/framework/Web/UI/ActiveControls/TActiveCustomValidator.php
index 80e594e2..686149eb 100644
--- a/framework/Web/UI/ActiveControls/TActiveCustomValidator.php
+++ b/framework/Web/UI/ActiveControls/TActiveCustomValidator.php
@@ -86,7 +86,7 @@ class TActiveCustomValidator extends TCustomValidator
{
$this->_isCallback = true;
$result = $this->onServerValidate($param->getCallbackParameter());
- $param->setData($result);
+ $param->setResponseData($result);
$this->onCallback($param);
}
diff --git a/framework/Web/UI/ActiveControls/TActivePageAdapter.php b/framework/Web/UI/ActiveControls/TActivePageAdapter.php
index 9274ddb7..3b386902 100644
--- a/framework/Web/UI/ActiveControls/TActivePageAdapter.php
+++ b/framework/Web/UI/ActiveControls/TActivePageAdapter.php
@@ -299,7 +299,7 @@ class TCallbackEventParameter extends TEventParameter
/**
* @param mixed callback response data.
*/
- public function setResponesData($value)
+ public function setResponseData($value)
{
$this->_response->getAdapter()->setResponseData($value);
}
@@ -307,7 +307,7 @@ class TCallbackEventParameter extends TEventParameter
/**
* @return mixed callback response data.
*/
- public function getResponesData()
+ public function getResponseData()
{
return $this->_response->getAdapter()->getResponseData();
}
diff --git a/tests/FunctionalTests/quickstart/ActiveControls/ActiveCustomValidatorTestCase.php b/tests/FunctionalTests/quickstart/ActiveControls/ActiveCustomValidatorTestCase.php
new file mode 100644
index 00000000..a78f5e2f
--- /dev/null
+++ b/tests/FunctionalTests/quickstart/ActiveControls/ActiveCustomValidatorTestCase.php
@@ -0,0 +1,33 @@
+<?php
+//$Id: ActiveButtonTestCase.php 1405 2006-09-10 01:03:56Z wei $
+class ActiveCustomValidatorTestCase extends SeleniumTestCase
+{
+ function test ()
+ {
+ $this->open("../../demos/quickstart/index.php?page=ActiveControls.Samples.TActiveCustomValidator.Home&amp;notheme=true");
+
+ $this->verifyTitle("PRADO QuickStart Sample", "");
+
+ $this->assertTextPresent('TActiveCustomValidator Samples (AJAX)');
+
+ $base = 'ctl0_body_';
+
+ $this->assertNotVisible($base.'validator1');
+ $this->click($base.'button1');
+ $this->pause(800);
+ $this->assertVisible($base.'validator1');
+
+ $this->type($base.'textbox1', 'hello');
+ $this->pause(800);
+ $this->assertVisible($base.'validator1');
+
+ $this->type($base.'textbox1', 'Prado');
+ $this->pause(800);
+ $this->assertNotVisible($base.'validator1');
+
+ $this->clickAndWait($base.'button1');
+ $this->assertNotVisible($base.'validator1');
+ }
+}
+
+?> \ No newline at end of file