From 0fb75d64f8dbcc98b4c06e7556125b94bf612819 Mon Sep 17 00:00:00 2001 From: Jens Klaer Date: Wed, 20 May 2015 15:54:33 +0200 Subject: made TJuiControl options changeable during callback - TJuiControlOptions are now stored in viewstate and tracked by the new TJuiCallbackPageStateTracker class extending the default viewstate tracker class - TJuiCallbackPageStateTracker registers endscripts automatically for each changed option for the clientside changes, added some normalized getter for that --- framework/Web/UI/JuiControls/TJuiAutoComplete.php | 24 +++++- .../Web/UI/JuiControls/TJuiControlAdapter.php | 85 +++++++++++++++++++++- framework/Web/UI/JuiControls/TJuiDialog.php | 27 ++++++- framework/Web/UI/JuiControls/TJuiDraggable.php | 27 ++++++- framework/Web/UI/JuiControls/TJuiDroppable.php | 29 ++++++-- framework/Web/UI/JuiControls/TJuiProgressbar.php | 27 ++++++- framework/Web/UI/JuiControls/TJuiResizable.php | 27 ++++++- framework/Web/UI/JuiControls/TJuiSelectable.php | 29 ++++++-- framework/Web/UI/JuiControls/TJuiSortable.php | 29 ++++++-- 9 files changed, 267 insertions(+), 37 deletions(-) (limited to 'framework/Web/UI') diff --git a/framework/Web/UI/JuiControls/TJuiAutoComplete.php b/framework/Web/UI/JuiControls/TJuiAutoComplete.php index f6663057..768f041e 100644 --- a/framework/Web/UI/JuiControls/TJuiAutoComplete.php +++ b/framework/Web/UI/JuiControls/TJuiAutoComplete.php @@ -101,15 +101,33 @@ class TJuiAutoComplete extends TActiveTextBox implements INamingContainer, IJuiO $this->setAdapter(new TJuiControlAdapter($this)); } + /** + * @return string the name of the jQueryUI widget method + */ + public function getWidget() + { + return 'autocomplete'; + } + + /** + * @return string the clientid of the jQueryUI widget element + */ + public function getWidgetID() + { + return $this->getClientID(); + } + /** * Object containing defined javascript options * @return TJuiControlOptions */ public function getOptions() { - static $options; - if($options===null) - $options=new TJuiControlOptions($this); + if (($options=$this->getViewState('JuiOptions'))===null) + { + $options=new TJuiControlOptions($this); + $this->setViewState('JuiOptions', $options); + } return $options; } diff --git a/framework/Web/UI/JuiControls/TJuiControlAdapter.php b/framework/Web/UI/JuiControls/TJuiControlAdapter.php index 3668a8b4..638f60f1 100644 --- a/framework/Web/UI/JuiControls/TJuiControlAdapter.php +++ b/framework/Web/UI/JuiControls/TJuiControlAdapter.php @@ -28,6 +28,17 @@ class TJuiControlAdapter extends TActiveControlAdapter const CSS_PATH = 'css'; const BASE_CSS_FILENAME ='jquery-ui.css'; + /** + * Replace default StateTracker with {@link TJuiCallbackPageStateTracker} for + * options tracking in ViewState. + * @param TEventParameter event parameter to be passed to the event handlers + */ + public function onInit($param) + { + parent::onInit($param); + $this->setStateTracker('TJuiCallbackPageStateTracker'); + } + /** * @param string set the jquery-ui style */ @@ -78,6 +89,15 @@ class TJuiControlAdapter extends TActiveControlAdapter return $url; } + /** + * Calls the parent implementation first and sets the parent control for the + * {@link TJuiControlOptions} again afterwards since it was not serialized in viewstate. + */ + public function loadState() { + parent::loadState(); + $this->getControl()->getOptions()->setControl($this->getControl()); + } + } /** @@ -92,6 +112,8 @@ class TJuiControlAdapter extends TActiveControlAdapter */ interface IJuiOptions { + public function getWidget(); + public function getWidgetID(); public function getOptions(); public function getValidOptions(); public function getValidEvents(); @@ -124,12 +146,27 @@ class TJuiControlOptions */ private $_control; + /** + * Constructor. Set the parent control owning these options. + * @param TControl parent control + */ public function __construct($control) { - if(!$control instanceof IJuiOptions) - throw new THttpException(500,'juioptions_control_invalid',$control->ID); - $this->_control=$control; + $this->setControl($control); } + + /** + * Sets the parent control. + * @param TControl $control + * @throws THttpException + */ + public function setControl($control) + { + if(!$control instanceof IJuiOptions) + throw new THttpException(500,'juioptions_control_invalid',$control->ID); + $this->_control=$control; + } + /** * Sets a named options with a value. Options are used to store and retrive * named values for the javascript control. @@ -189,6 +226,14 @@ class TJuiControlOptions return null; } + /** + * Only serialize the options itself, not the corresponding parent control. + * @return mixed array with the names of all variables of that object that should be serialized. + */ + public function __sleep() { + return array('_options'); + } + /** * @return Array of active control options */ @@ -289,4 +334,38 @@ class TJuiEventParameter extends TCallbackEventParameter return $this->getControl($cp->$name); } +} + +/** + * TJuiCallbackPageStateTracker class. + * + * Tracking changes to the page state during callback, including {@link TJuiControlOptions}. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.JuiControls + * @since 3.3 + */ +class TJuiCallbackPageStateTracker extends TCallbackPageStateTracker { + + /** + * Add the {@link TJuiControlOptions} to the states to track. + */ + protected function addStatesToTrack() + { + parent::addStatesToTrack(); + $states = $this->getStatesToTrack(); + $states['JuiOptions'] = array('TMapCollectionDiff', array($this, 'updateJuiOptions')); + } + + /** + * Updates the options of the jQueryUI widget. + * @param array list of widget options to change. + */ + protected function updateJuiOptions($options) + { + foreach ($options as $key => $value) $options[$key] = $key . ': ' . (is_string($value) ? "'{$value}'" : TPropertyValue::ensureString($value)); + $code = "jQuery('#{$this->_control->getWidgetID()}').{$this->_control->getWidget()}('option', { " . implode(', ', $options) . " });"; + $this->_control->getPage()->getClientScript()->registerEndScript(sprintf('%08X', crc32($code)), $code); + } + } \ No newline at end of file diff --git a/framework/Web/UI/JuiControls/TJuiDialog.php b/framework/Web/UI/JuiControls/TJuiDialog.php index 7168ab16..0460cad5 100644 --- a/framework/Web/UI/JuiControls/TJuiDialog.php +++ b/framework/Web/UI/JuiControls/TJuiDialog.php @@ -46,15 +46,34 @@ class TJuiDialog extends TActivePanel implements IJuiOptions, ICallbackEventHand $this->setAdapter(new TJuiControlAdapter($this)); } + /** + * @return string the name of the jQueryUI widget method + */ + public function getWidget() + { + return 'dialog'; + } + + /** + * @return string the clientid of the jQueryUI widget element + */ + public function getWidgetID() + { + return $this->getClientID(); + } + /** * Object containing defined javascript options * @return TJuiControlOptions */ public function getOptions() { - if($this->_options===null) - $this->_options=new TJuiControlOptions($this); - return $this->_options; + if (($options=$this->getViewState('JuiOptions'))===null) + { + $options=new TJuiControlOptions($this); + $this->setViewState('JuiOptions', $options); + } + return $options; } /** @@ -100,7 +119,7 @@ class TJuiDialog extends TActivePanel implements IJuiOptions, ICallbackEventHand $writer->addAttribute('id',$this->getClientID()); $options=TJavascript::encode($this->getPostBackOptions()); $cs=$this->getPage()->getClientScript(); - $code="jQuery('#".$this->getClientId()."').dialog(".$options.");"; + $code="jQuery('#".$this->getWidgetID()."').".$this->getWidget()."(".$options.");"; $cs->registerEndScript(sprintf('%08X', crc32($code)), $code); } diff --git a/framework/Web/UI/JuiControls/TJuiDraggable.php b/framework/Web/UI/JuiControls/TJuiDraggable.php index 56e6c7e7..ed5c3814 100644 --- a/framework/Web/UI/JuiControls/TJuiDraggable.php +++ b/framework/Web/UI/JuiControls/TJuiDraggable.php @@ -50,15 +50,34 @@ class TJuiDraggable extends TActivePanel implements IJuiOptions, ICallbackEventH $this->setAdapter(new TJuiControlAdapter($this)); } + /** + * @return string the name of the jQueryUI widget method + */ + public function getWidget() + { + return 'draggable'; + } + + /** + * @return string the clientid of the jQueryUI widget element + */ + public function getWidgetID() + { + return $this->getClientID(); + } + /** * Object containing defined javascript options * @return TJuiControlOptions */ public function getOptions() { - if($this->_options===null) - $this->_options=new TJuiControlOptions($this); - return $this->_options; + if (($options=$this->getViewState('JuiOptions'))===null) + { + $options=new TJuiControlOptions($this); + $this->setViewState('JuiOptions', $options); + } + return $options; } /** @@ -98,7 +117,7 @@ class TJuiDraggable extends TActivePanel implements IJuiOptions, ICallbackEventH $writer->addAttribute('id',$this->getClientID()); $options=TJavascript::encode($this->getPostBackOptions()); $cs=$this->getPage()->getClientScript(); - $code="jQuery('#".$this->getClientId()."').draggable(".$options.");"; + $code="jQuery('#".$this->getWidgetID()."').".$this->getWidget()."(".$options.");"; $cs->registerEndScript(sprintf('%08X', crc32($code)), $code); } diff --git a/framework/Web/UI/JuiControls/TJuiDroppable.php b/framework/Web/UI/JuiControls/TJuiDroppable.php index 2d2ed6b9..77c43940 100644 --- a/framework/Web/UI/JuiControls/TJuiDroppable.php +++ b/framework/Web/UI/JuiControls/TJuiDroppable.php @@ -70,15 +70,34 @@ class TJuiDroppable extends TActivePanel implements IJuiOptions, ICallbackEventH $this->setAdapter(new TJuiControlAdapter($this)); } + /** + * @return string the name of the jQueryUI widget method + */ + public function getWidget() + { + return 'droppable'; + } + + /** + * @return string the clientid of the jQueryUI widget element + */ + public function getWidgetID() + { + return $this->getClientID(); + } + /** * Object containing defined javascript options * @return TJuiControlOptions */ public function getOptions() { - if($this->_options===null) - $this->_options=new TJuiControlOptions($this); - return $this->_options; + if (($options=$this->getViewState('JuiOptions'))===null) + { + $options=new TJuiControlOptions($this); + $this->setViewState('JuiOptions', $options); + } + return $options; } /** @@ -87,7 +106,7 @@ class TJuiDroppable extends TActivePanel implements IJuiOptions, ICallbackEventH */ public function getValidOptions() { - return array('addClasses', 'appendTo', 'axis', 'cancel', 'connectToSortable', 'containment', 'cursor', 'cursorAt', 'delay', 'disabled', 'distance', 'grid', 'handle', 'helper', 'iframeFix', 'opacity', 'refreshPositions', 'revert', 'revertDuration', 'scope', 'scroll', 'scrollSensitivity', 'scrollSpeed', 'snap', 'snapMode', 'snapTolerance', 'stack', 'zIndex'); + return array('accept', 'activeClass', 'addClasses', 'disabled', 'greedy', 'hoverClass', 'scope', 'tolerance'); } /** @@ -118,7 +137,7 @@ class TJuiDroppable extends TActivePanel implements IJuiOptions, ICallbackEventH $writer->addAttribute('id',$this->getClientID()); $options=TJavascript::encode($this->getPostBackOptions()); $cs=$this->getPage()->getClientScript(); - $code="jQuery('#".$this->getClientId()."').droppable(".$options.");"; + $code="jQuery('#".$this->getWidgetID()."').".$this->getWidget()."(".$options.");"; $cs->registerEndScript(sprintf('%08X', crc32($code)), $code); } diff --git a/framework/Web/UI/JuiControls/TJuiProgressbar.php b/framework/Web/UI/JuiControls/TJuiProgressbar.php index 41f3eab4..604a41e4 100644 --- a/framework/Web/UI/JuiControls/TJuiProgressbar.php +++ b/framework/Web/UI/JuiControls/TJuiProgressbar.php @@ -46,15 +46,34 @@ class TJuiProgressbar extends TActivePanel implements IJuiOptions, ICallbackEven $this->setAdapter(new TJuiControlAdapter($this)); } + /** + * @return string the name of the jQueryUI widget method + */ + public function getWidget() + { + return 'progressbar'; + } + + /** + * @return string the clientid of the jQueryUI widget element + */ + public function getWidgetID() + { + return $this->getClientID(); + } + /** * Object containing defined javascript options * @return TJuiControlOptions */ public function getOptions() { - if($this->_options===null) - $this->_options=new TJuiControlOptions($this); - return $this->_options; + if (($options=$this->getViewState('JuiOptions'))===null) + { + $options=new TJuiControlOptions($this); + $this->setViewState('JuiOptions', $options); + } + return $options; } /** @@ -94,7 +113,7 @@ class TJuiProgressbar extends TActivePanel implements IJuiOptions, ICallbackEven $writer->addAttribute('id',$this->getClientID()); $options=TJavascript::encode($this->getPostBackOptions()); $cs=$this->getPage()->getClientScript(); - $code="jQuery('#".$this->getClientId()."').progressbar(".$options.");"; + $code="jQuery('#".$this->getWidgetID()."').".$this->getWidget()."(".$options.");"; $cs->registerEndScript(sprintf('%08X', crc32($code)), $code); } diff --git a/framework/Web/UI/JuiControls/TJuiResizable.php b/framework/Web/UI/JuiControls/TJuiResizable.php index 5e1f8d31..ef0cb059 100644 --- a/framework/Web/UI/JuiControls/TJuiResizable.php +++ b/framework/Web/UI/JuiControls/TJuiResizable.php @@ -52,15 +52,34 @@ class TJuiResizable extends TActivePanel implements IJuiOptions, ICallbackEventH $this->setAdapter(new TJuiControlAdapter($this)); } + /** + * @return string the name of the jQueryUI widget method + */ + public function getWidget() + { + return 'resizable'; + } + + /** + * @return string the clientid of the jQueryUI widget element + */ + public function getWidgetID() + { + return $this->getClientID(); + } + /** * Object containing defined javascript options * @return TJuiControlOptions */ public function getOptions() { - if($this->_options===null) - $this->_options=new TJuiControlOptions($this); - return $this->_options; + if (($options=$this->getViewState('JuiOptions'))===null) + { + $options=new TJuiControlOptions($this); + $this->setViewState('JuiOptions', $options); + } + return $options; } /** @@ -101,7 +120,7 @@ class TJuiResizable extends TActivePanel implements IJuiOptions, ICallbackEventH $writer->addAttribute('id',$this->getClientID()); $options=TJavascript::encode($this->getPostBackOptions()); $cs=$this->getPage()->getClientScript(); - $code="jQuery('#".$this->getClientId()."').resizable(".$options.");"; + $code="jQuery('#".$this->getWidgetID()."').".$this->getWidget()."(".$options.");"; $cs->registerEndScript(sprintf('%08X', crc32($code)), $code); } diff --git a/framework/Web/UI/JuiControls/TJuiSelectable.php b/framework/Web/UI/JuiControls/TJuiSelectable.php index b370d14a..5e9570f8 100644 --- a/framework/Web/UI/JuiControls/TJuiSelectable.php +++ b/framework/Web/UI/JuiControls/TJuiSelectable.php @@ -52,15 +52,34 @@ class TJuiSelectable extends TActivePanel implements IJuiOptions, ICallbackEvent $this->setAdapter(new TJuiControlAdapter($this)); } + /** + * @return string the name of the jQueryUI widget method + */ + public function getWidget() + { + return 'selectable'; + } + + /** + * @return string the clientid of the jQueryUI widget element + */ + public function getWidgetID() + { + return $this->getClientID() . '_0'; + } + /** * Object containing defined javascript options * @return TJuiControlOptions */ public function getOptions() { - if($this->_options===null) - $this->_options=new TJuiControlOptions($this); - return $this->_options; + if (($options=$this->getViewState('JuiOptions'))===null) + { + $options=new TJuiControlOptions($this); + $this->setViewState('JuiOptions', $options); + } + return $options; } /** @@ -105,7 +124,7 @@ class TJuiSelectable extends TActivePanel implements IJuiOptions, ICallbackEvent $writer->addAttribute('id',$this->getClientID()); $options=TJavascript::encode($this->getPostBackOptions()); $cs=$this->getPage()->getClientScript(); - $code="jQuery('#".$this->getClientId()."_0').selectable(".$options.");"; + $code="jQuery('#".$this->getWidgetID()."').".$this->getWidget()."(".$options.");"; $cs->registerEndScript(sprintf('%08X', crc32($code)), $code); } @@ -222,7 +241,7 @@ class TJuiSelectable extends TActivePanel implements IJuiOptions, ICallbackEvent protected function createRepeater() { $repeater = Prado::createComponent('System.Web.UI.WebControls.TRepeater'); - $repeater->setHeaderTemplate(new TJuiSelectableTemplate('