From 407aa2ff5d56859fcd1f47b85b4c4180d035c428 Mon Sep 17 00:00:00 2001
From: wei <>
Date: Sat, 21 Jan 2006 02:07:59 +0000
Subject: Fixed DefaultButton and TLinkButton
---
framework/Web/Javascripts/extended/base.js | 2 +-
framework/Web/Javascripts/extended/event.js | 33 +++++++-
framework/Web/Javascripts/js/prado.js | 59 ++++++++++---
framework/Web/Javascripts/prado/controls.js | 66 +++++----------
framework/Web/UI/TClientScriptManager.php | 31 ++++++-
framework/Web/UI/WebControls/TButton.php | 3 +
framework/Web/UI/WebControls/TDatePicker.php | 98 ++++++++++++++++++++--
framework/Web/UI/WebControls/TPanel.php | 9 +-
.../pages/UI/TestTPanelDefaultButton.page | 4 +-
.../protected/pages/UI/TestTPanelDefaultButton.php | 22 +++++
10 files changed, 246 insertions(+), 81 deletions(-)
diff --git a/framework/Web/Javascripts/extended/base.js b/framework/Web/Javascripts/extended/base.js
index e3ca729b..48927b75 100644
--- a/framework/Web/Javascripts/extended/base.js
+++ b/framework/Web/Javascripts/extended/base.js
@@ -29,6 +29,6 @@ function $(n,d) {
Function.prototype.bindEvent = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function(event) {
- return __method.call(object, event || window.event, args);
+ return __method.apply(object, [event || window.event].concat(args));
}
}
diff --git a/framework/Web/Javascripts/extended/event.js b/framework/Web/Javascripts/extended/event.js
index a7514cda..b6dccf3b 100644
--- a/framework/Web/Javascripts/extended/event.js
+++ b/framework/Web/Javascripts/extended/event.js
@@ -26,12 +26,39 @@ Object.extend(Event, {
return e.keyCode != null ? e.keyCode : e.charCode
},
+ isHTMLEvent : function(type)
+ {
+ var events = ['abort', 'blur', 'change', 'error', 'focus', 'load', 'reset', 'resize', 'scroll', 'select', 'submit', 'unload'];
+ return events.include(type);
+ },
+
+ isMouseEvent : function(type)
+ {
+ var events = ['click', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup'];
+ return events.include(type);
+ },
+
fireEvent : function(element,type)
{
if(document.createEvent)
- {
- var event = document.createEvent('HTMLEvents');
- event.initEvent(type, true, true);
+ {
+ if(Event.isHTMLEvent(type))
+ {
+ var event = document.createEvent('HTMLEvents');
+ event.initEvent(type, true, true);
+ }
+ else if(Event.isMouseEvent(type))
+ {
+ var event = document.createEvent('MouseEvents');
+ event.initMouseEvent(type,true,true,
+ document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
+ }
+ else
+ {
+ if(Logger)
+ Logger.error("undefined event", type);
+ return;
+ }
element.dispatchEvent(event);
}
else if(element.fireEvent)
diff --git a/framework/Web/Javascripts/js/prado.js b/framework/Web/Javascripts/js/prado.js
index 590882fa..f411cbcf 100644
--- a/framework/Web/Javascripts/js/prado.js
+++ b/framework/Web/Javascripts/js/prado.js
@@ -193,7 +193,7 @@ return x;
Function.prototype.bindEvent=function(){
var _6=this,args=$A(arguments),object=args.shift();
return function(_7){
-return _6.call(object,_7||window.event,args);
+return _6.apply(object,[_7||window.event].concat(args));
};
};
@@ -1140,17 +1140,35 @@ _9="keydown";
this._observeAndCache(_8,_9,_10,_11);
},keyCode:function(e){
return e.keyCode!=null?e.keyCode:e.charCode;
-},fireEvent:function(_13,_14){
+},isHTMLEvent:function(_13){
+var _14=["abort","blur","change","error","focus","load","reset","resize","scroll","select","submit","unload"];
+return _14.include(_13);
+},isMouseEvent:function(_15){
+var _16=["click","mousedown","mousemove","mouseout","mouseover","mouseup"];
+return _16.include(_15);
+},fireEvent:function(_17,_18){
if(document.createEvent){
-var _15=document.createEvent("HTMLEvents");
-_15.initEvent(_14,true,true);
-_13.dispatchEvent(_15);
+if(Event.isHTMLEvent(_18)){
+var _19=document.createEvent("HTMLEvents");
+_19.initEvent(_18,true,true);
}else{
-if(_13.fireEvent){
-_13.fireEvent("on"+_14);
-_13[_14]();
+if(Event.isMouseEvent(_18)){
+var _19=document.createEvent("MouseEvents");
+_19.initMouseEvent(_18,true,true,document.defaultView,1,0,0,0,0,false,false,false,false,0,null);
}else{
-_13[_14]();
+if(Logger){
+Logger.error("undefined event",_18);
+}
+return;
+}
+}
+_17.dispatchEvent(_19);
+}else{
+if(_17.fireEvent){
+_17.fireEvent("on"+_18);
+_17[_18]();
+}else{
+_17[_18]();
}
}
}});
@@ -2372,7 +2390,7 @@ _41.set(_42);
Prado.WebUI=Class.create();
Prado.WebUI.PostBackControl=Class.create();
Object.extend(Prado.WebUI.PostBackControl.prototype,{initialize:function(_1){
-this.element=$(_1["ID"]);
+this.control=$(_1["ID"]);
if(_1["CausesValidation"]&&Prado.Validation){
Prado.Validation.AddTarget(_1["ID"],_1["ValidationGroup"]);
}
@@ -2390,7 +2408,7 @@ return _3;
};
Prado.WebUI.TButton=Prado.WebUI.createPostBackComponent();
Prado.WebUI.ClickableComponent=Prado.WebUI.createPostBackComponent({onInit:function(_4){
-Event.observe(this.element,"click",Prado.PostBack.bindEvent(this,_4));
+Event.observe(this.control,"click",Prado.PostBack.bindEvent(this,_4));
}});
Prado.WebUI.TLinkButton=Prado.WebUI.ClickableComponent;
Prado.WebUI.TCheckBox=Prado.WebUI.ClickableComponent;
@@ -2407,14 +2425,29 @@ var _7=Event.element(e);
if(_7){
Event.fireEvent(_7,"change");
Event.stop(e);
-return false;
}
}
-return true;
}});
Prado.WebUI.TListControl=Prado.WebUI.createPostBackComponent({onInit:function(_8){
Event.observe(this.element.id,"change",Prado.PostBack.bindEvent(this,_8));
}});
Prado.WebUI.TListBox=Prado.WebUI.TListControl;
Prado.WebUI.TDropDownList=Prado.WebUI.TListControl;
+Prado.WebUI.DefaultButton=Class.create();
+Object.extend(Prado.WebUI.DefaultButton.prototype,{initialize:function(_9){
+this.options=_9;
+this._event=this.triggerEvent.bindEvent(this);
+Event.observe(_9["Panel"],"keydown",this._event);
+},triggerEvent:function(ev,_11){
+var _12=Event.keyCode(ev)==Event.KEY_RETURN;
+var _13=Event.element(ev).tagName.toLowerCase()=="textarea";
+if(_12&&!_13){
+var _14=$(this.options["Target"]);
+if(_14){
+this.triggered=true;
+Event.fireEvent(_14,this.options["Event"]);
+Event.stop(ev);
+}
+}
+}});
diff --git a/framework/Web/Javascripts/prado/controls.js b/framework/Web/Javascripts/prado/controls.js
index 34c734f9..d1720dfe 100644
--- a/framework/Web/Javascripts/prado/controls.js
+++ b/framework/Web/Javascripts/prado/controls.js
@@ -6,7 +6,7 @@ Object.extend(Prado.WebUI.PostBackControl.prototype,
{
initialize : function(options)
{
- this.element = $(options['ID']);
+ this.control = $(options['ID']);
if(options['CausesValidation'] && Prado.Validation)
Prado.Validation.AddTarget(options['ID'], options['ValidationGroup']);
@@ -34,7 +34,7 @@ Prado.WebUI.ClickableComponent = Prado.WebUI.createPostBackComponent(
{
onInit : function(options)
{
- Event.observe(this.element, "click", Prado.PostBack.bindEvent(this,options));
+ Event.observe(this.control, "click", Prado.PostBack.bindEvent(this,options));
}
});
@@ -61,10 +61,8 @@ Prado.WebUI.TTextBox = Prado.WebUI.createPostBackComponent(
{
Event.fireEvent(target, "change");
Event.stop(e);
- return false;
}
}
- return true;
}
});
@@ -79,53 +77,29 @@ Prado.WebUI.TListControl = Prado.WebUI.createPostBackComponent(
Prado.WebUI.TListBox = Prado.WebUI.TListControl;
Prado.WebUI.TDropDownList = Prado.WebUI.TListControl;
-
-//Prado.Button = Class.create();
-
-/**
- * Usage: Event.observe("panelID", "keypress", Prado.fireButton.bindEvent($("panelID"), "targetButtonID"));
- */
-/*Object.extend(Prado.Button,
+Prado.WebUI.DefaultButton = Class.create();
+Object.extend(Prado.WebUI.DefaultButton.prototype,
{
- buttonFired : false,
- fireButton : function(e, target)
+ initialize : function(options)
{
- var eventFired = !this.buttonFired && Event.keyCode(e) == Event.KEY_RETURN;
- var isTextArea = Event.element(e).tagName.toLowerCase() == "textarea";
- if (eventFired && !isTextArea)
- {
- var defaultButton = $(target);
- if (defaultButton)
- {
- Prado.Button.buttonFired = true;
- Event.fireEvent(defaultButton,"click");
- Event.stop(e);
- return false;
- }
- }
- return true;
- }
-});
+ this.options = options;
+ this._event = this.triggerEvent.bindEvent(this);
+ Event.observe(options['Panel'], 'keydown', this._event);
+ },
-Prado.TextBox = Class.create();
-*/
-/**
- * Usage: Event.observe("textboxID", "keypress", Prado.fireButton.bindEvent($("textboxID")));
- */
-/*Object.extend(Prado.TextBox,
-{
- handleReturnKey : function(e)
+ triggerEvent : function(ev, target)
{
- if(Event.keyCode(e) == Event.KEY_RETURN)
- {
- var target = Event.element(e);
- if(target)
+ var enterPressed = Event.keyCode(ev) == Event.KEY_RETURN;
+ var isTextArea = Event.element(ev).tagName.toLowerCase() == "textarea";
+ if(enterPressed && !isTextArea)
+ {
+ var defaultButton = $(this.options['Target']);
+ if(defaultButton)
{
- Event.fireEvent(target, "change");
- Event.stop(e);
- return false;
+ this.triggered = true;
+ Event.fireEvent(defaultButton, this.options['Event']);
+ Event.stop(ev);
}
}
- return true;
}
-});*/
+});
\ No newline at end of file
diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php
index 535e85b2..be6611cd 100644
--- a/framework/Web/UI/TClientScriptManager.php
+++ b/framework/Web/UI/TClientScriptManager.php
@@ -1,6 +1,6 @@
_trackFocus=$value;
}
}
-
+*/
Prado::using('System.Web.Javascripts.*');
class TClientScriptManager extends TComponent
@@ -133,6 +133,33 @@ class TClientScriptManager extends TComponent
return $options->toJavascript();
}
+ /**
+ * Register a default button to panel. When the $panel is in focus and
+ * the 'enter' key is pressed, the $button will be clicked.
+ * @param TControl panel to register the default button action
+ * @param TControl button to trigger a postback
+ */
+ public function registerDefaultButton($panel, $button)
+ {
+ $serializer = new TJavascriptSerializer(
+ $this->getDefaultButtonOptions($panel, $button));
+ $options = $serializer->toJavascript();
+ $code = "new Prado.WebUI.DefaultButton($options);";
+ $scripts = $this->_page->getClientScript();
+ $scripts->registerEndScript("prado:".$panel->getClientID(), $code);
+ }
+
+ /**
+ * @return array default button options.
+ */
+ protected function getDefaultButtonOptions($panel, $button)
+ {
+ $options['Panel'] = $panel->getClientID();
+ $options['Target'] = $button->getClientID();
+ $options['Event'] = 'click';
+ return $options;
+ }
+
/**
* Register client scripts.
diff --git a/framework/Web/UI/WebControls/TButton.php b/framework/Web/UI/WebControls/TButton.php
index 9c364af8..85473349 100644
--- a/framework/Web/UI/WebControls/TButton.php
+++ b/framework/Web/UI/WebControls/TButton.php
@@ -86,6 +86,9 @@ class TButton extends TWebControl implements IPostBackEventHandler
parent::addAttributesToRender($writer);
}
+ /**
+ * @return boolean true if validators are active and can cause validation.
+ */
protected function canCauseValidation()
{
$group = $this->getValidationGroup();
diff --git a/framework/Web/UI/WebControls/TDatePicker.php b/framework/Web/UI/WebControls/TDatePicker.php
index 10d3248e..60cf882d 100644
--- a/framework/Web/UI/WebControls/TDatePicker.php
+++ b/framework/Web/UI/WebControls/TDatePicker.php
@@ -1,13 +1,58 @@
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ */
/**
- * ${classname}
*
- * ${description}
+ * TDatePicker class.
+ *
+ * TDatePicker displays a text box for date input purpose.
+ * When the text box receives focus, a calendar will pop up and users can
+ * pick up from it a date that will be automatically entered into the text box.
+ * The format of the date string displayed in the text box is determined by
+ * the DateFormat property. Valid formats are the combination of the
+ * following tokens,
+ *
+ *
+ * Character Format Pattern (en-US)
+ * -----------------------------------------
+ * d day digit
+ * dd padded day digit e.g. 01, 02
+ * M month digit
+ * MM padded month digit
+ * MMMM localized month name, e.g. March, April
+ * yy 2 digit year
+ * yyyy 4 digit year
+ * -----------------------------------------
+ *
+ *
+ * TDatePicker has three Mode to show the date picker popup.
+ *
+ * # Basic -- Only shows a text input, focusing on the input shows the
+ * date picker.
+ * # Button -- Shows a button next to the text input, clicking on the
+ * button shows the date, button text can be by the
+ * ButtonText property
+ * # ImageButton -- Shows an image next to the text input, clicking on
+ * the image shows the date picker, image source can be
+ * change through the ImageUrl property.
+ *
+ * The CssClass property can be used to override the css class name
+ * for the date picker panel. CalendarStyle property sets the packages
+ * styles available. E.g. default.
*
- * @author Wei Zhuo
- * @version $Revision: 1.66 $ $Date: ${DATE} ${TIME} $
- * @package ${package}
+ * @author Wei Zhuo
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ * @since 3.0
*/
class TDatePicker extends TTextBox
{
@@ -175,6 +220,10 @@ class TDatePicker extends TTextBox
return $this->getViewState('UpToYear', intval(@date('Y'))+10);
}
+ /**
+ * Get javascript date picker options.
+ * @return array date picker client-side options
+ */
protected function getDatePickerOptions()
{
$options['Format'] = $this->getDateFormat();
@@ -189,6 +238,10 @@ class TDatePicker extends TTextBox
return $options;
}
+ /**
+ * Get javascript localization options, e.g. month and weekday names.
+ * @return array localization options.
+ */
protected function getCulturalOptions()
{
$app = $this->getApplication()->getGlobalization();
@@ -206,6 +259,9 @@ class TDatePicker extends TTextBox
return $options;
}
+ /**
+ * Publish the date picker Css asset files.
+ */
protected function OnPreRender($param)
{
parent::onPreRender($param);
@@ -214,8 +270,8 @@ class TDatePicker extends TTextBox
/**
* Renders body content.
- * This method overrides parent implementation by replacing
- * the body content with syntax highlighted result.
+ * This method overrides parent implementation by adding
+ * additional date picker button if Mode is "Button" or "ImageButton".
* @param THtmlWriter writer
*/
protected function render($writer)
@@ -229,11 +285,19 @@ class TDatePicker extends TTextBox
}
}
+ /**
+ * Gets the ID for the date picker trigger button.
+ * @return string unique button ID
+ */
protected function getDatePickerButtonID()
{
return $this->getClientID().'button';
}
+ /**
+ * Adds an additional button such that when clicked it shows the date picker.
+ * @return THtmlWriter writer
+ */
protected function renderButtonDatePicker($writer)
{
$writer->addAttribute('id', $this->getDatePickerButtonID());
@@ -243,7 +307,11 @@ class TDatePicker extends TTextBox
$writer->renderBeginTag("input");
}
- protected function renderImageButtonDatePicker($writer)
+ /**
+ * Adds an additional image button such that when clicked it shows the date picker.
+ * @return THtmlWriter writer
+ */
+ protected function renderImageButtonDatePicker($writer)
{
$url = $this->getButtonImageUrl();
$url = empty($url) ? $this->publishDefaultButtonImage() : $url;
@@ -253,6 +321,10 @@ class TDatePicker extends TTextBox
$writer->renderBeginTag('img');
}
+ /**
+ * Publish the default button image asset file.
+ * @return string image file url.
+ */
protected function publishDefaultButtonImage()
{
$cs = $this->getPage()->getClientScript();
@@ -261,6 +333,10 @@ class TDatePicker extends TTextBox
return $this->getService()->getAsset($file);
}
+ /**
+ * Publish the calendar style Css asset file.
+ * @return string Css file url.
+ */
protected function publishCalendarStyle()
{
$cs = $this->getPage()->getClientScript();
@@ -272,6 +348,12 @@ class TDatePicker extends TTextBox
return $url;
}
+ /**
+ * Registers the javascript code to initialize the date picker.
+ * Must use "Event.OnLoad" to initialize the date picker when the
+ * full page is loaded, otherwise IE will throw an error.
+ * @param THtmlWriter writer
+ */
protected function addAttributesToRender($writer)
{
parent::addAttributesToRender($writer);
diff --git a/framework/Web/UI/WebControls/TPanel.php b/framework/Web/UI/WebControls/TPanel.php
index 9eab135e..33ae7cd2 100644
--- a/framework/Web/UI/WebControls/TPanel.php
+++ b/framework/Web/UI/WebControls/TPanel.php
@@ -72,13 +72,8 @@ class TPanel extends TWebControl
throw new TInvalidDataValueException('panel_defaultbutton_invalid',$butt);
else
{
- //TODO
- /*$scripts = $this->getPage()->getClientScript();
- $js = $scripts->registerDefaultButtonScript($this,$button);
- $clientID=$this->getClientID();
- $scripts->registerEndScript($clientID.'defaultButton', $js);
- $writer->addAttribute('id',$clientID);
- $writer->addAttribute('onkeypress', "return false;");*/
+ $writer->addAttribute('id',$this->getClientID());
+ $this->getPage()->getClientScript()->registerDefaultButton($this, $button);
}
}
}
diff --git a/tests/FunctionalTests/protected/pages/UI/TestTPanelDefaultButton.page b/tests/FunctionalTests/protected/pages/UI/TestTPanelDefaultButton.page
index 7585bdbc..753550d8 100644
--- a/tests/FunctionalTests/protected/pages/UI/TestTPanelDefaultButton.page
+++ b/tests/FunctionalTests/protected/pages/UI/TestTPanelDefaultButton.page
@@ -3,13 +3,15 @@
This is panel content with a
and two buttons:
-
+
+
When you change focus to the panel and hit 'enter' key, button2
will be clicked because it is set as the default button of the panel.
+
\ No newline at end of file
diff --git a/tests/FunctionalTests/protected/pages/UI/TestTPanelDefaultButton.php b/tests/FunctionalTests/protected/pages/UI/TestTPanelDefaultButton.php
index bc88dc00..2b0ba466 100644
--- a/tests/FunctionalTests/protected/pages/UI/TestTPanelDefaultButton.php
+++ b/tests/FunctionalTests/protected/pages/UI/TestTPanelDefaultButton.php
@@ -8,4 +8,26 @@ class TestTPanelDefaultButton extends TPage
}
}
+/**
+ *
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ * @since 3.0
+ */
+class DefaultButtonTest extends SeleniumTestCase
+{
+ function setup()
+ {
+ $page = Prado::getApplication()->getTestPage(__FILE__);
+ $this->open($page);
+ }
+
+ function testClick()
+ {
+ $this->clickAndWait("ctl0_Content_Button2");
+ $this->assertTextPresent("You have clicked on 'button2'.");
+ }
+}
?>
\ No newline at end of file
--
cgit v1.2.3