diff options
35 files changed, 359 insertions, 378 deletions
diff --git a/.gitattributes b/.gitattributes index 04b42000..ea016ff1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -696,10 +696,6 @@ demos/quickstart/index.php -text demos/quickstart/index2.php -text demos/quickstart/protected/.htaccess -text demos/quickstart/protected/application.xml -text -demos/quickstart/protected/comments/CommentList.php -text -demos/quickstart/protected/comments/CommentList.tpl -text -demos/quickstart/protected/comments/QuickStartComments.php -text -demos/quickstart/protected/comments/comments.db -text demos/quickstart/protected/controls/DocLink.php -text demos/quickstart/protected/controls/Layout.php -text demos/quickstart/protected/controls/Layout.tpl -text @@ -1500,6 +1496,7 @@ framework/Web/Javascripts/colorpicker/colorpicker.js -text framework/Web/Javascripts/colorpicker/default.css -text framework/Web/Javascripts/colorpicker/hue.gif -text framework/Web/Javascripts/colorpicker/slider.gif -text +framework/Web/Javascripts/colorpicker/spacer.gif -text framework/Web/Javascripts/colorpicker/target_black.gif -text framework/Web/Javascripts/colorpicker/target_white.gif -text framework/Web/Javascripts/datepicker/calendar.png -text @@ -13,11 +13,14 @@ Version 3.0.2 July 2, 2006 ==========================
BUG: Ticket#182 - List and validator controls cause problem in child classes (Qiang)
BUG: Ticket#191 - Duplicated postbacks occur when using TButton with validators (Qiang)
+BUG: Ticket#207 - Validators ClientSide.OnError triggered twice (Wei)
BUG: Ticket#213 - PRADO Requirements Checker charset error (Qiang)
+BUG: Ticket#227 - Enabled property doesn't works with THtmlArea (Wei)
BUG: Ticket#234 - Postback target could be out of date (Qiang)
BUG: Ticket#239 - Ondeactivate handler for the first View of MultiView is always fired (Qiang)
BUG: Ticket#244 - redirect() needs absolute URL (Qiang)
BUG: Ticket#245 - getIsSecureConnection() is not working correctly (Qiang)
+BUG: Ticket#246 - TDatePicker wrong popup position in scrolled div (Wei)
BUG: Ticket#260 - Wrong value of a configuration option in setUseTransparentSessionID (Qiang)
CHG: ensureChildControls() is now invoked in TControl::initRecursive (Qiang)
CHG: Postback enabled control will always disable default client-side browser action. (Qiang)
@@ -28,12 +31,15 @@ ENH: Ticket#231 - Added TButton.ButtonType property to allow reset button (Qiang ENH: Ticket#232 - Allow <%# %> and <%= %> embedded within property values (Qiang)
ENH: Ticket#256 - Datagrid columns can now be accessed via IDs (Qiang)
ENH: Ticket#257 - OnSelectedIndexChanged event of TDataList and TDataGrid now passes the original command parameter (Qiang)
+ENH: Ticket#262 - Added TCheckBox.Value property (Qiang)
ENH: TRepeater, TDataList and TDataGrid will store data indices in DataKeys if DataKeyField is not set. (Qiang)
ENH: Added TPageService.BasePageClass property (Qiang)
ENH: Added TDataGrid.EmptyTemplate property (Qiang)
ENH: Added paging feature to all TDataBoundControl-derived controls (Qiang)
+ENH: ClientSide.ObserveChanges="false" to only revalidate client side validator when control changes (Wei)
NEW: Added TPager (Qiang)
NEW: Added Dreamweaver taglib extension (Stanislav, Qiang)
+NEW: Prado Command line script to create a new project, see framework/prado-cli.php (Wei)
Version 3.0.1 June 4, 2006
==========================
diff --git a/demos/quickstart/protected/application.xml b/demos/quickstart/protected/application.xml index 79ee4529..3e2374d8 100644 --- a/demos/quickstart/protected/application.xml +++ b/demos/quickstart/protected/application.xml @@ -16,12 +16,8 @@ </modules>
<paths>
<using namespace="Application.controls.*" />
- <using namespace="Application.comments.*" />
</paths>
<services>
<service id="page" class="TPageService" DefaultPage="GettingStarted.Introduction" />
</services>
- <parameters>
- <parameter id="enableNewComment" value="false" />
- </parameters>
</application>
\ No newline at end of file diff --git a/demos/quickstart/protected/comments/CommentList.php b/demos/quickstart/protected/comments/CommentList.php deleted file mode 100644 index 3bfb7239..00000000 --- a/demos/quickstart/protected/comments/CommentList.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php - -Prado::using('System.I18N.*'); - -/** - * CommentList class. - * - * @author Wei Zhuo <weizhuo[at]gmail[dot]com> - * @version : $ Sat May 27 17:53:15 AZOST 2006 $ - * @package Demo.Quickstart.comments - * @since 3.0 - */ -class CommentList extends TTemplateControl -{ - private $_exclude = array( - 'Comments', - 'Markdown', - 'Search', - 'GettingStarted.Introduction'); - - private $_quickstart; - - public function onLoad($param) - { - parent::onLoad($param); - - $this->_quickstart = new QuickStartComments(); - - $page = $this->getService()->getRequestedPagePath(); - - $this->listComments($page); - } - - protected function listComments($page) - { - $this->comments->setDataSource($this->_quickstart->getComments($page)); - $this->comments->dataBind(); - } - - public function addComment_Clicked($sender, $param) - { - $page = $this->getService()->getRequestedPagePath(); - $this->_quickstart->addNewComment($page, - $this->email->getText(), $this->content->getText()); - $this->multiView1->setActiveViewIndex(1); - } - - public function setVisible($value) - { - $page = $this->getService()->getRequestedPagePath(); - if(in_array($page, $this->_exclude)) - parent::setVisible(false); - else - parent::setVisible($value); - } -} - -?>
\ No newline at end of file diff --git a/demos/quickstart/protected/comments/CommentList.tpl b/demos/quickstart/protected/comments/CommentList.tpl deleted file mode 100644 index 06cddd1e..00000000 --- a/demos/quickstart/protected/comments/CommentList.tpl +++ /dev/null @@ -1,105 +0,0 @@ -<div id="comments"> - -<com:TRepeater ID="comments"> - <prop:HeaderTemplate> - <h2 class="comment_header">Comments - <com:TPlaceHolder Visible=<%$ enableNewComment %> > - <span style="font-size:0.8em">( <a href="#add_comments">Add your comments</a> )</span> - </com:TPlaceHolder> - </h2> - </prop:HeaderTemplate> - <prop:ItemTemplate> - <div class="comment_item comment_item<%# $this->ItemIndex%2 %>"> - <span class="number" id="comment_<%# $this->ItemIndex+1 %>"><%# $this->ItemIndex+1 %></span> - <span class="email"> - <%# str_replace(array('@','.'),array(' at ',' dot '), strtoupper($this->DataItem['email'])) %> - </span> - <span class="date"> - <com:TDateFormat Value=<%# intval($this->DataItem['date_added']) %> /> - </span> - <div class="comment"> - <com:TSafeHtml> - <com:TMarkdown CssClass="source"> - <%# $this->DataItem['comment'] %> - </com:TMarkdown> - </com:TSafeHtml> - </div> - </div> - </prop:ItemTemplate> -</com:TRepeater> - -<com:TMultiView ID="multiView1" ActiveViewIndex="0" Visible=<%$ enableNewComment %> > - <com:TView ID="view1"> - <div id="add_comments" class="add_comments"> - <h3>Post a comment</h3> - <p><strong>Note:</strong> - Please only use the comments in relation to this page for - <ul> - <li>questions/critcisms/suggestions on the documentation,</li> - <li>small notes that can solve or clarify a particular problem or task.</li> - </ul> - If you experience errors please <a href="http://trac.pradosoft.com/newticket">file a ticket</a> - or <a href="http://www.pradosoft.com/forum/">ask at the forum</a>. - Please use the <a href="http://pradosoft.com/wiki/index.php/Main_Page">Prado wiki</a> for longer pieces and detailed solutions</a>. - </p> - <p>Comments will be periodically reviewed, integrated into the documentation and removed. - You may use <a href="?page=Markdown">markdown syntax</a> in your comment. </p> - - <div class="comment_email"> - <com:TLabel ID="email_label" Text="Email:" ForControl="email"/> - <com:TTextBox ID="email" /> - <com:TRequiredFieldValidator - ControlToValidate="email" - Display="Dynamic" - ErrorMessage="An email address is required." /> - <com:TEmailAddressValidator - ControlToValidate="email" - CheckMXRecord="false" - Display="Dynamic" - ErrorMessage="Please provide your email address."/> - </div> - <div class="comment_content"> - <com:TLabel ID="content_label" Text="Comment:" ForControl="content"/> - <com:TTextBox ID="content" TextMode="MultiLine"/> - <div class="please_add"> - <com:TRequiredFieldValidator - ControlToValidate="content" - Display="Dynamic" - ErrorMessage="Please add your comment." /> - </div> - </div> - <com:TPlaceHolder Visible=<%= strlen($this->content->Text) %> > - <div class="comment_preview"> - <h3 style="margin:0">Preview comment</h3> - <div class="comment"> - <com:TSafeHtml> - <com:TMarkdown CssClass="source"> - <%= $this->content->Text %> - </com:TMarkdown> - </com:TSafeHtml> - </div> - </div> - </com:TPlaceHolder> - <div class="add_comment"> - <com:TButton ID="previewComment" Text="Preview Comment" /> - <com:TButton ID="addComment" Text="Add Comment" OnClick="addComment_Clicked"/> - </div> - </div> - </com:TView> - <com:TView ID="view2"> - <div class="comment_added"> - <div class="thank">Thank you, your comment is quequed for moderation.</div> - <div class="comment_preview"> - <h3 style="margin:0">Preview comment</h3> - <div class="comment"> - <com:TSafeHtml> - <com:TMarkdown CssClass="source"> - <%= $this->content->Text %> - </com:TMarkdown> - </com:TSafeHtml> - </div> - </div> - </div> - </com:TView> -</com:TMultiView> -</div>
\ No newline at end of file diff --git a/demos/quickstart/protected/comments/QuickStartComments.php b/demos/quickstart/protected/comments/QuickStartComments.php deleted file mode 100644 index 7b504caf..00000000 --- a/demos/quickstart/protected/comments/QuickStartComments.php +++ /dev/null @@ -1,175 +0,0 @@ -<?php - -/** - * QuickStartComments class. - * - * @author Wei Zhuo <weizhuo[at]gmail[dot]com> - * @version : $ Sat May 27 16:49:19 AZOST 2006 $ - * @package Demos.QuickStart.comments - * @since 3.0 - */ -class QuickStartComments -{ - /** - * @var string sqlite database source. - */ - private $_database; - /** - * @var sqlite connection. - */ - private $_connection; - - /** - * Sets the sqlite comment database file. - */ - public function __construct() - { - $this->_database = realpath(dirname(__FILE__).'/comments.db'); - } - - /** - * Closed the database connection. - */ - public function __destruct() - { - if(!is_null($this->_connection)) - sqlite_close($this->_connection); - } - - /** - * @return resource sqlite database connection. - */ - protected function getConnection() - { - if(is_null($this->_connection)) - $this->_connection = sqlite_open($this->_database); - return $this->_connection; - } - - /** - * Quote database input data. - */ - protected function quote($value) - { - return sqlite_escape_string($value); - } - - /** - * Executes an sqlite query. - * @param string SQL - * @return mixed query results. - */ - protected function query($sql) - { - return sqlite_query($this->getConnection(), $sql); - } - - /** - * Returns a row from the sqlite result. - * @param resource sqlite result - * @return array database record. - */ - protected function fetch($resource) - { - if($resource !== false) - return sqlite_fetch_array($resource); - else - return false; - } - - /** - * Fetch all the records for given SQL query. - * @param string SQL query. - * @return array result set. - */ - protected function fetchAll($sql) - { - $rs = $this->query($sql); - $rows = array(); - while($row = $this->fetch($rs)) - $rows[] = $row; - return $rows; - } - - /** - * Returns all the comments for a given page. - * @param string specific page comments - * @return array list of comments - */ - public function getComments($pageID) - { - $page = $this->quote($pageID); - $sql = "SELECT * FROM comments WHERE page='$page' AND approved = 1 ORDER BY date_added ASC"; - return $this->fetchAll($sql); - } - - /** - * Adds a new comment for moderation. - * @param string ID of the page to comment belongs - * @param string email address of the commenter - * @param string comment contents - */ - public function addNewComment($pageID, $email, $comment) - { - $page = $this->quote($pageID); - $email = $this->quote($email); - $comment = $this->quote($comment); - $date_added = time(); - $sql = <<<EOD - INSERT INTO comments(page, email, comment, date_added) - VALUES ('$page', '$email', '$comment', '$date_added') -EOD; - return $this->query($sql); - } - - /** - * Update an existing comment. - * @param string comment ID - * @param string page ID - * @param string email address - * @param string updated comment. - */ - public function updateComment($commentID, $page, $email, $content) - { - $ID = intval($commentID); - $email = $this->quote($email); - $comment = $this->quote($content); - $page = $this->quote($page); - $sql = <<<EOD - UPDATE comments SET - email = '$email', comment = '$comment', page = '$page' - WHERE id = $ID; -EOD; - $this->query($sql); - } - - /** - * Delete a comment. - * @param string comment ID - */ - public function deleteComment($commentID) - { - $ID = intval($commentID); - $this->query("DELETE FROM comments WHERE id=$ID"); - } - - /** - * @return array all the quequed comments. - */ - public function getQuequedComments() - { - return $this->fetchAll("SELECT * FROM comments WHERE approved != 1"); - } - - /** - * Approve a quequed comment. - * @param string comment ID. - */ - public function approveComment($commentID) - { - $ID = intval($commentID); - $this->query("UPDATE comments SET approved = 1 WHERE id=$ID"); - } -} - -?>
\ No newline at end of file diff --git a/demos/quickstart/protected/comments/comments.db b/demos/quickstart/protected/comments/comments.db Binary files differdeleted file mode 100644 index b81d7123..00000000 --- a/demos/quickstart/protected/comments/comments.db +++ /dev/null diff --git a/demos/quickstart/protected/controls/Layout.tpl b/demos/quickstart/protected/controls/Layout.tpl index 733bf6e1..52ab5bc4 100644 --- a/demos/quickstart/protected/controls/Layout.tpl +++ b/demos/quickstart/protected/controls/Layout.tpl @@ -32,7 +32,6 @@ <div id="content">
<com:TContentPlaceHolder ID="body" />
</div>
-<com:CommentList Visible="true" />
</td>
</tr>
</table>
diff --git a/framework/Util/TLogRouter.php b/framework/Util/TLogRouter.php index fe0d2964..a9d37b2f 100644 --- a/framework/Util/TLogRouter.php +++ b/framework/Util/TLogRouter.php @@ -22,8 +22,8 @@ * or an external configuration file specified by {@link setConfigFile ConfigFile}.
* The format is as follows,
* <code>
- * <route class="TFileLogRoute" Categories="System.Web.UI" Levels="Warning" />
- * <route class="TEmailLogRoute" Categories="Application" Levels="Fatal" Emails="admin@pradosoft.com" />
+ * <route class="TFileLogRoute" Categories="System.Web.UI" Levels="Warning" />
+ * <route class="TEmailLogRoute" Categories="Application" Levels="Fatal" Emails="admin@pradosoft.com" />
* </code>
* You can specify multiple routes with different filtering conditions and different
* targets, even if the routes are of the same type.
diff --git a/framework/Web/Javascripts/colorpicker/colorpicker.js b/framework/Web/Javascripts/colorpicker/colorpicker.js index 06cfb037..acf5531c 100644 --- a/framework/Web/Javascripts/colorpicker/colorpicker.js +++ b/framework/Web/Javascripts/colorpicker/colorpicker.js @@ -68,7 +68,7 @@ Object.extend(Prado.WebUI.TColorPicker.prototype, {
var constructor = mode == "Basic" ? "getBasicPickerContainer": "getFullPickerContainer"
this.element = this[constructor](this.options['ID'], this.options['Palette'])
- document.body.appendChild(this.element);
+ this.input.parentNode.appendChild(this.element);
this.element.style.display = "none";
if(Prado.Browser().ie)
@@ -90,7 +90,7 @@ Object.extend(Prado.WebUI.TColorPicker.prototype, {
if(!this.showing)
{
- var pos = Position.cumulativeOffset(this.input);
+ var pos = Position.positionedOffset(this.input);
pos[1] += this.input.offsetHeight;
this.element.style.top = (pos[1]-1) + "px";
diff --git a/framework/Web/Javascripts/colorpicker/spacer.gif b/framework/Web/Javascripts/colorpicker/spacer.gif Binary files differnew file mode 100755 index 00000000..fc256098 --- /dev/null +++ b/framework/Web/Javascripts/colorpicker/spacer.gif diff --git a/framework/Web/Javascripts/datepicker/datepicker.js b/framework/Web/Javascripts/datepicker/datepicker.js index 11bee07e..4525c1ba 100644 --- a/framework/Web/Javascripts/datepicker/datepicker.js +++ b/framework/Web/Javascripts/datepicker/datepicker.js @@ -247,10 +247,10 @@ Prado.WebUI.TDatePicker.prototype = this.iePopUp.style.position = "absolute"
this.iePopUp.scrolling="no"
this.iePopUp.frameBorder="0"
- document.body.appendChild(this.iePopUp);
+ this.control.parentNode.appendChild(this.iePopUp);
}
- document.body.appendChild(this._calDiv);
+ this.control.parentNode.appendChild(this._calDiv);
this.update();
this.updateHeader();
@@ -542,8 +542,8 @@ Prado.WebUI.TDatePicker.prototype = if(!this.showing)
{
- var pos = Position.cumulativeOffset(this.control);
-
+ var pos = Position.positionedOffset(this.control);
+
pos[1] += this.getDatePickerOffsetHeight();
this._calDiv.style.display = "block";
diff --git a/framework/Web/Javascripts/js/colorpicker.js b/framework/Web/Javascripts/js/colorpicker.js index 47949239..8429b5e6 100644 --- a/framework/Web/Javascripts/js/colorpicker.js +++ b/framework/Web/Javascripts/js/colorpicker.js @@ -33,7 +33,7 @@ Event.observe(this.button,"click",this._buttonOnClick);Event.observe(this.input, {var mode=this.options['Mode'];if(this.element==null) {var constructor=mode=="Basic"?"getBasicPickerContainer":"getFullPickerContainer" this.element=this[constructor](this.options['ID'],this.options['Palette']) -document.body.appendChild(this.element);this.element.style.display="none";if(Prado.Browser().ie) +this.input.parentNode.appendChild(this.element);this.element.style.display="none";if(Prado.Browser().ie) {this.iePopUp=document.createElement('iframe');this.iePopUp.src=Prado.WebUI.TColorPicker.UIImages['button.gif'];this.iePopUp.style.position="absolute" this.iePopUp.scrolling="no" this.iePopUp.frameBorder="0" @@ -42,7 +42,7 @@ if(mode=="Full") this.initializeFullPicker();} this.show(mode);},show:function(type) {if(!this.showing) -{var pos=Position.cumulativeOffset(this.input);pos[1]+=this.input.offsetHeight;this.element.style.top=(pos[1]-1)+"px";this.element.style.left=pos[0]+"px";this.element.style.display="block";this.ieHack(type);this._documentClickEvent=this.hideOnClick.bindEvent(this,type);this._documentKeyDownEvent=this.keyPressed.bindEvent(this,type);Event.observe(document.body,"click",this._documentClickEvent);Event.observe(document,"keydown",this._documentKeyDownEvent);this.showing=true;if(type=="Full") +{var pos=Position.positionedOffset(this.input);pos[1]+=this.input.offsetHeight;this.element.style.top=(pos[1]-1)+"px";this.element.style.left=pos[0]+"px";this.element.style.display="block";this.ieHack(type);this._documentClickEvent=this.hideOnClick.bindEvent(this,type);this._documentKeyDownEvent=this.keyPressed.bindEvent(this,type);Event.observe(document.body,"click",this._documentClickEvent);Event.observe(document,"keydown",this._documentKeyDownEvent);this.showing=true;if(type=="Full") {this.observeMouseMovement();var color=Rico.Color.createFromHex(this.input.value);this.inputs.oldColor.style.backgroundColor=color.asHex();this.setColor(color,true);}}},hide:function(event) {if(this.showing) {if(this.iePopUp) diff --git a/framework/Web/Javascripts/js/datepicker.js b/framework/Web/Javascripts/js/datepicker.js index 090f3cbd..bbf81293 100644 --- a/framework/Web/Javascripts/js/datepicker.js +++ b/framework/Web/Javascripts/js/datepicker.js @@ -22,8 +22,8 @@ div=document.createElement("div");div.className="calendarFooter";this._calDiv.ap {this.iePopUp=document.createElement('iframe');this.iePopUp.src=Prado.WebUI.TDatePicker.spacer;this.iePopUp.style.position="absolute" this.iePopUp.scrolling="no" this.iePopUp.frameBorder="0" -document.body.appendChild(this.iePopUp);} -document.body.appendChild(this._calDiv);this.update();this.updateHeader();this.ieHack(true);previousMonth.hideFocus=true;nextMonth.hideFocus=true;todayButton.hideFocus=true;Event.observe(previousMonth,"click",this.prevMonth.bindEvent(this));Event.observe(nextMonth,"click",this.nextMonth.bindEvent(this));Event.observe(todayButton,"click",this.selectToday.bindEvent(this));Event.observe(this._monthSelect,"change",this.monthSelect.bindEvent(this));Event.observe(this._yearSelect,"change",this.yearSelect.bindEvent(this));Event.observe(this._calDiv,"mousewheel",this.mouseWheelChange.bindEvent(this));Event.observe(calendarBody,"click",this.selectDate.bindEvent(this));Prado.Element.focus(this.control);},ieHack:function(cleanup) +this.control.parentNode.appendChild(this.iePopUp);} +this.control.parentNode.appendChild(this._calDiv);this.update();this.updateHeader();this.ieHack(true);previousMonth.hideFocus=true;nextMonth.hideFocus=true;todayButton.hideFocus=true;Event.observe(previousMonth,"click",this.prevMonth.bindEvent(this));Event.observe(nextMonth,"click",this.nextMonth.bindEvent(this));Event.observe(todayButton,"click",this.selectToday.bindEvent(this));Event.observe(this._monthSelect,"change",this.monthSelect.bindEvent(this));Event.observe(this._yearSelect,"change",this.yearSelect.bindEvent(this));Event.observe(this._calDiv,"mousewheel",this.mouseWheelChange.bindEvent(this));Event.observe(calendarBody,"click",this.selectDate.bindEvent(this));Prado.Element.focus(this.control);},ieHack:function(cleanup) {if(this.iePopUp) {this.iePopUp.style.display="block";this.iePopUp.style.top=(this._calDiv.offsetTop-1)+"px";this.iePopUp.style.left=(this._calDiv.offsetLeft-1)+"px";this.iePopUp.style.width=Math.abs(this._calDiv.offsetWidth-2)+"px";this.iePopUp.style.height=(this._calDiv.offsetHeight+1)+"px";if(cleanup)this.iePopUp.style.display="none";}},keyPressed:function(ev) {if(!this.showing)return;if(!ev)ev=document.parentWindow.event;var kc=ev.keyCode!=null?ev.keyCode:ev.charCode;if(kc==Event.KEY_RETURN||kc==Event.KEY_SPACEBAR||kc==Event.KEY_TAB) @@ -92,7 +92,7 @@ this.onChange();},getElement:function() {if(this.options.InputMode=="TextBox") return this.control.offsetHeight;var control=Prado.WebUI.TDatePicker.getDayListControl(this.control);if(control)return control.offsetHeight;var control=Prado.WebUI.TDatePicker.getMonthListControl(this.control);if(control)return control.offsetHeight;var control=Prado.WebUI.TDatePicker.getYearListControl(this.control);if(control)return control.offsetHeight;return 0;},show:function() {this.create();if(!this.showing) -{var pos=Position.cumulativeOffset(this.control);pos[1]+=this.getDatePickerOffsetHeight();this._calDiv.style.display="block";this._calDiv.style.top=(pos[1]-1)+"px";this._calDiv.style.left=pos[0]+"px";this.ieHack(false);this.documentClickEvent=this.hideOnClick.bindEvent(this);this.documentKeyDownEvent=this.keyPressed.bindEvent(this);Event.observe(document.body,"click",this.documentClickEvent);var date=this.getDateFromInput();if(date) +{var pos=Position.positionedOffset(this.control);pos[1]+=this.getDatePickerOffsetHeight();this._calDiv.style.display="block";this._calDiv.style.top=(pos[1]-1)+"px";this._calDiv.style.left=pos[0]+"px";this.ieHack(false);this.documentClickEvent=this.hideOnClick.bindEvent(this);this.documentKeyDownEvent=this.keyPressed.bindEvent(this);Event.observe(document.body,"click",this.documentClickEvent);var date=this.getDateFromInput();if(date) {this.selectedDate=date;this.setSelectedDate(date);} Event.observe(document,"keydown",this.documentKeyDownEvent);this.showing=true;}},getDateFromInput:function() {if(this.options.InputMode=="TextBox") diff --git a/framework/Web/UI/WebControls/TBaseValidator.php b/framework/Web/UI/WebControls/TBaseValidator.php index a0801d4c..9366de62 100644 --- a/framework/Web/UI/WebControls/TBaseValidator.php +++ b/framework/Web/UI/WebControls/TBaseValidator.php @@ -124,7 +124,7 @@ abstract class TBaseValidator extends TLabel implements IValidator } /** - * Adds attributes to renderer. Calls parent implementation and renders the + * Adds attributes to renderer. Calls parent implementation and renders the * client control scripts. * @param THtmlWriter the renderer */ @@ -237,7 +237,7 @@ abstract class TBaseValidator extends TLabel implements IValidator $this->registerClientScriptValidator(); $this->updateControlCssClass(); } - + /** * Update the ControlToValidate component's css class depending * if the ControlCssClass property is set, and whether this is valid. @@ -635,6 +635,25 @@ class TClientSideValidatorOptions extends TClientSideOptions } /** + * @param boolean true to revalidate when the control to validate changes value. + */ + public function setObserveChanges($value) + { + $this->setOption('ObserveChanges', TPropertyValue::ensureBoolean($value)); + } + + /** + * @return boolean true to observe changes. + */ + public function getObserveChanges() + { + if(($option=$this->getOption('ObserveChanges'))!==null) + return $option; + else + return true; + } + + /** * Ensure the string is a valid javascript function. If the string begins * with "javascript:" valid javascript function is assumed, otherwise the * code block is enclosed with "function(validator, sender){ }" block. diff --git a/framework/Web/UI/WebControls/TCheckBox.php b/framework/Web/UI/WebControls/TCheckBox.php index 6fe562c9..04733f95 100644 --- a/framework/Web/UI/WebControls/TCheckBox.php +++ b/framework/Web/UI/WebControls/TCheckBox.php @@ -60,13 +60,10 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl public function loadPostData($key,$values)
{
$checked=$this->getChecked();
- if(isset($values[$key])!=$checked)
- {
- $this->setChecked(!$checked);
- return true;
- }
- else
- return false;
+ if($newChecked=isset($values[$key]))
+ $this->setValue($values[$key]);
+ $this->setChecked($newChecked);
+ return $newChecked!==$checked;
}
/**
@@ -134,6 +131,22 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl }
/**
+ * @return string the value of the checkbox. Defaults to empty.
+ */
+ public function getValue()
+ {
+ return $this->getViewState('Value','');
+ }
+
+ /**
+ * @param string the value of the checkbox
+ */
+ public function setValue($value)
+ {
+ $this->setViewState('Value',$value,'');
+ }
+
+ /**
* @return string the alignment (Left or Right) of the text caption, defaults to Right.
*/
public function getTextAlign()
@@ -309,13 +322,18 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl */
protected function getValueAttribute()
{
- $attributes=$this->getViewState('InputAttributes',null);
- if($attributes && $attributes->contains('value'))
- return $attributes->itemAt('value');
- else if($this->hasAttribute('value'))
- return $this->getAttribute('value');
+ if(($value=$this->getValue())!=='')
+ return $value;
else
- return '';
+ {
+ $attributes=$this->getViewState('InputAttributes',null);
+ if($attributes && $attributes->contains('value'))
+ return $attributes->itemAt('value');
+ else if($this->hasAttribute('value'))
+ return $this->getAttribute('value');
+ else
+ return '';
+ }
}
/**
@@ -345,7 +363,7 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl if($clientID!=='')
$writer->addAttribute('id',$clientID);
$writer->addAttribute('type','checkbox');
- if(($value = $this->getValueAttribute()) !== '')
+ if(($value=$this->getValueAttribute())!=='')
$writer->addAttribute('value',$value);
if(!empty($onclick))
$writer->addAttribute('onclick',$onclick);
diff --git a/framework/Web/UI/WebControls/THtmlArea.php b/framework/Web/UI/WebControls/THtmlArea.php index 09f8328c..2a1e311d 100644 --- a/framework/Web/UI/WebControls/THtmlArea.php +++ b/framework/Web/UI/WebControls/THtmlArea.php @@ -219,7 +219,7 @@ class THtmlArea extends TTextBox */
protected function addAttributesToRender($writer)
{
- if($this->getEnableVisualEdit())
+ if($this->getEnableVisualEdit() && $this->getEnabled(true))
{
$writer->addAttribute('id',$this->getClientID());
$this->registerEditorClientScript($writer);
diff --git a/framework/Web/UI/WebControls/TRadioButton.php b/framework/Web/UI/WebControls/TRadioButton.php index bb3e0658..2bbdf22e 100644 --- a/framework/Web/UI/WebControls/TRadioButton.php +++ b/framework/Web/UI/WebControls/TRadioButton.php @@ -101,6 +101,9 @@ class TRadioButton extends TCheckBox $this->setViewState('GroupName',$value,'');
}
+ /**
+ * @return string the value attribute to be rendered
+ */
protected function getValueAttribute()
{
if(($value=parent::getValueAttribute())==='')
diff --git a/tests/FunctionalTests/index.php b/tests/FunctionalTests/index.php index ceba599a..c4b3123b 100644 --- a/tests/FunctionalTests/index.php +++ b/tests/FunctionalTests/index.php @@ -14,4 +14,4 @@ Prado Functional Test Suites <li><a href="features.php">Tests of New Features</a> (<a href="features/index.php">list of new features</a>)</li> </ul> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/FunctionalTests/tickets/protected/pages/Home.page b/tests/FunctionalTests/tickets/protected/pages/Home.page new file mode 100755 index 00000000..d4ac162c --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Home.page @@ -0,0 +1,3 @@ +<com:TContent ID="Content"> +<com:TBulletedList ID="List" DisplayMode="HyperLink"/> +</com:TContent>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/protected/pages/Home.php b/tests/FunctionalTests/tickets/protected/pages/Home.php new file mode 100755 index 00000000..37804419 --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Home.php @@ -0,0 +1,34 @@ +<?php + +class Home extends TPage +{ + public function onLoad($param) + { + parent::onLoad($param); + $list=$this->getPageList(dirname(__FILE__),''); + $this->List->DataSource=$list; + $this->List->dataBind(); + } + + protected function getPageList($directory,$basePath) + { + $list=array(); + $folder=@opendir($directory); + while($entry=@readdir($folder)) + { + if($entry[0]==='.') + continue; + else if(is_file($directory.'/'.$entry)) + { + if(($page=basename($entry,'.page'))!==$entry && strpos($page,'.')===false) + $list['?page='.$basePath.$page]=$basePath.$page; + } + else + $list=array_merge($list,$this->getPageList($directory.'/'.$entry,$basePath.$entry.'.')); + } + closedir($folder); + return $list; + } +} + +?>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket200.page b/tests/FunctionalTests/tickets/protected/pages/Ticket200.page new file mode 100644 index 00000000..76c60f40 --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Ticket200.page @@ -0,0 +1,6 @@ +<com:TContent ID="Content"> + <com:TLinkButton ID="linkButton1" Text="Click Me" OnClick="linkButton1_Clicked" /> + <p style="height:500px"><br /></p> + <com:TLinkButton ID="linkButton2" Text="Click Me" OnClick="linkButton2_Clicked" /> + <p style="height:500px"></br></p> +</com:TContent>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket200.php b/tests/FunctionalTests/tickets/protected/pages/Ticket200.php new file mode 100644 index 00000000..a80a3b8a --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Ticket200.php @@ -0,0 +1,16 @@ +<?php + +class Ticket200 extends TPage +{ + function linkButton1_Clicked() + { + + } + + function linkButton2_Clicked() + { + + } +} + +?>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket202.page b/tests/FunctionalTests/tickets/protected/pages/Ticket202.page new file mode 100644 index 00000000..ae984c2d --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Ticket202.page @@ -0,0 +1,19 @@ +<%@ MasterPage="" %> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" > + +<com:THead ID="Head"> + <meta http-equiv="content-language" content="en"/> + <meta http-equiv="Expires" content="0"> +</com:THead> + +<body> +<com:TForm> +<com:TTextBox MaxLength="50" /> +<com:TTextBox ID="CustomerNumber" /> +<com:TButton Text="Search" /> +<com:TDataTypeValidator DataType="Integer" ControlToValidate="CustomerNumber" ErrorMessage="Customernumber must be a number." /> + +</com:TForm> +</body> +</html>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket205.page b/tests/FunctionalTests/tickets/protected/pages/Ticket205.page new file mode 100644 index 00000000..1481a227 --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Ticket205.page @@ -0,0 +1,26 @@ +<com:TContent ID="Content"> + <h3>TCustomValidator not enabling ControlCssClass or prop:ClientSide.OnError after postback.</h3> + <style> + .required + { + border: 1px solid red; + background-color: pink; + } + </style> + <script type="text/javascript"> + function clientSideCustomValidate(sender, param) + { + return param == "Prado"; + } + </script> + <com:TTextBox ID="textbox1" /> + <com:TCustomValidator + ID="validator1" + ControlToValidate="textbox1" + ControlCssClass="required" + OnServerValidate="customValidate" + ClientValidationFunction="clientSideCustomValidate" + ClientSide.OnError="alert('error')" + ErrorMessage="must equal to 'Prado'" /> + <com:TButton ID="button1" Text="Submit!" /> +</com:TContent>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket205.php b/tests/FunctionalTests/tickets/protected/pages/Ticket205.php new file mode 100644 index 00000000..6145af9a --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Ticket205.php @@ -0,0 +1,11 @@ +<?php + +class Ticket205 extends TPage +{ + function customValidate($sender, $param) + { + $param->IsValid = $this->textbox1->Text == "Prado"; + } +} + +?>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket207.page b/tests/FunctionalTests/tickets/protected/pages/Ticket207.page new file mode 100644 index 00000000..556c5aae --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Ticket207.page @@ -0,0 +1,24 @@ +<com:TContent ID="Content"> + <h2>Validators ClientSide.OnError triggered twice</h2> + <h3>Use ClientSide.ObseveChanges="false"</h3> + <com:TTextBox ID="text1" /><br /> + <com:TRequiredFieldValidator + id="validator1" + ControlToValidate="text1" Text="Error" + ClientSide.ObserveChanges="false" + ClientSide.OnError="alert('error on text1 fired')" /> + <br /> + <com:TTextBox ID="text2" /><br /> + <com:TRequiredFieldValidator id="validator2" ControlToValidate="text2" Text="Error" /> + <br /> + <com:TButton id="button1" Text="submit" /> + <h3>Conditions</h3> +<pre> + (TextBox? B is just there to prevent server submission) + To verify try exactly this: + + 1. Enter nothing and click on submit : 1 error event will be triggered + 2. Enter something into TextBox? T and click on submit : no error event (ok) + 3. Delete your text from TextBox? T again and click on submit : error event will be triggered twice +</pre> +</com:TContent>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket227.page b/tests/FunctionalTests/tickets/protected/pages/Ticket227.page new file mode 100644 index 00000000..ab481fa2 --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Ticket227.page @@ -0,0 +1,4 @@ +<com:TContent ID="Content"> + <h2>Disabled HTMLArea</h2> + <com:THtmlArea ID="htmlArea1" Width="500px" Height="250px" Enabled="false"/> +</com:TContent>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket246.page b/tests/FunctionalTests/tickets/protected/pages/Ticket246.page new file mode 100644 index 00000000..e25a484b --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Ticket246.page @@ -0,0 +1,17 @@ +<com:TContent ID="Content"> + <h2>TDatePicker inside absolute DIV with scrollbar</h2> + + <div style="position:absolute; top:100px; + width: 400px; background-color: #fee; + overflow: scroll; + border:1px solid red; height:350px; text-align:center"> + <p style="height:200px; background-color: #eef;"></p> + <com:TDatePicker ID="datePicker1" DateFormat="dd/MM/yyyy" InputMode="DropDownList" /> + <br /><br /> + <com:TDropDownList ID="dropDownList1"> + <com:TListItem Value="value 1" Text="item 1" /> + <com:TListItem Value="value 2" Text="item 2" /> + </com:TDropDownList> + <p style="height:400px; width:600px; background-color:#efe;"></p> + </div> +</com:TContent>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/tests/Ticket205TestCase.php b/tests/FunctionalTests/tickets/tests/Ticket205TestCase.php new file mode 100644 index 00000000..85785697 --- /dev/null +++ b/tests/FunctionalTests/tickets/tests/Ticket205TestCase.php @@ -0,0 +1,23 @@ +<?php + +class Ticket205TestCase extends SeleniumTestCase +{ + function test() + { + $base = 'ctl0_Content_'; + $this->open("tickets/index.php?page=Ticket205"); + $this->assertTitle("Verifying Ticket 205"); + $this->assertNotVisible("{$base}validator1"); + + $this->type("{$base}textbox1", "test"); + $this->click("{$base}button1"); + $this->assertVisible("{$base}validator1"); + $this->assertAlert("error"); + + $this->type("{$base}textbox1", "Prado"); + $this->clickAndWait("{$base}button1"); + $this->assertNotVisible("{$base}validator1"); + } +} + +?>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/tests/Ticket207TestCase.php b/tests/FunctionalTests/tickets/tests/Ticket207TestCase.php new file mode 100644 index 00000000..53ae6528 --- /dev/null +++ b/tests/FunctionalTests/tickets/tests/Ticket207TestCase.php @@ -0,0 +1,37 @@ +<?php + +class Ticket207TestCase extends SeleniumTestCase +{ + function test() + { + $base = 'ctl0_Content_'; + $this->open('tickets/index.php?page=Ticket207'); + $this->assertTitle("Verifying Ticket 207"); + $this->assertNotVisible("{$base}validator1"); + $this->assertNotVisible("{$base}validator2"); + + $this->click("{$base}button1"); + $this->assertAlert('error on text1 fired'); + $this->assertVisible("{$base}validator1"); + $this->assertVisible("{$base}validator2"); + + $this->type("{$base}text1", 'test'); + $this->assertVisible("{$base}validator1"); + $this->assertVisible("{$base}validator2"); + + $this->click("{$base}button1"); + $this->assertNotVisible("{$base}validator1"); + $this->assertVisible("{$base}validator2"); + + $this->type("{$base}text1", ''); + $this->assertNotVisible("{$base}validator1"); + $this->assertVisible("{$base}validator2"); + + $this->click("{$base}button1"); + $this->assertAlert('error on text1 fired'); + $this->assertVisible("{$base}validator1"); + $this->assertVisible("{$base}validator2"); + } +} + +?>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/tests/Ticket227TestCase.php b/tests/FunctionalTests/tickets/tests/Ticket227TestCase.php new file mode 100644 index 00000000..c0dd2a98 --- /dev/null +++ b/tests/FunctionalTests/tickets/tests/Ticket227TestCase.php @@ -0,0 +1,12 @@ +<?php + +class Ticket227TestCase extends SeleniumTestCase +{ + function test() + { + $this->open('tickets/index.php?page=Ticket227'); + $this->assertTitle('Verifying Ticket 227'); + } +} + +?>
\ No newline at end of file diff --git a/tests/FunctionalTests/tickets/tests/Ticket246TestCase.php b/tests/FunctionalTests/tickets/tests/Ticket246TestCase.php new file mode 100644 index 00000000..8f07790e --- /dev/null +++ b/tests/FunctionalTests/tickets/tests/Ticket246TestCase.php @@ -0,0 +1,12 @@ +<?php + +class Ticket246TestCase extends SeleniumTestCase +{ + function test() + { + $this->open('tickets/index.php?page=Ticket246'); + $this->assertTitle('Verifying Ticket 246'); + } +} + +?>
\ No newline at end of file diff --git a/tests/FunctionalTests/validators/protected/pages/Home.page b/tests/FunctionalTests/validators/protected/pages/Home.page new file mode 100755 index 00000000..d4ac162c --- /dev/null +++ b/tests/FunctionalTests/validators/protected/pages/Home.page @@ -0,0 +1,3 @@ +<com:TContent ID="Content"> +<com:TBulletedList ID="List" DisplayMode="HyperLink"/> +</com:TContent>
\ No newline at end of file diff --git a/tests/FunctionalTests/validators/protected/pages/Home.php b/tests/FunctionalTests/validators/protected/pages/Home.php new file mode 100755 index 00000000..37804419 --- /dev/null +++ b/tests/FunctionalTests/validators/protected/pages/Home.php @@ -0,0 +1,34 @@ +<?php + +class Home extends TPage +{ + public function onLoad($param) + { + parent::onLoad($param); + $list=$this->getPageList(dirname(__FILE__),''); + $this->List->DataSource=$list; + $this->List->dataBind(); + } + + protected function getPageList($directory,$basePath) + { + $list=array(); + $folder=@opendir($directory); + while($entry=@readdir($folder)) + { + if($entry[0]==='.') + continue; + else if(is_file($directory.'/'.$entry)) + { + if(($page=basename($entry,'.page'))!==$entry && strpos($page,'.')===false) + $list['?page='.$basePath.$page]=$basePath.$page; + } + else + $list=array_merge($list,$this->getPageList($directory.'/'.$entry,$basePath.$entry.'.')); + } + closedir($folder); + return $list; + } +} + +?>
\ No newline at end of file |