summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--framework/Web/Javascripts/js/ajax.js4
-rw-r--r--framework/Web/Javascripts/js/prado.js69
-rw-r--r--framework/Web/Javascripts/prado/activecontrols3.js17
-rw-r--r--framework/Web/Javascripts/prado/element.js176
-rw-r--r--framework/Web/UI/ActiveControls/TActiveButton.php3
-rw-r--r--framework/Web/UI/ActiveControls/TActiveCheckBox.php11
-rw-r--r--framework/Web/UI/ActiveControls/TActiveCheckBoxList.php100
-rw-r--r--framework/Web/UI/ActiveControls/TActiveControlAdapter.php12
-rw-r--r--framework/Web/UI/ActiveControls/TActiveDropDownList.php153
-rw-r--r--framework/Web/UI/ActiveControls/TActiveHyperLink.php99
-rw-r--r--framework/Web/UI/ActiveControls/TActiveImage.php27
-rw-r--r--framework/Web/UI/ActiveControls/TActiveImageButton.php25
-rw-r--r--framework/Web/UI/ActiveControls/TActiveLabel.php5
-rw-r--r--framework/Web/UI/ActiveControls/TActiveLinkButton.php25
-rw-r--r--framework/Web/UI/ActiveControls/TActiveListBox.php26
-rw-r--r--framework/Web/UI/ActiveControls/TActiveListControlAdapter.php212
-rw-r--r--framework/Web/UI/ActiveControls/TActivePageAdapter.php2
-rw-r--r--framework/Web/UI/ActiveControls/TActivePanel.php5
-rw-r--r--framework/Web/UI/ActiveControls/TActiveRadioButton.php27
-rw-r--r--framework/Web/UI/ActiveControls/TActiveRadioButtonList.php25
-rw-r--r--framework/Web/UI/ActiveControls/TActiveTextBox.php11
-rw-r--r--framework/Web/UI/ActiveControls/TAutoComplete.php5
-rw-r--r--framework/Web/UI/ActiveControls/TBaseActiveControl.php6
-rw-r--r--framework/Web/UI/ActiveControls/TCallback.php5
-rw-r--r--framework/Web/UI/ActiveControls/TCallbackClientScript.php37
-rw-r--r--framework/Web/UI/ActiveControls/TCallbackTimer.php5
-rw-r--r--framework/Web/UI/TClientScriptManager.php4
-rw-r--r--framework/Web/UI/TControl.php41
-rw-r--r--framework/Web/UI/TPage.php8
-rw-r--r--framework/Web/UI/WebControls/TBulletedList.php8
-rw-r--r--framework/Web/UI/WebControls/TCheckBox.php2
-rw-r--r--framework/Web/UI/WebControls/THyperLink.php25
-rw-r--r--framework/Web/UI/WebControls/TListControl.php78
-rw-r--r--tests/FunctionalTests/active-controls/protected/pages/ActiveDropDownList.page26
-rw-r--r--tests/FunctionalTests/active-controls/protected/pages/ActiveDropDownList.php39
-rw-r--r--tests/FunctionalTests/active-controls/protected/pages/ActiveHyperLinkTest.page13
-rw-r--r--tests/FunctionalTests/active-controls/protected/pages/ActiveHyperLinkTest.php26
-rw-r--r--tests/FunctionalTests/active-controls/protected/pages/TActiveCheckBoxListTest.page24
-rw-r--r--tests/FunctionalTests/active-controls/protected/pages/TActiveCheckBoxListTest.php37
-rw-r--r--tests/FunctionalTests/active-controls/tests/ActiveCheckBoxListTestCase.php57
-rw-r--r--tests/FunctionalTests/active-controls/tests/ActiveDropDownListTestCase.php41
-rw-r--r--tests/FunctionalTests/active-controls/tests/ActiveHyperLinkTestCase.php18
-rw-r--r--tests/FunctionalTests/selenium/prado-functional-test.js16
43 files changed, 1439 insertions, 116 deletions
diff --git a/framework/Web/Javascripts/js/ajax.js b/framework/Web/Javascripts/js/ajax.js
index e0e9ae7e..fbbd3ecf 100644
--- a/framework/Web/Javascripts/js/ajax.js
+++ b/framework/Web/Javascripts/js/ajax.js
@@ -215,4 +215,6 @@ this.timeout=(t+this.options.Interval)*1000;this.count++;return parseInt(this.ti
{if(this.timers[id])
this.timers[id].startTimer();},stop:function(id)
{if(this.timers[id])
-this.timers[id].stopTimer();}}); \ No newline at end of file
+this.timers[id].stopTimer();}});Prado.WebUI.ActiveListControl=Base.extend({constructor:function(options)
+{this.element=$(options.ID);this.options=options;Event.observe(this.element,"change",this.doCallback.bind(this));},doCallback:function(event)
+{new Prado.CallbackRequest(this.options.EventTarget,this.options);Event.stop(event);}});Prado.WebUI.TActiveDropDownList=Prado.WebUI.ActiveListControl; \ No newline at end of file
diff --git a/framework/Web/Javascripts/js/prado.js b/framework/Web/Javascripts/js/prado.js
index c2f2fdfd..0e71f733 100644
--- a/framework/Web/Javascripts/js/prado.js
+++ b/framework/Web/Javascripts/js/prado.js
@@ -251,9 +251,9 @@ lastFocus.value=options['EventTarget'];}}
$('PRADO_POSTBACK_TARGET').value=options['EventTarget'];$('PRADO_POSTBACK_PARAMETER').value=options['EventParameter'];Event.stop(event);Event.fireEvent(form,"submit");}
Prado.Element={setValue:function(element,value)
{var el=$(element);if(el&&typeof(el.value)!="undefined")
-el.value=value;},select:function(element,method,value)
-{var el=$(element);var isList=element.indexOf('[]')>-1;if(!el&&!isList)return;method=isList?'check'+method:el.tagName.toLowerCase()+method;var selection=Prado.Element.Selection;if(typeof(selection[method])=="function")
-selection[method](isList?element:el,value);},click:function(element)
+el.value=value;},select:function(element,method,value,total)
+{var el=$(element);var selection=Prado.Element.Selection;if(typeof(selection[method])=="function")
+{control=selection.isSelectable(el)?[el]:selection.getListElements(element,total);selection[method](control,value);}},click:function(element)
{var el=$(element);if(el)
Event.fireEvent(el,'click');},setAttribute:function(element,attribute,value)
{var el=$(element);if(attribute=="disabled"&&value==false)
@@ -278,32 +278,59 @@ else
return result[2];else
return null;},evaluateScript:function(content)
{content.evalScripts();}}
-Prado.Element.Selection={inputValue:function(el,value)
+Prado.Element.Selection={isSelectable:function(el)
+{if(el&&el.type)
{switch(el.type.toLowerCase())
-{case'checkbox':case'radio':return el.checked=value;}},selectValue:function(el,value)
+{case'checkbox':case'radio':case'select':case'select-one':return true;}}
+return false;},inputValue:function(el,value)
+{switch(el.type.toLowerCase())
+{case'checkbox':case'radio':return el.checked=value;}},selectValue:function(elements,value)
+{elements.each(function(el)
{$A(el.options).each(function(option)
-{option.selected=option.value==value;});},selectIndex:function(el,index)
-{if(el.type=='select-one')
+{if(typeof(value)=="boolean")
+options.selected=value;else if(option.value==value)
+option.selected=true;});})},selectValues:function(elements,values)
+{selection=this;values.each(function(value)
+{selection.selectValue(elements,value);})},selectIndex:function(elements,index)
+{elements.each(function(el)
+{if(el.type.toLowerCase()=='select-one')
el.selectedIndex=index;else
{for(var i=0;i<el.length;i++)
{if(i==index)
-el.options[i].selected=true;}}},selectClear:function(el)
-{el.selectedIndex=-1;},selectAll:function(el)
+el.options[i].selected=true;}}})},selectAll:function(elements)
+{elements.each(function(el)
+{if(el.type.toLowerCase()!='select-one')
{$A(el.options).each(function(option)
-{option.selected=true;Logger.warn(option.value);});},selectInvert:function(el)
+{option.selected=true;})}})},selectInvert:function(elements)
+{elements.each(function(el)
+{if(el.type.toLowerCase()!='select-one')
{$A(el.options).each(function(option)
-{option.selected=!option.selected;});},checkValue:function(name,value)
-{$A(document.getElementsByName(name)).each(function(el)
-{el.checked=el.value==value});},checkIndex:function(name,index)
-{var elements=$A(document.getElementsByName(name));for(var i=0;i<elements.length;i++)
+{option.selected=!options.selected;})}})},selectIndices:function(elements,indices)
+{selection=this;indices.each(function(index)
+{selection.selectIndex(elements,index);})},selectClear:function(elements)
+{elements.each(function(el)
+{el.selectedIndex=-1;})},getListElements:function(element,total)
+{elements=new Array();for(i=0;i<total;i++)
+{el=$(element+"_c"+i);if(el)
+elements.push(el);}
+return elements;},checkValue:function(elements,value)
+{elements.each(function(el)
+{if(typeof(value)=="boolean")
+el.checked=value;else if(el.value==value)
+el.checked=true;});},checkValues:function(elements,values)
+{selection=this;values.each(function(value)
+{selection.checkValue(elements,value);})},checkIndex:function(elements,index)
+{for(var i=0;i<elements.length;i++)
{if(i==index)
-elements[i].checked=true;}},checkClear:function(name)
-{$A(document.getElementsByName(name)).each(function(el)
-{el.checked=false;});},checkAll:function(name)
-{$A(document.getElementsByName(name)).each(function(el)
-{el.checked=true;});},checkInvert:function(name)
-{$A(document.getElementsByName(name)).each(function(el)
-{el.checked=!el.checked;});}};Prado.WebUI=Class.create();Prado.WebUI.PostBackControl=Class.create();Prado.WebUI.PostBackControl.prototype={_elementOnClick:null,initialize:function(options)
+elements[i].checked=true;}},checkIndices:function(elements,indices)
+{selection=this;indices.each(function(index)
+{selection.checkIndex(elements,index);})},checkClear:function(elements)
+{elements.each(function(el)
+{el.checked=false;});},checkAll:function(elements)
+{elements.each(function(el)
+{el.checked=true;})},checkInvert:function(elements)
+{elements.each(function(el)
+{el.checked!=el.checked;})}};Prado.WebUI=Class.create();Prado.WebUI.PostBackControl=Class.create();Prado.WebUI.PostBackControl.prototype={_elementOnClick:null,initialize:function(options)
{this.element=$(options.ID);if(this.onInit)
this.onInit(options);},onInit:function(options)
{if(typeof(this.element.onclick)=="function")
diff --git a/framework/Web/Javascripts/prado/activecontrols3.js b/framework/Web/Javascripts/prado/activecontrols3.js
index 7039feec..760d6e0e 100644
--- a/framework/Web/Javascripts/prado/activecontrols3.js
+++ b/framework/Web/Javascripts/prado/activecontrols3.js
@@ -189,5 +189,20 @@ Prado.WebUI.TCallbackTimer = Base.extend(
}
});
+Prado.WebUI.ActiveListControl = Base.extend(
+{
+ constructor : function(options)
+ {
+ this.element = $(options.ID);
+ this.options = options;
+ Event.observe(this.element, "change", this.doCallback.bind(this));
+ },
+
+ doCallback : function(event)
+ {
+ new Prado.CallbackRequest(this.options.EventTarget, this.options);
+ Event.stop(event);
+ }
+});
-
+Prado.WebUI.TActiveDropDownList = Prado.WebUI.ActiveListControl;
diff --git a/framework/Web/Javascripts/prado/element.js b/framework/Web/Javascripts/prado/element.js
index 9d0179dc..51756cd0 100644
--- a/framework/Web/Javascripts/prado/element.js
+++ b/framework/Web/Javascripts/prado/element.js
@@ -12,15 +12,15 @@ Prado.Element =
el.value = value;
},
- select : function(element, method, value)
+ select : function(element, method, value, total)
{
var el = $(element);
- var isList = element.indexOf('[]') > -1;
- if(!el && !isList) return;
- method = isList ? 'check'+method : el.tagName.toLowerCase()+method;
var selection = Prado.Element.Selection;
if(typeof(selection[method]) == "function")
- selection[method](isList ? element : el,value);
+ {
+ control = selection.isSelectable(el) ? [el] : selection.getListElements(element,total);
+ selection[method](control, value);
+ }
},
click : function(element)
@@ -102,6 +102,22 @@ Prado.Element =
Prado.Element.Selection =
{
+ isSelectable : function(el)
+ {
+ if(el && el.type)
+ {
+ switch(el.type.toLowerCase())
+ {
+ case 'checkbox':
+ case 'radio':
+ case 'select':
+ case 'select-one':
+ return true;
+ }
+ }
+ return false;
+ },
+
inputValue : function(el, value)
{
switch(el.type.toLowerCase())
@@ -112,61 +128,125 @@ Prado.Element.Selection =
}
},
- selectValue : function(el, value)
+ selectValue : function(elements, value)
{
- $A(el.options).each(function(option)
+ elements.each(function(el)
{
- option.selected = option.value == value;
- });
+ $A(el.options).each(function(option)
+ {
+ if(typeof(value) == "boolean")
+ options.selected = value;
+ else if(option.value == value)
+ option.selected = true;
+ });
+ })
+ },
+
+ selectValues : function(elements, values)
+ {
+ selection = this;
+ values.each(function(value)
+ {
+ selection.selectValue(elements,value);
+ })
},
- selectIndex : function(el, index)
+ selectIndex : function(elements, index)
{
- if(el.type == 'select-one')
- el.selectedIndex = index;
- else
+ elements.each(function(el)
{
- for(var i = 0; i<el.length; i++)
+ if(el.type.toLowerCase() == 'select-one')
+ el.selectedIndex = index;
+ else
{
- if(i == index)
- el.options[i].selected = true;
+ for(var i = 0; i<el.length; i++)
+ {
+ if(i == index)
+ el.options[i].selected = true;
+ }
}
- }
+ })
+ },
+
+ selectAll : function(elements)
+ {
+ elements.each(function(el)
+ {
+ if(el.type.toLowerCase() != 'select-one')
+ {
+ $A(el.options).each(function(option)
+ {
+ option.selected = true;
+ })
+ }
+ })
},
- selectClear : function(el)
+ selectInvert : function(elements)
{
- el.selectedIndex = -1;
+ elements.each(function(el)
+ {
+ if(el.type.toLowerCase() != 'select-one')
+ {
+ $A(el.options).each(function(option)
+ {
+ option.selected = !options.selected;
+ })
+ }
+ })
+ },
+
+ selectIndices : function(elements, indices)
+ {
+ selection = this;
+ indices.each(function(index)
+ {
+ selection.selectIndex(elements,index);
+ })
},
- selectAll : function(el)
+ selectClear : function(elements)
{
- $A(el.options).each(function(option)
+ elements.each(function(el)
{
- option.selected = true;
- Logger.warn(option.value);
- });
+ el.selectedIndex = -1;
+ })
},
- selectInvert : function(el)
+ getListElements : function(element, total)
+ {
+ elements = new Array();
+ for(i = 0; i < total; i++)
+ {
+ el = $(element+"_c"+i);
+ if(el)
+ elements.push(el);
+ }
+ return elements;
+ },
+
+ checkValue : function(elements, value)
{
- $A(el.options).each(function(option)
+ elements.each(function(el)
{
- option.selected = !option.selected;
+ if(typeof(value) == "boolean")
+ el.checked = value;
+ else if(el.value == value)
+ el.checked = true;
});
},
- checkValue : function(name, value)
+ checkValues : function(elements, values)
{
- $A(document.getElementsByName(name)).each(function(el)
+ selection = this;
+ values.each(function(value)
{
- el.checked = el.value == value
- });
+ selection.checkValue(elements, value);
+ })
},
- checkIndex : function(name, index)
+ checkIndex : function(elements, index)
{
- var elements = $A(document.getElementsByName(name));
for(var i = 0; i<elements.length; i++)
{
if(i == index)
@@ -174,26 +254,36 @@ Prado.Element.Selection =
}
},
- checkClear : function(name)
+ checkIndices : function(elements, indices)
+ {
+ selection = this;
+ indices.each(function(index)
+ {
+ selection.checkIndex(elements, index);
+ })
+ },
+
+ checkClear : function(elements)
{
- $A(document.getElementsByName(name)).each(function(el)
+ elements.each(function(el)
{
el.checked = false;
});
},
-
- checkAll : function(name)
+
+ checkAll : function(elements)
{
- $A(document.getElementsByName(name)).each(function(el)
+ elements.each(function(el)
{
el.checked = true;
- });
+ })
},
- checkInvert : function(name)
+
+ checkInvert : function(elements)
{
- $A(document.getElementsByName(name)).each(function(el)
+ elements.each(function(el)
{
- el.checked = !el.checked;
- });
+ el.checked != el.checked;
+ })
}
}; \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveButton.php b/framework/Web/UI/ActiveControls/TActiveButton.php
index 81744057..232e639c 100644
--- a/framework/Web/UI/ActiveControls/TActiveButton.php
+++ b/framework/Web/UI/ActiveControls/TActiveButton.php
@@ -10,6 +10,9 @@
* @package System.Web.UI.ActiveControls
*/
+/**
+ * Load active control adapter.
+ */
Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter');
/**
diff --git a/framework/Web/UI/ActiveControls/TActiveCheckBox.php b/framework/Web/UI/ActiveControls/TActiveCheckBox.php
index 1b34f32d..a7f3ac2a 100644
--- a/framework/Web/UI/ActiveControls/TActiveCheckBox.php
+++ b/framework/Web/UI/ActiveControls/TActiveCheckBox.php
@@ -11,6 +11,11 @@
*/
/**
+ * Load active control adapter.
+ */
+Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter');
+
+/**
* TActiveCheckBox class.
*
* The active control counter part to checkbox. The {@link setAutoPostBack AutoPostBack}
@@ -49,16 +54,12 @@ class TActiveCheckBox extends TCheckBox implements ICallbackEventHandler, IActiv
/**
* Raises the callback event. This method is required by {@link
- * ICallbackEventHandler} interface. If {@link getCausesValidation
- * CausesValidation} is true, it will invoke the page's {@link TPage::
- * validate validate} method first. It will raise {@link onCheckedChanged
- * OnCheckedChanged} event first and then the {@link onCallback OnCallback} event.
+ * ICallbackEventHandler} interface.
* This method is mainly used by framework and control developers.
* @param TCallbackEventParameter the event parameter
*/
public function raiseCallbackEvent($param)
{
- $this->raisePostDataChangedEvent($param);
$this->onCallback($param);
}
diff --git a/framework/Web/UI/ActiveControls/TActiveCheckBoxList.php b/framework/Web/UI/ActiveControls/TActiveCheckBoxList.php
new file mode 100644
index 00000000..3a33ccc2
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveCheckBoxList.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * TActiveCheckBoxList class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+/**
+ * Load active control adapter.
+ */
+Prado::using('System.Web.UI.ActiveControls.TActiveListControlAdapter');
+
+/**
+ * TActiveCheckBoxList class.
+ *
+ * The active control counter part to checkbox list control.
+ * The {@link setAutoPostBack AutoPostBack} property is set to true by default.
+ * Thus, when a checkbox is clicked a {@link onCallback OnCallback} event is
+ * raised after {@link OnSelectedIndexChanged} event.
+ *
+ * With {@link TBaseActiveControl::setEnableUpdate() ActiveControl.EnabledUpdate}
+ * set to true (default is true), changes to the selection will be updated
+ * on the client side.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Sun Jun 25 01:50:27 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveCheckBoxList extends TCheckBoxList implements IActiveControl, ICallbackEventHandler
+{
+ /**
+ * Creates a new callback control, sets the adapter to
+ * TActiveListControlAdapter. If you override this class, be sure to set the
+ * adapter appropriately by, for example, by calling this constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ $this->setAdapter(new TActiveListControlAdapter($this));
+ $this->setAutoPostBack(true);
+ }
+
+ /**
+ * @return TBaseActiveCallbackControl standard callback control options.
+ */
+ public function getActiveControl()
+ {
+ return $this->getAdapter()->getBaseActiveControl();
+ }
+
+ /**
+ * No client class for this control.
+ * This method overrides the parent implementation.
+ * @return null no javascript class name.
+ */
+ protected function getClientClassName()
+ {
+ return null;
+ }
+
+ /**
+ * Creates a control used for repetition (used as a template).
+ * @return TControl the control to be repeated
+ */
+ protected function createRepeatedControl()
+ {
+ return new TActiveCheckBox;
+ }
+
+ /**
+ * Raises the callback event. This method is required by {@link
+ * ICallbackEventHandler} interface.
+ * This method is mainly used by framework and control developers.
+ * @param TCallbackEventParameter the event parameter
+ */
+ public function raiseCallbackEvent($param)
+ {
+ $this->onCallback($param);
+ }
+
+ /**
+ * This method is invoked when a callback is requested. The method raises
+ * 'OnCallback' event to fire up the event handlers. If you override this
+ * method, be sure to call the parent implementation so that the event
+ * handler can be invoked.
+ * @param TCallbackEventParameter event parameter to be passed to the event handlers
+ */
+ public function onCallback($param)
+ {
+ $this->raiseEvent('OnCallback', $this, $param);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
index e6e8585f..75c9ba21 100644
--- a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
+++ b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
@@ -90,13 +90,17 @@ class TActiveControlAdapter extends TControlAdapter
protected function renderCallbackClientScripts()
{
$cs = $this->getPage()->getClientScript();
- $key = get_class($this);
+ $key = 'Prado.CallbackRequest.addPostLoaders';
if(!$cs->isEndScriptRegistered($key))
{
$cs->registerPradoScript('ajax');
- $options = TJavascript::encode($this->getPage()->getPostDataLoaders(),false);
- $script = "Prado.CallbackRequest.addPostLoaders({$options});";
- $cs->registerEndScript($key, $script);
+ $data = $this->getPage()->getPostDataLoaders();
+ if(count($data) > 0)
+ {
+ $options = TJavascript::encode($data,false);
+ $script = "Prado.CallbackRequest.addPostLoaders({$options});";
+ $cs->registerEndScript($key, $script);
+ }
}
}
diff --git a/framework/Web/UI/ActiveControls/TActiveDropDownList.php b/framework/Web/UI/ActiveControls/TActiveDropDownList.php
new file mode 100644
index 00000000..679996b5
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveDropDownList.php
@@ -0,0 +1,153 @@
+<?php
+/**
+ * TActiveDropDownList class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+/**
+ * Load active list control adapter
+ */
+Prado::using('System.Web.UI.ActiveControls.TActiveListControlAdapter');
+
+/**
+/**
+ * TActiveDropDownList class.
+ *
+ * The active control counter part to drop down list control.
+ * The {@link setAutoPostBack AutoPostBack} property is set to true by default.
+ * Thus, when the drop down list selection is changed the {@link onCallback OnCallback} event is
+ * raised after {@link OnSelectedIndexChanged} event.
+ *
+ * With {@link TBaseActiveControl::setEnableUpdate() ActiveControl.EnabledUpdate}
+ * set to true (default is true), changes to the selection, <b>after</b> OnLoad event has
+ * been raised, will be updated.
+ * on the client side.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Sun Jun 25 19:55:19 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveDropDownList extends TDropDownList implements ICallbackEventHandler, IActiveControl
+{
+ /**
+ * Creates a new callback control, sets the adapter to
+ * TActiveListControlAdapter. If you override this class, be sure to set the
+ * adapter appropriately by, for example, by calling this constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ $this->setAdapter(new TActiveListControlAdapter($this));
+ $this->setAutoPostBack(true);
+ }
+
+ /**
+ * @return TBaseActiveCallbackControl standard callback control options.
+ */
+ public function getActiveControl()
+ {
+ return $this->getAdapter()->getBaseActiveControl();
+ }
+
+ /**
+ * No client class for this control.
+ * This method overrides the parent implementation.
+ * @return null no javascript class name.
+ */
+ protected function getClientClassName()
+ {
+ return 'Prado.WebUI.TActiveDropDownList';
+ }
+
+ /**
+ * Loads user input data.
+ * Disables ActiveControl.EnableUpdate subproperty during loading post data
+ * to avoid duplicating selection changes.
+ * @param string the key that can be used to retrieve data from the input data collection
+ * @param array the input data collection
+ * @return boolean whether the data of the component has been changed
+ */
+ public function loadPostData($key,$values)
+ {
+ $enabled = $this->getActiveControl()->getEnableUpdate();
+ $this->getActiveControl()->setEnableUpdate(false);
+ $result = parent::loadPostData($key, $values);
+ $this->getActiveControl()->setEnableUpdate($enabled);
+ return $result;
+ }
+
+ /**
+ * Creates a collection object to hold list items. A specialized
+ * TActiveListItemCollection is created to allow the drop down list options
+ * to be added.
+ * This method may be overriden to create a customized collection.
+ * @return TActiveListItemCollection the collection object
+ */
+ protected function createListItemCollection()
+ {
+ $collection = new TActiveListItemCollection;
+ $collection->setControl($this);
+ return $collection;
+ }
+
+ /**
+ * Override parent implementation, no javascript is rendered here instead
+ * the javascript required for active control is registered in {@link addAttributesToRender}.
+ */
+ protected function renderClientControlScript($writer)
+ {
+ }
+
+ /**
+ * Ensure that the ID attribute is rendered and registers the javascript code
+ * for initializing the active control.
+ */
+ protected function addAttributesToRender($writer)
+ {
+ parent::addAttributesToRender($writer);
+ $writer->addAttribute('id',$this->getClientID());
+ $this->getActiveControl()->registerCallbackClientScript(
+ $this->getClientClassName(), $this->getPostBackOptions());
+ }
+
+ /**
+ * Raises the callback event. This method is required by {@link
+ * ICallbackEventHandler} interface.
+ * This method is mainly used by framework and control developers.
+ * @param TCallbackEventParameter the event parameter
+ */
+ public function raiseCallbackEvent($param)
+ {
+ $this->onCallback($param);
+ }
+
+ /**
+ * This method is invoked when a callback is requested. The method raises
+ * 'OnCallback' event to fire up the event handlers. If you override this
+ * method, be sure to call the parent implementation so that the event
+ * handler can be invoked.
+ * @param TCallbackEventParameter event parameter to be passed to the event handlers
+ */
+ public function onCallback($param)
+ {
+ $this->raiseEvent('OnCallback', $this, $param);
+ }
+
+ /**
+ * Updates the client-side options if the item list has changed after the OnLoad event.
+ */
+ public function onPreRender($param)
+ {
+ parent::onPreRender($param);
+ $this->getAdapter()->updateListItems();
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveHyperLink.php b/framework/Web/UI/ActiveControls/TActiveHyperLink.php
new file mode 100644
index 00000000..ac99089d
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveHyperLink.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * TActiveHyperLink class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+/**
+ * TActiveHyperLink class.
+ *
+ * The active control counterpart of THyperLink component. When
+ * {@link TBaseActiveControl::setEnableUpdate ActiveControl.EnableUpdate}
+ * property is true the during a callback request, setting {@link setText Text}
+ * property will also set the text of the label on the client upon callback
+ * completion. Similarly, for other properties such as {@link setImageUrl ImageUrl},
+ * {@link setNavigateUrl NavigateUrl} and {@link setTarget Target}.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Mon Jun 26 00:08:24 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveHyperLink extends THyperLink implements IActiveControl
+{
+ /**
+ * Creates a new callback control, sets the adapter to
+ * TActiveControlAdapter. If you override this class, be sure to set the
+ * adapter appropriately by, for example, by calling this constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ $this->setAdapter(new TActiveControlAdapter($this));
+ }
+
+ /**
+ * @return TBaseActiveControl basic active control options.
+ */
+ public function getActiveControl()
+ {
+ return $this->getAdapter()->getBaseActiveControl();
+ }
+
+ /**
+ * On callback response, the inner HTMl of the label is updated.
+ * @param string the text value of the label
+ */
+ public function setText($value)
+ {
+ parent::setText($value);
+ if($this->getActiveControl()->canUpdateClientSide())
+ $this->getPage()->getCallbackClient()->update($this, $value);
+ }
+
+ /**
+ * Sets the location of image file of the THyperLink.
+ * @param string the image file location
+ */
+ public function setImageUrl($value)
+ {
+ parent::setImageUrl($value);
+ if($this->getActiveControl()->canUpdateClientSide() && $value !== '')
+ {
+ $textWriter = new TTextWriter();
+ $renderer = new THtmlWriter($textWriter);
+ $this->createImage($value)->renderControl($renderer);
+ $this->getPage()->getCallbackClient()->update($this, $textWriter->flush());
+ }
+ }
+
+ /**
+ * Sets the URL to link to when the THyperLink component is clicked.
+ * @param string the URL
+ */
+ public function setNavigateUrl($value)
+ {
+ parent::setNavigateUrl($value);
+ if($this->getActiveControl()->canUpdateClientSide())
+ $this->getPage()->getCallbackClient()->setAttribute($this, 'href', $value);
+ }
+
+ /**
+ * Sets the target window or frame to display the Web page content linked to when the THyperLink component is clicked.
+ * @param string the target window, valid values include '_blank', '_parent', '_self', '_top' and empty string.
+ */
+ public function setTarget($value)
+ {
+ parent::setTarget($value);
+ if($this->getActiveControl()->canUpdateClientSide())
+ $this->getPage()->getCallbackClient()->setAttribute($this, 'target', $value);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveImage.php b/framework/Web/UI/ActiveControls/TActiveImage.php
new file mode 100644
index 00000000..eb0f4ca9
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveImage.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * TActiveImage class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.WebControls
+ */
+
+
+/**
+ * TActiveImage class.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Mon Jun 26 00:44:25 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveImage extends TImage implements IActiveControl
+{
+
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveImageButton.php b/framework/Web/UI/ActiveControls/TActiveImageButton.php
new file mode 100644
index 00000000..74e99781
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveImageButton.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * TActiveImageButton class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+/**
+ * TActiveImageButton class.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Mon Jun 26 00:45:39 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveImageButton extends TImageButton implements IActiveControl, ICallbackEventHandler
+{
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveLabel.php b/framework/Web/UI/ActiveControls/TActiveLabel.php
index f54e0b98..f6c0ce81 100644
--- a/framework/Web/UI/ActiveControls/TActiveLabel.php
+++ b/framework/Web/UI/ActiveControls/TActiveLabel.php
@@ -11,6 +11,11 @@
*/
/**
+ * Load active control adapter.
+ */
+Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter');
+
+/**
* TActiveLabel class
*
* The active control counterpart of TLabel component. When
diff --git a/framework/Web/UI/ActiveControls/TActiveLinkButton.php b/framework/Web/UI/ActiveControls/TActiveLinkButton.php
new file mode 100644
index 00000000..40b69391
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveLinkButton.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * TActiveLinkButton class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+/**
+ * TActiveLinkButton class.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Mon Jun 26 00:49:25 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveLinkButton extends TLinkButton implements IActiveControl, ICallbackEventHandler
+{
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveListBox.php b/framework/Web/UI/ActiveControls/TActiveListBox.php
new file mode 100644
index 00000000..37db5e27
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveListBox.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * TActiveListBox class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+/**
+ * TActiveListBox class.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Mon Jun 26 00:50:16 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveListBox extends TListBox implements IActiveControl, ICallbackEventHandler
+{
+
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveListControlAdapter.php b/framework/Web/UI/ActiveControls/TActiveListControlAdapter.php
new file mode 100644
index 00000000..592c4c14
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveListControlAdapter.php
@@ -0,0 +1,212 @@
+<?php
+/**
+ * TActiveListControlAdapter class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+/**
+ * Load active control adapter.
+ */
+Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter');
+Prado::using('System.Web.UI.WebControls.TListControl');
+
+/**
+ * TActiveListControlAdapter class.
+ *
+ * Adapte the list controls to allows the selections on the client-side to be altered
+ * during callback response.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ Sun Jun 25 04:53:43 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveListControlAdapter extends TActiveControlAdapter implements IListControlAdaptee
+{
+ /**
+ * @return boolean true if can update client-side attributes.
+ */
+ protected function canUpdateClientSide()
+ {
+ return $this->getControl()->getActiveControl()->canUpdateClientSide();
+ }
+
+ /**
+ * Selects an item based on zero-base index on the client side.
+ * @param integer the index (zero-based) of the item to be selected
+ */
+ public function setSelectedIndex($index)
+ {
+ if($this->canUpdateClientSide())
+ $this->getPage()->getCallbackClient()->select(
+ $this->getControl(), 'Index', $index);
+ }
+
+ /**
+ * Selects a list of item based on zero-base indices on the client side.
+ * @param array list of index of items to be selected
+ */
+ public function setSelectedIndices($indices)
+ {
+ if($this->canUpdateClientSide())
+ {
+ $n = $this->getControl()->getItemCount();
+ $list = array();
+ foreach($indices as $index)
+ {
+ $index = intval($index);
+ if($index >= 0 && $index <= $n)
+ $list[] = $index;
+ }
+ if(count($list) > 0)
+ $this->getPage()->getCallbackClient()->select(
+ $this->getControl(), 'Indices', $list);
+ }
+ }
+
+ /**
+ * Sets selection by item value on the client side.
+ * @param string the value of the item to be selected.
+ */
+ public function setSelectedValue($value)
+ {
+ if($this->canUpdateClientSide())
+ $this->getPage()->getCallbackClient()->select(
+ $this->getControl(), 'Value', $value);
+ }
+
+ /**
+ * Sets selection by a list of item values on the client side.
+ * @param array list of the selected item values
+ */
+ public function setSelectedValues($values)
+ {
+ if($this->canUpdateClientSide())
+ {
+ $list = array();
+ foreach($values as $value)
+ $list[] = $value;
+ if(count($list) > 0)
+ $this->getPage()->getCallbackClient()->select(
+ $this->getControl(), 'Values', $list);
+ }
+ }
+
+ /**
+ * Clears all existing selections on the client side.
+ */
+ public function clearSelection()
+ {
+ if($this->canUpdateClientSide())
+ $this->getPage()->getCallbackClient()->select($this->getControl(), 'Clear');
+ }
+
+ /**
+ * Update the client-side list options.
+ */
+ public function updateListItems()
+ {
+ if($this->canUpdateClientSide() && $this->getControl()->getHasItems())
+ {
+ $items = $this->getControl()->getItems();
+ if($items instanceof TActiveListItemCollection && $items->getListHasChanged())
+ $this->getPage()->getCallbackClient()->setListItems($this->getControl(), $items);
+ }
+ }
+}
+
+/**
+ * TActiveListItemCollection class.
+ *
+ * Allows TActiveDropDownList and TActiveListBox to add new options
+ * during callback response. New options can only be added <b>after</b> the
+ * {@link TControl::onLoad OnLoad} event.
+ *
+ * The {@link getListHasChanged ListHasChanged} property is true when the
+ * list items has changed. The control responsible for the list needs to
+ * repopulate the client-side options.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ Sun Jun 25 21:15:05 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveListItemCollection extends TListItemCollection
+{
+ /**
+ * @var IActiveControl control instance.
+ */
+ private $_control;
+ /**
+ * @var boolean true if list items were changed.
+ */
+ private $_hasChanged=false;
+
+ /**
+ * @return boolean true if active controls can update client-side and
+ * the onLoad event has already been raised.
+ */
+ protected function canUpdateClientSide()
+ {
+ return $this->getControl()->getActiveControl()->canUpdateClientSide()
+ && $this->getControl()->getHasLoaded();
+ }
+
+ /**
+ * @param IActiveControl a active list control.
+ */
+ public function setControl(IActiveControl $control)
+ {
+ $this->_control = $control;
+ }
+
+ /**
+ * @return IActiveControl active control using the collection.
+ */
+ public function getControl()
+ {
+ return $this->_control;
+ }
+
+ /**
+ * @return boolean true if the list has changed after onLoad event.
+ */
+ public function getListHasChanged()
+ {
+ return $this->_hasChanged;
+ }
+
+ /**
+ * Inserts an item into the collection.
+ * The new option is added on the client-side during callback.
+ * @param integer the location where the item will be inserted.
+ * The current item at the place and the following ones will be moved backward.
+ * @param TListItem the item to be inserted.
+ * @throws TInvalidDataTypeException if the item being inserted is neither a string nor TListItem
+ */
+ public function insertAt($index, $value)
+ {
+ parent::insertAt($index, $value);
+ if($this->canUpdateClientSide())
+ $this->_hasChanged = true;
+ }
+
+ /**
+ * Removes an item from at specified index.
+ * @param int zero based index.
+ */
+ public function removeAt($index)
+ {
+ parent::removeAt($index);
+ if($this->canUpdateClientSide())
+ $this->_hasChanged = true;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActivePageAdapter.php b/framework/Web/UI/ActiveControls/TActivePageAdapter.php
index 90c64820..656b959c 100644
--- a/framework/Web/UI/ActiveControls/TActivePageAdapter.php
+++ b/framework/Web/UI/ActiveControls/TActivePageAdapter.php
@@ -142,7 +142,7 @@ class TActivePageAdapter extends TControlAdapter
}
//output the actions
- $executeJavascript = $this->getCallbackClientHandler()->getClientFunctionsToExecute()->toArray();
+ $executeJavascript = $this->getCallbackClientHandler()->getClientFunctionsToExecute();
$actions = TJavascript::jsonEncode($executeJavascript);
$response->appendHeader(self::CALLBACK_ACTION_HEADER.': '.$actions);
diff --git a/framework/Web/UI/ActiveControls/TActivePanel.php b/framework/Web/UI/ActiveControls/TActivePanel.php
index 787b65d3..b7773e1c 100644
--- a/framework/Web/UI/ActiveControls/TActivePanel.php
+++ b/framework/Web/UI/ActiveControls/TActivePanel.php
@@ -11,6 +11,11 @@
*/
/**
+ * Load active control adapter.
+ */
+Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter');
+
+/**
* TActivePanel is the TPanel active control counterpart.
*
* TActivePanel allows the client-side panel contents to be updated during a
diff --git a/framework/Web/UI/ActiveControls/TActiveRadioButton.php b/framework/Web/UI/ActiveControls/TActiveRadioButton.php
new file mode 100644
index 00000000..b9497051
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveRadioButton.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * TActiveRadioButton class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+
+/**
+ * TActiveRadioButton class.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ Mon Jun 26 00:47:14 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveRadioButton extends TRadioButton implements IActiveControl, ICallbackEventHandler
+{
+
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveRadioButtonList.php b/framework/Web/UI/ActiveControls/TActiveRadioButtonList.php
new file mode 100644
index 00000000..665a8542
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TActiveRadioButtonList.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * TActiveRadioButtonList class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+/**
+ * TActiveRadioButtonList class.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Mon Jun 26 00:48:08 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TActiveRadioButtonList extends TRadioButtonList implements IActiveControl, ICallbackEventHandler
+{
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveTextBox.php b/framework/Web/UI/ActiveControls/TActiveTextBox.php
index 2e207f92..950a5dcb 100644
--- a/framework/Web/UI/ActiveControls/TActiveTextBox.php
+++ b/framework/Web/UI/ActiveControls/TActiveTextBox.php
@@ -11,6 +11,11 @@
*/
/**
+ * Load active control adapter.
+ */
+Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter');
+
+/**
* TActiveTextBox class.
*
* TActiveTextBox allows the {@link setText Text} property of the textbox to
@@ -58,16 +63,12 @@ class TActiveTextBox extends TTextBox implements ICallbackEventHandler, IActiveC
/**
* Raises the callback event. This method is required by {@link
- * ICallbackEventHandler} interface. If {@link getCausesValidation
- * CausesValidation} is true, it will invoke the page's {@link TPage::
- * validate validate} method first. It will raise {@link onTextChanged
- * onTextChanged} event first and then the {@link onCallback OnCallback} event.
+ * ICallbackEventHandler} interface.
* This method is mainly used by framework and control developers.
* @param TCallbackEventParameter the event parameter
*/
public function raiseCallbackEvent($param)
{
- $this->raisePostDataChangedEvent($param);
$this->onCallback($param);
}
diff --git a/framework/Web/UI/ActiveControls/TAutoComplete.php b/framework/Web/UI/ActiveControls/TAutoComplete.php
index 55ffde04..7d901e7f 100644
--- a/framework/Web/UI/ActiveControls/TAutoComplete.php
+++ b/framework/Web/UI/ActiveControls/TAutoComplete.php
@@ -11,6 +11,11 @@
*/
/**
+ * Load active text box.
+ */
+Prado::using('System.Web.UI.ActiveControls.TActiveTextBox');
+
+/**
* TAutoComplete class.
*
* TAutoComplete is a textbox that provides a list of suggestion on
diff --git a/framework/Web/UI/ActiveControls/TBaseActiveControl.php b/framework/Web/UI/ActiveControls/TBaseActiveControl.php
index c42f75e8..dfb7efeb 100644
--- a/framework/Web/UI/ActiveControls/TBaseActiveControl.php
+++ b/framework/Web/UI/ActiveControls/TBaseActiveControl.php
@@ -117,7 +117,7 @@ class TBaseActiveControl extends TComponent
*/
public function canUpdateClientSide()
{
- return $this->getControl()->getIsInitialized()
+ return $this->getControl()->getHasChildInitialized()
&& $this->getPage()->getIsCallback()
&& $this->getEnableUpdate();
}
@@ -319,7 +319,9 @@ class TBaseActiveCallbackControl extends TBaseActiveControl
if(is_array($options))
$options = array_merge($this->getClientSideOptions(),$options);
else
- $options = $this->getClientSideOptions();
+ $options = $this->getClientSideOptions();
+ //remove true as default to save bytes
+ $options['CausesValidation']= $options['CausesValidation'] ? '' : false;
$cs->registerCallbackControl($class, $options);
}
diff --git a/framework/Web/UI/ActiveControls/TCallback.php b/framework/Web/UI/ActiveControls/TCallback.php
index 3c7d70c5..e87cea11 100644
--- a/framework/Web/UI/ActiveControls/TCallback.php
+++ b/framework/Web/UI/ActiveControls/TCallback.php
@@ -11,6 +11,11 @@
*/
/**
+ * Load active control adapter.
+ */
+Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter');
+
+/**
* TCallback component class.
*
* The TCallback provides a basic callback handler that can be invoke from the
diff --git a/framework/Web/UI/ActiveControls/TCallbackClientScript.php b/framework/Web/UI/ActiveControls/TCallbackClientScript.php
index d83bf90a..0e1dff5c 100644
--- a/framework/Web/UI/ActiveControls/TCallbackClientScript.php
+++ b/framework/Web/UI/ActiveControls/TCallbackClientScript.php
@@ -53,7 +53,7 @@ class TCallbackClientScript extends TApplicationComponent
*/
public function getClientFunctionsToExecute()
{
- return $this->_actions;
+ return $this->_actions->toArray();
}
/**
@@ -89,18 +89,41 @@ class TCallbackClientScript extends TApplicationComponent
* or radio button list.
* The second parameter determines the selection method. Valid methods are
* - <b>Value</b>, select or check by value
- * - <b>Index</b>, select or check by list index (zero based index)
- * - <b>All</b>, selects or checks all in the list
+ * - <b>Values</b>, select or check by a list of values
+ * - <b>Index</b>, select or check by index (zero based index)
+ * - <b>Indices</b>, select or check by a list of index (zero based index)
* - <b>Clear</b>, clears or selections or checks in the list
- * - <b>Invert</b>, inverts the current selection or checks.
+ * - <b>All</b>, select all
+ * - <b>Invert</b>, invert the selection.
* @param TControl|string list control
* @param string selection method
* @param string|int the value or index to select/check.
+ * @param string selection control type, either 'check' or 'select'
*/
- public function select($listControl, $method="Value", $valueOrIndex=null)
+ public function select($control, $method='Value', $value=null, $type=null)
{
- $this->callClientFunction('Prado.Element.select', array($listControl, $method, $valueOrIndex));
+ $method = TPropertyValue::ensureEnum($method,
+ 'Value', 'Index', 'Clear', 'Indices', 'Values', 'All', 'Invert');
+ $type = is_null($type) ? $this->getSelectionControlType($control) : $type;
+ $total = $this->getSelectionControlIsListType($control) ? $control->getItemCount() : 1;
+ $this->callClientFunction('Prado.Element.select',
+ array($control, $type.$method, $value, $total));
}
+
+ private function getSelectionControlType($control)
+ {
+ if(is_string($control)) return 'check';
+ if($control instanceof TCheckBoxList)
+ return 'check';
+ if($control instanceof TCheckBox)
+ return 'check';
+ return 'select';
+ }
+
+ private function getSelectionControlIsListType($control)
+ {
+ return $control instanceof TListControl;
+ }
/**
* Client script to click on an element. <b>This client-side function
@@ -138,7 +161,7 @@ class TCallbackClientScript extends TApplicationComponent
* @param TControl|string control element or element id
* @param TCollection a list of new options
*/
- public function setOptions($control, $items)
+ public function setListItems($control, $items)
{
$options = array();
foreach($items as $item)
diff --git a/framework/Web/UI/ActiveControls/TCallbackTimer.php b/framework/Web/UI/ActiveControls/TCallbackTimer.php
index 7f1aa692..bae41e1f 100644
--- a/framework/Web/UI/ActiveControls/TCallbackTimer.php
+++ b/framework/Web/UI/ActiveControls/TCallbackTimer.php
@@ -11,6 +11,11 @@
*/
/**
+ * Load active callback control.
+ */
+Prado::using('System.Web.UI.ActiveControls.TCallback');
+
+/**
* TCallbackTimer class.
*
* TCallbackTimer sends callback request every {@link setInterval Interval} seconds.
diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php
index 8f43fbab..540ea01e 100644
--- a/framework/Web/UI/TClientScriptManager.php
+++ b/framework/Web/UI/TClientScriptManager.php
@@ -198,12 +198,14 @@ class TClientScriptManager extends TApplicationComponent
}
/**
- * Registers postback javascript for a control.
+ * Registers postback javascript for a control. A null class parameter will prevent
+ * the javascript code registration.
* @param string javascript class responsible for the control being registered for postback
* @param array postback options
*/
public function registerPostBackControl($class,$options)
{
+ if(is_null($class)) return;
if(!isset($options['FormID']) && ($form=$this->_page->getForm())!==null)
$options['FormID']=$form->getClientID();
$optionString=TJavaScript::encode($options);
diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php
index d1767d57..34aeb85e 100644
--- a/framework/Web/UI/TControl.php
+++ b/framework/Web/UI/TControl.php
@@ -1000,20 +1000,44 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable
}
/**
- * @return boolean true if the control has been initialized.
+ * @return boolean true if the child control has been initialized.
*/
- public function getIsInitialized()
+ public function getHasChildInitialized()
{
return $this->getControlStage() >= self::CS_CHILD_INITIALIZED;
}
/**
+ * @return boolean true if the onInit event has raised.
+ */
+ public function getHasInitialized()
+ {
+ return $this->getControlStage() >= self::CS_INITIALIZED;
+ }
+
+ /**
* @return boolean true if the control has loaded post data.
*/
public function getHasLoadedPostData()
{
+ return $this->getControlStage() >= self::CS_STATE_LOADED;
+ }
+
+ /**
+ * @return boolean true if the onLoad event has raised.
+ */
+ public function getHasLoaded()
+ {
return $this->getControlStage() >= self::CS_LOADED;
}
+
+ /**
+ * @return boolean true if onPreRender event has raised.
+ */
+ public function getHasPreRendered()
+ {
+ return $this->getControlStage() >= self::CS_PRERENDERED;
+ }
/**
* Returns the named registered object.
@@ -1250,12 +1274,19 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable
$control->evaluateDynamicContent();
}
}
-
- if($this instanceof IPostBackDataHandler)
- $this->getPage()->registerPostDataLoader($this);
+ $this->addToPostDataLoader();
}
$this->_stage=self::CS_PRERENDERED;
}
+
+ /**
+ * Add controls implementing IPostBackDataHandler to post data loaders.
+ */
+ protected function addToPostDataLoader()
+ {
+ if($this instanceof IPostBackDataHandler)
+ $this->getPage()->registerPostDataLoader($this);
+ }
/**
* Performs the Unload step for the control and all its child controls.
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
index 838d0342..57c66a31 100644
--- a/framework/Web/UI/TPage.php
+++ b/framework/Web/UI/TPage.php
@@ -291,8 +291,10 @@ class TPage extends TTemplateControl
$this->onPreLoad(null);
Prado::trace("Page loadRecursive()",'System.Web.UI.TPage');
$this->loadRecursive();
+
Prado::trace("Page processPostData()",'System.Web.UI.TPage');
$this->processPostData($this->_restPostData,false);
+
Prado::trace("Page raiseChangedEvents()",'System.Web.UI.TPage');
$this->raiseChangedEvents();
@@ -388,7 +390,8 @@ class TPage extends TTemplateControl
*/
public function registerPostDataLoader($control)
{
- $this->_postDataLoaders[] = $control->getUniqueID();
+ $id=is_string($control)?$control:$control->getUniqueID();
+ $this->_postDataLoaders[$id] = true;
}
/**
@@ -397,7 +400,7 @@ class TPage extends TTemplateControl
*/
public function getPostDataLoaders()
{
- return $this->_postDataLoaders;
+ return array_keys($this->_postDataLoaders);
}
/**
@@ -747,6 +750,7 @@ class TPage extends TTemplateControl
{
$id=is_string($control)?$control:$control->getUniqueID();
$this->_controlsRegisteredForPostData[$id]=true;
+ $this->registerPostDataLoader($id);
$params=func_get_args();
foreach($this->getCachingStack() as $item)
$item->registerAction('Page','registerRequiresPostData',$id);
diff --git a/framework/Web/UI/WebControls/TBulletedList.php b/framework/Web/UI/WebControls/TBulletedList.php
index 5499a9eb..c47b1035 100644
--- a/framework/Web/UI/WebControls/TBulletedList.php
+++ b/framework/Web/UI/WebControls/TBulletedList.php
@@ -395,6 +395,14 @@ class TBulletedList extends TListControl implements IPostBackEventHandler
{
throw new TNotSupportedException('bulletedlist_selectedvalue_unsupported');
}
+
+ /**
+ * @throws TNotSupportedException if this method is invoked
+ */
+ public function setSelectedValues($values)
+ {
+ throw new TNotSupportedException('bulletedlist_selectedvalue_unsupported');
+ }
}
/**
diff --git a/framework/Web/UI/WebControls/TCheckBox.php b/framework/Web/UI/WebControls/TCheckBox.php
index 9f26b02c..6fe562c9 100644
--- a/framework/Web/UI/WebControls/TCheckBox.php
+++ b/framework/Web/UI/WebControls/TCheckBox.php
@@ -347,7 +347,7 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl
$writer->addAttribute('type','checkbox');
if(($value = $this->getValueAttribute()) !== '')
$writer->addAttribute('value',$value);
- if($onclick!=='')
+ if(!empty($onclick))
$writer->addAttribute('onclick',$onclick);
if(($uniqueID=$this->getUniqueID())!=='')
$writer->addAttribute('name',$uniqueID);
diff --git a/framework/Web/UI/WebControls/THyperLink.php b/framework/Web/UI/WebControls/THyperLink.php
index 011ce4db..7827038a 100644
--- a/framework/Web/UI/WebControls/THyperLink.php
+++ b/framework/Web/UI/WebControls/THyperLink.php
@@ -68,15 +68,26 @@ class THyperLink extends TWebControl
}
else
{
- $image=Prado::createComponent('System.Web.UI.WebControls.TImage');
- $image->setImageUrl($imageUrl);
- if(($toolTip=$this->getToolTip())!=='')
- $image->setToolTip($toolTip);
- if(($text=$this->getText())!=='')
- $image->setAlternateText($text);
- $image->renderControl($writer);
+ $this->createImage($imageUrl)->renderControl($writer);
}
}
+
+ /**
+ * Gets the TImage for rendering the ImageUrl property. This is not for
+ * creating dynamic images.
+ * @param string image url.
+ * @return TImage image control for rendering.
+ */
+ protected function createImage($imageUrl)
+ {
+ $image=Prado::createComponent('System.Web.UI.WebControls.TImage');
+ $image->setImageUrl($imageUrl);
+ if(($toolTip=$this->getToolTip())!=='')
+ $image->setToolTip($toolTip);
+ if(($text=$this->getText())!=='')
+ $image->setAlternateText($text);
+ return $image;
+ }
/**
* @return string the text caption of the THyperLink
diff --git a/framework/Web/UI/WebControls/TListControl.php b/framework/Web/UI/WebControls/TListControl.php
index a9087af5..3ad46db8 100644
--- a/framework/Web/UI/WebControls/TListControl.php
+++ b/framework/Web/UI/WebControls/TListControl.php
@@ -436,6 +436,8 @@ abstract class TListControl extends TDataBoundControl
throw new TInvalidDataValueException('listcontrol_selectedindex_invalid',get_class($this),$index);
}
$this->_cachedSelectedIndex=$index;
+ if($this->getAdapter() instanceof IListControlAdaptee)
+ $this->getAdapter()->setSelectedIndex($index);
}
/**
@@ -469,6 +471,9 @@ abstract class TListControl extends TDataBoundControl
$this->_items->itemAt($index)->setSelected(true);
}
}
+
+ if($this->getAdapter() instanceof IListControlAdaptee)
+ $this->getAdapter()->setSelectedIndices($indices);
}
/**
@@ -512,6 +517,8 @@ abstract class TListControl extends TDataBoundControl
throw new TInvalidDataValueException('listcontrol_selectedvalue_invalid',get_class($this),$value);
}
$this->_cachedSelectedValue=$value;
+ if($this->getAdapter() instanceof IListControlAdaptee)
+ $this->getAdapter()->setSelectedValue($value);
}
@@ -551,6 +558,9 @@ abstract class TListControl extends TDataBoundControl
throw new TInvalidDataValueException('listcontrol_selectedvalue_invalid',get_class($this),$value);
}
}
+
+ if($this->getAdapter() instanceof IListControlAdaptee)
+ $this->getAdapter()->setSelectedValues($values);
}
/**
@@ -579,6 +589,9 @@ abstract class TListControl extends TDataBoundControl
foreach($this->_items as $item)
$item->setSelected(false);
}
+
+ if($this->getAdapter() instanceof IListControlAdaptee)
+ $this->getAdapter()->clearSelection();
}
/**
@@ -707,13 +720,24 @@ class TListItemCollection extends TList
*/
public function createListItem($index=-1)
{
- $item=new TListItem;
+ $item=$this->createNewListItem();
if($index<0)
$this->add($item);
else
$this->insertAt($index,$item);
return $item;
}
+
+ /**
+ * @return TListItem new item.
+ */
+ protected function createNewListItem($text=null)
+ {
+ $item = new TListItem;
+ if(!is_null($text))
+ $item->setText($text);
+ return $item;
+ }
/**
* Inserts an item into the collection.
@@ -724,15 +748,11 @@ class TListItemCollection extends TList
*/
public function insertAt($index,$item)
{
- if($item instanceof TListItem)
- parent::insertAt($index,$item);
- else if(is_string($item))
- {
- $item=$this->createListItem($index);
- $item->setText($item);
- }
- else
+ if(is_string($item))
+ $item = $this->createNewListItem($item);
+ if(!($item instanceof TListItem))
throw new TInvalidDataTypeException('listitemcollection_item_invalid',get_class($this));
+ parent::insertAt($index,$item);
}
/**
@@ -824,4 +844,44 @@ class TListItemCollection extends TList
}
}
+/**
+ * IListControlAdapter interface
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ Sun Jun 25 04:53:43 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+interface IListControlAdaptee
+{
+ /**
+ * Selects an item based on zero-base index on the client side.
+ * @param integer the index (zero-based) of the item to be selected
+ */
+ public function setSelectedIndex($index);
+ /**
+ * Selects a list of item based on zero-base indices on the client side.
+ * @param array list of index of items to be selected
+ */
+ public function setSelectedIndices($indices);
+
+ /**
+ * Sets selection by item value on the client side.
+ * @param string the value of the item to be selected.
+ */
+ public function setSelectedValue($value);
+
+ /**
+ * Sets selection by a list of item values on the client side.
+ * @param array list of the selected item values
+ */
+ public function setSelectedValues($values);
+
+ /**
+ * Clears all existing selections on the client side.
+ */
+ public function clearSelection();
+}
+
+
?>
diff --git a/tests/FunctionalTests/active-controls/protected/pages/ActiveDropDownList.page b/tests/FunctionalTests/active-controls/protected/pages/ActiveDropDownList.page
new file mode 100644
index 00000000..8b8962a8
--- /dev/null
+++ b/tests/FunctionalTests/active-controls/protected/pages/ActiveDropDownList.page
@@ -0,0 +1,26 @@
+<com:TForm ID="form1">
+ <h1>Active Drop Down List Test Case</h1>
+
+ <com:TActiveDropDownList ID="list1" AutoPostBack="true" OnSelectedIndexChanged="list1_changed">
+ <com:TListItem Value="value 1" Text="item 1" />
+ <com:TListItem Value="value 2" Text="item 2" />
+ <com:TListItem Value="value 3" Text="item 3" />
+ <com:TListItem Value="value 4" Text="item 4" />
+ </com:TActiveDropDownList>
+
+ <com:TActiveDropDownList ID="list2"
+ Enabled="false"
+ AutoPostBack="true" OnSelectedIndexChanged="list2_changed" />
+
+ <div style="margin:1em; padding:1em; border:1px solid #ccc; text-align:center;">
+ <com:TActiveLabel ID="label1" Text="Label 1" />
+ </div>
+ <div style="margin:1em; padding:0.5em; text-align:center; border:1px solid #ccc;">
+ <com:TActiveButton ID="button1" Text="Select Index 3" OnClick="select_index_3" />
+ <com:TActiveButton ID="button2" Text="Clear selection" OnClick="clear_selections" />
+ <com:TActiveButton ID="button3" Text="Select Value 'value 2'" OnClick="select_value_2" />
+ </div>
+
+ <com:TJavascriptLogger />
+
+</com:TForm> \ No newline at end of file
diff --git a/tests/FunctionalTests/active-controls/protected/pages/ActiveDropDownList.php b/tests/FunctionalTests/active-controls/protected/pages/ActiveDropDownList.php
new file mode 100644
index 00000000..7060d84b
--- /dev/null
+++ b/tests/FunctionalTests/active-controls/protected/pages/ActiveDropDownList.php
@@ -0,0 +1,39 @@
+<?php
+
+class ActiveDropDownList extends TPage
+{
+ function list1_changed($sender)
+ {
+ $this->label1->setText("Selection 1: ".$sender->getSelectedValue());
+ $this->addOptionsToList2($sender->getSelectedValue());
+ }
+
+ function addOptionsToList2($parent)
+ {
+ for($i = 0; $i < 5; $i++)
+ $this->list2->Items[$i] = $parent.' - item '.($i+1);
+ $this->list2->setEnabled(true);
+ }
+
+ function list2_changed($sender)
+ {
+ $this->label1->setText("Selection 2: ".$sender->getSelectedValue());
+ }
+
+ function select_index_3()
+ {
+ $this->list1->setSelectedIndex(3);
+ }
+
+ function clear_selections()
+ {
+ $this->list1->clearSelection();
+ }
+
+ function select_value_2()
+ {
+ $this->list1->setSelectedValue("value 2");
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/active-controls/protected/pages/ActiveHyperLinkTest.page b/tests/FunctionalTests/active-controls/protected/pages/ActiveHyperLinkTest.page
new file mode 100644
index 00000000..59098052
--- /dev/null
+++ b/tests/FunctionalTests/active-controls/protected/pages/ActiveHyperLinkTest.page
@@ -0,0 +1,13 @@
+<com:TForm ID="form1">
+ <h1>Active HyperLink Test Case</h1>
+
+ <div style="margin:1em; padding:1em; border:1px solid #ccc; text-align:center;">
+ <com:TActiveHyperLink ID="link1" Text="Link 1" NavigateUrl="http://www.pradosoft.com" />
+ </div>
+ <com:TActiveButton ID="button1" Text="Change Text" OnClick="change_text" />
+ <com:TActiveButton ID="button2" Text="Change Image" OnClick="change_image" />
+ <com:TActiveButton ID="button3" Text="Change Target" OnClick="change_target" />
+ <com:TActiveButton ID="button4" Text="Change URL" OnClick="change_url" />
+
+ <com:TJavascriptLogger />
+</com:TForm> \ No newline at end of file
diff --git a/tests/FunctionalTests/active-controls/protected/pages/ActiveHyperLinkTest.php b/tests/FunctionalTests/active-controls/protected/pages/ActiveHyperLinkTest.php
new file mode 100644
index 00000000..cd4880d2
--- /dev/null
+++ b/tests/FunctionalTests/active-controls/protected/pages/ActiveHyperLinkTest.php
@@ -0,0 +1,26 @@
+<?php
+
+class ActiveHyperLinkTest extends TPage
+{
+ function change_text()
+ {
+ $this->link1->Text = "Pradosoft.com";
+ }
+
+ function change_image()
+ {
+ $this->link1->ImageUrl = "...";
+ }
+
+ function change_target()
+ {
+ $this->link1->Target = "_top";
+ }
+
+ function change_url()
+ {
+ $this->link1->NavigateUrl = "http://www.xlab6.com";
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/active-controls/protected/pages/TActiveCheckBoxListTest.page b/tests/FunctionalTests/active-controls/protected/pages/TActiveCheckBoxListTest.page
new file mode 100644
index 00000000..b30ced69
--- /dev/null
+++ b/tests/FunctionalTests/active-controls/protected/pages/TActiveCheckBoxListTest.page
@@ -0,0 +1,24 @@
+<com:TForm ID="form1">
+ <h1>TActiveCheckBoxList Test Case</h1>
+
+ <com:TActiveCheckBoxList ID="list1" OnCallback="list1_callback">
+ <com:TListItem Value="value 1" Text="item 1" />
+ <com:TListItem Value="value 2" Text="item 2" />
+ <com:TListItem Value="value 3" Text="item 3" />
+ <com:TListItem Value="value 4" Text="item 4" />
+ <com:TListItem Value="value 5" Text="item 5" />
+ </com:TActiveCheckBoxList>
+ <div style="margin:1em; padding:1em; border:1px solid #ccc; text-align:center;">
+ <com:TActiveLabel ID="label1" Text="Label 1" />
+ </div>
+ <div style="margin:1em; padding:0.5em; text-align:center; border:1px solid #ccc;">
+ <com:TActiveButton ID="button1" Text="Select Index 1 2 3" OnClick="select_index_123" />
+ <com:TActiveButton ID="button2" Text="Clear selection" OnClick="clear_selections" />
+ <com:TActiveButton ID="button3" Text="Select Value 'value 1'" OnClick="select_value_1" />
+ <com:TActiveButton ID="button4" Text="Select Index 4" OnClick="select_index_4" />
+ <com:TActiveButton ID="button5" Text="Select Values 'value 2', 'value 5'" OnClick="select_values_25" />
+ </div>
+
+ <com:TJavascriptLogger />
+
+</com:TForm> \ No newline at end of file
diff --git a/tests/FunctionalTests/active-controls/protected/pages/TActiveCheckBoxListTest.php b/tests/FunctionalTests/active-controls/protected/pages/TActiveCheckBoxListTest.php
new file mode 100644
index 00000000..66bfe83d
--- /dev/null
+++ b/tests/FunctionalTests/active-controls/protected/pages/TActiveCheckBoxListTest.php
@@ -0,0 +1,37 @@
+<?php
+
+class TActiveCheckBoxListTest extends TPage
+{
+ function list1_callback($sender, $param)
+ {
+ $values = $sender->getSelectedValues();
+ $this->label1->setText("Selection: ".implode(', ', $values));
+ }
+
+ function select_index_123()
+ {
+ $this->list1->setSelectedIndices(array(1,2,3));
+ }
+
+ function select_index_4()
+ {
+ $this->list1->setSelectedIndex(4);
+ }
+
+ function clear_selections()
+ {
+ $this->list1->clearSelection();
+ }
+
+ function select_value_1()
+ {
+ $this->list1->setSelectedValue("value 1");
+ }
+
+ function select_values_25()
+ {
+ $this->list1->setSelectedValues(array('value 2', 'value 5'));
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/active-controls/tests/ActiveCheckBoxListTestCase.php b/tests/FunctionalTests/active-controls/tests/ActiveCheckBoxListTestCase.php
new file mode 100644
index 00000000..af7ea1f0
--- /dev/null
+++ b/tests/FunctionalTests/active-controls/tests/ActiveCheckBoxListTestCase.php
@@ -0,0 +1,57 @@
+<?php
+
+class ActiveCheckBoxListTestCase extends SeleniumTestCase
+{
+ function test()
+ {
+ $this->open("active-controls/index.php?page=TActiveCheckBoxListTest");
+ $this->verifyTextPresent("TActiveCheckBoxList Test Case");
+
+ $this->assertText("label1", "Label 1");
+
+ $this->click("button1");
+ $this->pause(500);
+ $this->assertCheckBoxes(array(1,2,3));
+
+ $this->click("button2");
+ $this->pause(500);
+ $this->assertCheckBoxes(array());
+
+
+ $this->click("button3");
+ $this->pause(500);
+ $this->assertCheckBoxes(array(0));
+
+
+ $this->click("button4");
+ $this->pause(500);
+ $this->assertCheckBoxes(array(4));
+
+
+ $this->click("button5");
+ $this->pause(500);
+ $this->assertCheckBoxes(array(1,4));
+
+ $this->click("list1_c2");
+ $this->pause(500);
+ $this->assertText("label1", "Selection: value 2, value 3, value 5");
+
+ $this->click("list1_c2");
+ $this->pause(500);
+ $this->assertText("label1", "Selection: value 2, value 5");
+
+ }
+
+ function assertCheckBoxes($checks, $total = 5)
+ {
+ for($i = 0; $i < $total; $i++)
+ {
+ if(in_array($i, $checks))
+ $this->assertChecked("list1_c{$i}");
+ else
+ $this->assertNotChecked("list1_c{$i}");
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/active-controls/tests/ActiveDropDownListTestCase.php b/tests/FunctionalTests/active-controls/tests/ActiveDropDownListTestCase.php
new file mode 100644
index 00000000..5806a3ec
--- /dev/null
+++ b/tests/FunctionalTests/active-controls/tests/ActiveDropDownListTestCase.php
@@ -0,0 +1,41 @@
+<?php
+
+class ActiveDropDownListTestCase extends SeleniumTestCase
+{
+ function test()
+ {
+ $this->open("active-controls/index.php?page=ActiveDropDownList");
+ $this->assertTextPresent('Active Drop Down List Test Case');
+
+ $this->assertText("label1", "Label 1");
+
+ $this->click("button1");
+ $this->pause(500);
+ $this->assertSelected("list1", "item 4");
+
+ $this->click("button2");
+ $this->pause(500);
+ $this->assertEmptySelection("list1");
+
+ $this->click("button3");
+ $this->pause(500);
+ $this->assertSelected("list1", "item 2");
+
+ // due to clearing selection and then updating the selection
+ // otherwise it should not fire the changed event (fired by js because of change to options).
+ $this->assertText("label1", "Selection 1: value 1");
+
+ $this->select("list2", "value 1 - item 4");
+ $this->pause(500);
+ $this->assertText("label1", "Selection 2: value 1 - item 4");
+
+ $this->select("list1", "item 3");
+ $this->pause(500);
+ $this->select("list2", "value 3 - item 5");
+ $this->pause(500);
+ $this->assertText("label1", "Selection 2: value 3 - item 5");
+
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/active-controls/tests/ActiveHyperLinkTestCase.php b/tests/FunctionalTests/active-controls/tests/ActiveHyperLinkTestCase.php
new file mode 100644
index 00000000..53198806
--- /dev/null
+++ b/tests/FunctionalTests/active-controls/tests/ActiveHyperLinkTestCase.php
@@ -0,0 +1,18 @@
+<?php
+
+class ActiveHyperLinkTestCase extends SeleniumTestCase
+{
+ function test()
+ {
+ $this->open("active-controls/index.php?page=ActiveHyperLinkTest");
+ $this->assertTextPresent("Active HyperLink Test Case");
+
+ $this->assertText("link1", "Link 1");
+
+ $this->click("button1");
+ $this->pause(500);
+ $this->assertText("link1", "Pradosoft.com");
+ }
+}
+
+?> \ No newline at end of file
diff --git a/tests/FunctionalTests/selenium/prado-functional-test.js b/tests/FunctionalTests/selenium/prado-functional-test.js
index f9889a72..306f6a74 100644
--- a/tests/FunctionalTests/selenium/prado-functional-test.js
+++ b/tests/FunctionalTests/selenium/prado-functional-test.js
@@ -39,7 +39,21 @@ Selenium.prototype._isDisplayed = function(element) {
return true;
};
-
+Selenium.prototype.assertEmptySelection = function(selectLocator, optionLocator)
+{
+ /**
+ * Verifies that the selected option of a drop-down satisfies the optionSpecifier.
+ *
+ * <p>See the select command for more information about option locators.</p>
+ *
+ * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
+ * @param optionLocator an option locator, typically just an option label (e.g. "John Smith")
+ */
+ var element = this.page().findElement(selectLocator);
+ var locator = this.optionLocatorFactory.fromLocatorString(optionLocator);
+ return element.selectedIndex == -1;
+}
+
function runNextTest() {
if (!runAllTests)
return;