diff options
author | Fabio Bas <ctrlaltca@gmail.com> | 2014-02-06 16:23:42 +0100 |
---|---|---|
committer | Fabio Bas <ctrlaltca@gmail.com> | 2014-02-06 16:23:42 +0100 |
commit | 2c1d9d453404ec2e3344ef477bf834a2a3c065af (patch) | |
tree | d309eca34de724db2804e0febaab76a68b50b889 /framework/Web/UI | |
parent | 705a311b3bbc223737a51bec1d2f978554da086a (diff) |
Implemented basic support for callback events for JUI controls; TJuiDraggable and TJuiDroppable examples
Diffstat (limited to 'framework/Web/UI')
-rw-r--r-- | framework/Web/UI/JuiControls/TJuiControlAdapter.php | 133 | ||||
-rw-r--r-- | framework/Web/UI/JuiControls/TJuiDraggable.php | 75 | ||||
-rw-r--r-- | framework/Web/UI/JuiControls/TJuiDroppable.php | 167 | ||||
-rw-r--r-- | framework/Web/UI/JuiControls/TJuiResizable.php | 23 | ||||
-rw-r--r-- | framework/Web/UI/JuiControls/TJuiSelectable.php | 19 | ||||
-rw-r--r-- | framework/Web/UI/JuiControls/TJuiSortable.php | 19 |
6 files changed, 327 insertions, 109 deletions
diff --git a/framework/Web/UI/JuiControls/TJuiControlAdapter.php b/framework/Web/UI/JuiControls/TJuiControlAdapter.php index 58ca34da..a9722a74 100644 --- a/framework/Web/UI/JuiControls/TJuiControlAdapter.php +++ b/framework/Web/UI/JuiControls/TJuiControlAdapter.php @@ -15,7 +15,8 @@ Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter'); * TJuiControlAdapter class * * TJuiControlAdapter is the base adapter class for controls that are - * derived from a jQuery-ui widget. + * derived from a jQuery-ui widget. It exposes convenience methods to + * publish jQuery-UI javascript and css assets. * * @author Fabio Bas <ctrlaltca@gmail.com> * @package System.Web.UI.JuiControls @@ -93,17 +94,20 @@ interface IJuiOptions { public function getOptions(); public function getValidOptions(); + public function getValidEvents(); } /** * TJuiControlOptions interface * - * TJuiControlOptions is an helper class that can collect a series of options + * TJuiControlOptions is an helper class that can collect a list of options * for a control. The control must implement {@link IJuiOptions}. - * The options are validated againg an array of valid options provided by the control. + * The options are validated againg an array of valid options provided by the control itself. * Since component properties are case insensitive, the array of valid options is used * to ensure the option name has the correct case. * The options array can then get retrieved using {@link toArray} and applied to the jQuery-ui widget. + * In addition to the options, this class will render the needed javascript to raise a callback + * for any event for which an handler is defined in the control. * * @author Fabio Bas <ctrlaltca@gmail.com> * @package System.Web.UI.JuiControls @@ -115,7 +119,9 @@ class TJuiControlOptions * @var TMap map of javascript options. */ private $_options; - + /** + * @var TControl parent control. + */ private $_control; public function __construct($control) @@ -128,22 +134,24 @@ class TJuiControlOptions * Sets a named options with a value. Options are used to store and retrive * named values for the javascript control. * @param string option name. - * @param mixed new value. - * @param mixed default value. - * @return mixed options value. + * @param mixed option value. + * @throws THttpException */ public function __set($name,$value) { if($this->_options===null) $this->_options=array(); + + $tmpname=strtolower($name); foreach($this->_control->getValidOptions() as $option) { - if($name == strtolower($option)) + if($tmpname == $option) { $this->_options[$option] = $value; return; } } + throw new THttpException(500,'juioptions_option_invalid',$control->ID, $name); } @@ -151,23 +159,118 @@ class TJuiControlOptions * Gets an option named value. Options are used to store and retrive * named values for the base active controls. * @param string option name. - * @param mixed default value. - * @return mixed options value. + * @return mixed options value or null if not set. */ public function __get($name) { if($this->_options===null) $this->_options=array(); - return isset($this->_options[$name]) ? $this->_options[$name] : null; + + $tmpname=strtolower($name); + if(isset($this->_options[$tmpname])) + return $this->_options[$tmpname]; + + return null; } /** - * @return TMap active control options + * @return Array of active control options */ public function toArray() { - if($this->_options===null) - $this->_options=array(); - return $this->_options; + $ret= ($this->_options===null) ? $this->_options : array(); + + foreach($this->_control->getValidEvents() as $event) + if($this->_control->hasEventHandler('on'.$event)) + $ret[$event]=new TJavaScriptLiteral("function( event, ui ) { Prado.JuiCallback(".TJavascript::encode($this->_control->getUniqueID()).", ".TJavascript::encode($event).", event, ui, this); }"); + + return $ret; + } + + /** + * Raise the specific callback event handler of the target control. + * @param mixed callback parameters + */ + public function raiseCallbackEvent($param) + { + $callbackParam=$param->CallbackParameter; + if(isset($callbackParam->event)) + { + $eventName = 'On'.ucfirst($callbackParam->event); + if($this->_control->hasEventHandler($eventName)) + { + $this->_control->$eventName( new TJuiEventParameter( + $this->_control->getResponse(), + isset($callbackParam->ui) ? $callbackParam->ui : null) + ); + } + } } } + +/** + * TJuiEventParameter class + * + * TJuiEventParameter encapsulate the parameters for callback + * events of TJui* components. + * Any parameter representing a control is identified by its + * clientside ID. + * TJuiEventParameter contains a {@link getControl} helper method + * that retrieves an existing PRADO control on che current page from its + * clientside ID as returned by the callback. + * For example, if the parameter contains a "draggable" item (as returned in + * {@link TJuiDroppable}::OnDrop event), the relative PRADO control can be + * retrieved using: + * <code> + * $draggable = $param->getControl($param->getCallbackParameter()->draggable); + * </code> + * + * A shortcut __get() method is implemented, too: + * <code> + * $draggable = $param->DraggableControl; + * </code> + * + * @author Fabio Bas <ctrlaltca[at]gmail[dot]com> + * @license http://www.pradosoft.com/license + * @package System.Web.UI.JuiControls + */ +class TJuiEventParameter extends TCallbackEventParameter +{ + /** + * getControl + * + * Compatibility method to get a control from its clientside id + * @return TControl control, or null if not found + */ + public function getControl($id) + { + $control=null; + $service=prado::getApplication()->getService(); + if ($service instanceof TPageService) + { + // Find the control + // Warning, this will not work if you have a '_' in your control Id ! + $controlId=str_replace(TControl::CLIENT_ID_SEPARATOR,TControl::ID_SEPARATOR,$id); + $control=$service->getRequestedPage()->findControl($controlId); + } + return $control; + } + + /** + * Gets a control instance named after a returned control id. + * Example: if a $param->draggable control id is returned from clientside, + * calling $param->DraggableControl will return the control instance + * @return mixed control or null if not set. + */ + public function __get($name) + { + $pos=strpos($name, 'Control',1); + $name=strtolower(substr($name, 0, $pos)); + + $cp=$this->getCallbackParameter(); + if(!isset($cp->$name) || $cp->$name=='') + return null; + + return $this->getControl($cp->$name); + } +}
\ No newline at end of file diff --git a/framework/Web/UI/JuiControls/TJuiDraggable.php b/framework/Web/UI/JuiControls/TJuiDraggable.php index 19d334aa..56e6c7e7 100644 --- a/framework/Web/UI/JuiControls/TJuiDraggable.php +++ b/framework/Web/UI/JuiControls/TJuiDraggable.php @@ -10,16 +10,22 @@ */ Prado::using('System.Web.UI.JuiControls.TJuiControlAdapter'); +Prado::using('System.Web.UI.ActiveControls.TActivePanel'); /** * TJuiDraggable class. * + * TJuiDraggable is an extension to {@link TActivePanel} based on jQuery-UI's + * {@link http://jqueryui.com/draggable/ Draggable} interaction. + * The panel can be moved using the mouse, and eventually dropped over a + * {@link TJuiDroppable}. * * <code> * <com:TJuiDraggable * ID="drag1" * Style="border: 1px solid red; width:100px;height:100px" * Options.Axis="y" + * OnStop="drag1_dragged" * > * drag me * </com:TJuiDraggable> @@ -29,8 +35,10 @@ Prado::using('System.Web.UI.JuiControls.TJuiControlAdapter'); * @package System.Web.UI.JuiControls * @since 3.3 */ -class TJuiDraggable extends TActivePanel implements IJuiOptions +class TJuiDraggable extends TActivePanel implements IJuiOptions, ICallbackEventHandler { + protected $_options; + /** * Creates a new callback control, sets the adapter to * TActiveControlAdapter. If you override this class, be sure to set the @@ -48,10 +56,9 @@ class TJuiDraggable extends TActivePanel implements IJuiOptions */ public function getOptions() { - static $options; - if($options===null) - $options=new TJuiControlOptions($this); - return $options; + if($this->_options===null) + $this->_options=new TJuiControlOptions($this); + return $this->_options; } /** @@ -64,12 +71,20 @@ class TJuiDraggable extends TActivePanel implements IJuiOptions } /** + * Array containing valid javascript events + * @return array() + */ + public function getValidEvents() + { + return array('create', 'drag', 'start', 'stop'); + } + + /** * @return array list of callback options. */ protected function getPostBackOptions() { - $options = $this->getOptions()->toArray(); - return $options; + return $this->getOptions()->toArray(); } /** @@ -86,4 +101,50 @@ class TJuiDraggable extends TActivePanel implements IJuiOptions $code="jQuery('#".$this->getClientId()."').draggable(".$options.");"; $cs->registerEndScript(sprintf('%08X', crc32($code)), $code); } + + /** + * Raises callback event. This method is required by the {@link ICallbackEventHandler} + * interface. + * @param TCallbackEventParameter the parameter associated with the callback event + */ + public function raiseCallbackEvent($param) + { + $this->getOptions()->raiseCallbackEvent($param); + } + + /** + * Raises the OnCreate event + * @param object $params event parameters + */ + public function onCreate ($params) + { + $this->raiseEvent('OnCreate', $this, $params); + } + + /** + * Raises the OnDrag event + * @param object $params event parameters + */ + public function onDrag ($params) + { + $this->raiseEvent('OnDrag', $this, $params); + } + + /** + * Raises the OnStart event + * @param object $params event parameters + */ + public function onStart ($params) + { + $this->raiseEvent('OnStart', $this, $params); + } + + /** + * Raises the OnStop event + * @param object $params event parameters + */ + public function onStop ($params) + { + $this->raiseEvent('OnStop', $this, $params); + } } diff --git a/framework/Web/UI/JuiControls/TJuiDroppable.php b/framework/Web/UI/JuiControls/TJuiDroppable.php index 6c07e49c..3c79f536 100644 --- a/framework/Web/UI/JuiControls/TJuiDroppable.php +++ b/framework/Web/UI/JuiControls/TJuiDroppable.php @@ -15,6 +15,13 @@ Prado::using('System.Web.UI.ActiveControls.TActivePanel'); /** * TJuiDroppable class. * + * TJuiDroppable is an extension to {@link TActivePanel} based on jQuery-UI's + * {@link http://jqueryui.com/droppable/ Droppable} interaction. + * When a {@link TJuiDraggable} is dropped over a TJuiDroppable panel, the + * {@link onDrop OnDrop} event will be triggered. An event hanler will receive + * a {@link TJuiEventParameter} object containing a reference to the dropped control + * in the <tt>DraggableControl</tt> property. + * * <code> * <com:TJuiDraggable * ID="drag1" @@ -35,11 +42,12 @@ Prado::using('System.Web.UI.ActiveControls.TActivePanel'); * <code> * public function drop1_ondrop($sender, $param) * { - * $draggable=$param->getDroppedControl()->ID; - * $this->drop1->Controls->clear(); - * $this->drop1->Controls->add("Dropped ".$draggable." at: <br/>Top=".$param->getOffsetTop()." Left=".$param->getOffsetLeft()); - * // it's still an active panel, after all - * $this->drop1->render($param->NewWriter); + * $draggable=$param->DraggableControl; + * $offset=$param->getCallbackParameter()->offset; + * $target=$param->getCallbackParameter()->target->offset; + * $top=$offset->top - $target->top; + * $left=$offset->left - $target->left; + * $this->label1->Text="Dropped ".$draggable->ID." at: <br/>Top=".$top." Left=".$left; * } * </code> * @@ -49,6 +57,8 @@ Prado::using('System.Web.UI.ActiveControls.TActivePanel'); */ class TJuiDroppable extends TActivePanel implements IJuiOptions, ICallbackEventHandler { + protected $_options; + /** * Creates a new callback control, sets the adapter to * TActiveControlAdapter. If you override this class, be sure to set the @@ -66,10 +76,9 @@ class TJuiDroppable extends TActivePanel implements IJuiOptions, ICallbackEventH */ public function getOptions() { - static $options; - if($options===null) - $options=new TJuiControlOptions($this); - return $options; + if($this->_options===null) + $this->_options=new TJuiControlOptions($this); + return $this->_options; } /** @@ -82,103 +91,111 @@ class TJuiDroppable extends TActivePanel implements IJuiOptions, ICallbackEventH } /** + * Array containing valid javascript events + * @return array() + */ + public function getValidEvents() + { + return array('activate', 'create', 'deactivate', 'drop', 'out', 'over'); + } + + /** * @return array list of callback options. */ protected function getPostBackOptions() { - $options = $this->getOptions()->toArray(); - $options['drop'] = new TJavaScriptLiteral("function( event, ui ) { Prado.Callback(".TJavascript::encode($this->getUniqueID()).", { 'offset' : { 'left' : ui.offset.left - $(this).offset().left, 'top' : ui.offset.top - $(this).offset().top }, 'position' : ui.position, 'draggable' : ui.draggable.get(0).id }) }"); - return $options; + return $this->getOptions()->toArray(); } /** - * Raises callback event. This method is required bu {@link ICallbackEventHandler} + * 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()); + $options=TJavascript::encode($this->getPostBackOptions()); + $cs=$this->getPage()->getClientScript(); + $code="jQuery('#".$this->getClientId()."').droppable(".$options.");"; + $cs->registerEndScript(sprintf('%08X', crc32($code)), $code); + } + + /** + * Raises callback event. This method is required by the {@link ICallbackEventHandler} * interface. - * It raises the {@link onDrop OnDrop} event, then, the {@link onCallback OnCallback} event - * This method is mainly used by framework and control developers. * @param TCallbackEventParameter the parameter associated with the callback event */ public function raiseCallbackEvent($param) { - $this->onDrop($param->getCallbackParameter()); - $this->onCallback($param); + $this->getOptions()->raiseCallbackEvent($param); } /** - * Raises the onDrop event. - * The drop parameters are encapsulated into a {@link TJuiDroppableEventParameter} - * - * @param object $dropControlId + * Raises the OnActivate event + * @param object $params event parameters */ - public function onDrop ($dropParams) + public function onActivate ($params) { - $this->raiseEvent('OnDrop', $this, new TJuiDroppableEventParameter ($this->getResponse(), $dropParams)); + $this->raiseEvent('OnActivate', $this, $params); + } + /** + * Raises the OnCreate event + * @param object $params event parameters + */ + public function onCreate ($params) + { + $this->raiseEvent('OnCreate', $this, $params); } /** - * 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 + * Raises the OnDeactivate event + * @param object $params event parameters */ - public function onCallback($param) + public function onDeactivate ($params) { - $this->raiseEvent('OnCallback', $this, $param); + $this->raiseEvent('OnDeactivate', $this, $params); } /** - * Ensure that the ID attribute is rendered and registers the javascript code - * for initializing the active control. + * Raises the OnDrop event + * @param object $params event parameters */ - protected function addAttributesToRender($writer) + public function onDrop ($params) { - parent::addAttributesToRender($writer); + $this->raiseEvent('OnDrop', $this, $params); + } - $writer->addAttribute('id',$this->getClientID()); - $options=TJavascript::encode($this->getPostBackOptions()); - $cs=$this->getPage()->getClientScript(); - $code="jQuery('#".$this->getClientId()."').droppable(".$options.");"; - $cs->registerEndScript(sprintf('%08X', crc32($code)), $code); + /** + * Raises the OnOut event + * @param object $params event parameters + */ + public function OnOut ($params) + { + $this->raiseEvent('OnOut', $this, $params); } -} -/** - * TJuiDroppableEventParameter class - * - * TJuiDroppableEventParameter encapsulate the parameter - * data for <b>OnDrop</b> event of TJuiDroppable components - * - * @author Fabio Bas <ctrlaltca[at]gmail[dot]com> - * @license http://www.pradosoft.com/license - * @package System.Web.UI.JuiControls - */ -class TJuiDroppableEventParameter extends TCallbackEventParameter -{ - public function getDragElementId() { return $this->getCallbackParameter()->draggable; } - public function getPositionTop() { return $this->getCallbackParameter()->position->top; } - public function getPositionLeft() { return $this->getCallbackParameter()->position->left; } - public function getOffsetTop() { return $this->getCallbackParameter()->offset->top; } - public function getOffsetLeft() { return $this->getCallbackParameter()->offset->left; } + /** + * Raises the OnOver event + * @param object $params event parameters + */ + public function OnOver ($params) + { + $this->raiseEvent('OnOver', $this, $params); + } /** - * GetDroppedControl - * - * Compatibility method to get the dropped control - * @return TControl dropped control, or null if not found + * 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 getDroppedControl() - { - $control=null; - $service=prado::getApplication()->getService(); - if ($service instanceof TPageService) - { - // Find the control - // Warning, this will not work if you have a '_' in your control Id ! - $dropControlId=str_replace(TControl::CLIENT_ID_SEPARATOR,TControl::ID_SEPARATOR,$this->getCallbackParameter()->draggable); - $control=$service->getRequestedPage()->findControl($dropControlId); - } - return $control; - } -}
\ No newline at end of file + + public function onCallback($param) + { + $this->raiseEvent('OnCallback', $this, $param); + } +} diff --git a/framework/Web/UI/JuiControls/TJuiResizable.php b/framework/Web/UI/JuiControls/TJuiResizable.php index f4553aef..e5b3b531 100644 --- a/framework/Web/UI/JuiControls/TJuiResizable.php +++ b/framework/Web/UI/JuiControls/TJuiResizable.php @@ -10,10 +10,15 @@ */ Prado::using('System.Web.UI.JuiControls.TJuiControlAdapter'); +Prado::using('System.Web.UI.ActiveControls.TActivePanel'); /** * TJuiResizable class. * + * TJuiResizable is an extension to {@link TActivePanel} based on jQuery-UI's + * {@link http://jqueryui.com/resizable/ Resizable} interaction. + * A small handle is shown on the bottom right corner of the panel, that permits + * the panel to be resized using the mouse. * * <code> * <com:TJuiResizable @@ -34,6 +39,8 @@ Prado::using('System.Web.UI.JuiControls.TJuiControlAdapter'); */ class TJuiResizable extends TActivePanel implements IJuiOptions { + protected $_options; + /** * Creates a new callback control, sets the adapter to * TActiveControlAdapter. If you override this class, be sure to set the @@ -51,10 +58,9 @@ class TJuiResizable extends TActivePanel implements IJuiOptions */ public function getOptions() { - static $options; - if($options===null) - $options=new TJuiControlOptions($this); - return $options; + if($this->_options===null) + $this->_options=new TJuiControlOptions($this); + return $this->_options; } /** @@ -67,6 +73,15 @@ class TJuiResizable extends TActivePanel implements IJuiOptions } /** + * Array containing valid javascript events + * @return array() + */ + public function getValidEvents() + { + return array('create', 'resize', 'start', 'stop'); + } + + /** * @return array list of callback options. */ protected function getPostBackOptions() diff --git a/framework/Web/UI/JuiControls/TJuiSelectable.php b/framework/Web/UI/JuiControls/TJuiSelectable.php index e895c1f8..968f0170 100644 --- a/framework/Web/UI/JuiControls/TJuiSelectable.php +++ b/framework/Web/UI/JuiControls/TJuiSelectable.php @@ -10,6 +10,7 @@ */ Prado::using('System.Web.UI.JuiControls.TJuiControlAdapter'); +Prado::using('System.Web.UI.ActiveControls.TActivePanel'); /** * TJuiSelectable class. @@ -33,6 +34,8 @@ Prado::using('System.Web.UI.JuiControls.TJuiControlAdapter'); */ class TJuiSelectable extends TActivePanel implements IJuiOptions, ICallbackEventHandler { + protected $_options; + /** * Creates a new callback control, sets the adapter to * TActiveControlAdapter. If you override this class, be sure to set the @@ -50,10 +53,9 @@ class TJuiSelectable extends TActivePanel implements IJuiOptions, ICallbackEvent */ public function getOptions() { - static $options; - if($options===null) - $options=new TJuiControlOptions($this); - return $options; + if($this->_options===null) + $this->_options=new TJuiControlOptions($this); + return $this->_options; } /** @@ -66,6 +68,15 @@ class TJuiSelectable extends TActivePanel implements IJuiOptions, ICallbackEvent } /** + * Array containing valid javascript events + * @return array() + */ + public function getValidEvents() + { + return array('create', 'selected', 'selecting', 'start', 'stop', 'unselected', 'unselecting'); + } + + /** * @return array list of callback options. */ protected function getPostBackOptions() diff --git a/framework/Web/UI/JuiControls/TJuiSortable.php b/framework/Web/UI/JuiControls/TJuiSortable.php index 557d62ba..e54dbefb 100644 --- a/framework/Web/UI/JuiControls/TJuiSortable.php +++ b/framework/Web/UI/JuiControls/TJuiSortable.php @@ -10,6 +10,7 @@ */ Prado::using('System.Web.UI.JuiControls.TJuiControlAdapter'); +Prado::using('System.Web.UI.ActiveControls.TActivePanel'); /** * TJuiSortable class. @@ -30,6 +31,8 @@ Prado::using('System.Web.UI.JuiControls.TJuiControlAdapter'); */ class TJuiSortable extends TActivePanel implements IJuiOptions, ICallbackEventHandler { + protected $_options; + /** * Creates a new callback control, sets the adapter to * TActiveControlAdapter. If you override this class, be sure to set the @@ -47,10 +50,9 @@ class TJuiSortable extends TActivePanel implements IJuiOptions, ICallbackEventHa */ public function getOptions() { - static $options; - if($options===null) - $options=new TJuiControlOptions($this); - return $options; + if($this->_options===null) + $this->_options=new TJuiControlOptions($this); + return $this->_options; } /** @@ -63,6 +65,15 @@ class TJuiSortable extends TActivePanel implements IJuiOptions, ICallbackEventHa } /** + * Array containing valid javascript events + * @return array() + */ + public function getValidEvents() + { + return array('activate', 'beforeStop', 'change', 'create', 'deactivate', 'out', 'over', 'receive', 'remove', 'sort', 'start', 'stop', 'update'); + } + + /** * @return array list of callback options. */ protected function getPostBackOptions() |