Chad 2010-08-10

Sometimes we may want to disable a widget, that is, to set the "disabled" html attribute, but don't want to only display the value of it as text. In this case, a common problem which we might encounter is that, the value of the html entity generated by the widget is never sent back to the server when you submit it either with the post or get method.

To solved this, we can store the value in a hidden field, leaving only a copy of the value to the target html entity. In implementation, we can create a new class which inherits the target widget, so that it will be treated the same as the target widget be in the form system of Symfony. Then create a hidden field inside and change the render method a little, so that the hidden field can take the place of the ogrinal target html entity.

For example, to set a "disabled" html attribute to the sfWidgetFormInputText widget, we can create a widget as below:

Code - PHPPlain Text
 
  1. // lib/widget/inlWidgetFormDisabledInputText.class.php  
  2.   
  3. class inlWidgetFormDisabledInputText extends sfWidgetFormInputText {  
  4.   
  5.     protected function configure($options = array(), $attributes = array()) {  
  6.         $this->addOption('hdfInputText'new sfWidgetFormInputHidden());  
  7.   
  8.         parent::configure($options$attributes);  
  9.     }  
  10.   
  11.     public function render($name$value = null, $attributes = array(), $errors = array()) {  
  12.         return $this->getOption('hdfInputText')->render($name$value$attributes$errors) .  
  13.         parent::render($name . '_disabled'$value$attributes + array('disabled' => 'disabled'), $errors);  
  14.     }  
  15.   
  16. }  

 

The same can be done to other widgets, say, for sfWidgetFormDoctrineChoice, we can create a widget as below:

Code - PHPPlain Text
 
  1. // lib/widget/inlWidgetFormDisabledDoctrineChoice.class.php  
  2.   
  3. class inlWidgetFormDisabledDoctrineChoice extends sfWidgetFormDoctrineChoice {  
  4.   
  5.     protected function configure($options = array(), $attributes = array()) {  
  6.         $this->addOption('hdfInputText'new sfWidgetFormInputHidden());  
  7.   
  8.         parent::configure($options$attributes);  
  9.     }  
  10.   
  11.     public function render($name$value = null, $attributes = array(), $errors = array()) {  
  12.         return $this->getOption('hdfInputText')->render($name$value$attributes$errors) .  
  13.         parent::render($name . '_disabled'$value$attributes + array('disabled' => 'disabled'), $errors);  
  14.     }  
  15.   
  16. }  

 

Isn't that easy to implement? And you might already notice that the code in the two examples are almost the same, except for the first line, which defines the class name and the parent class. I wonder if we can create a generic class for this purpose or not, in stead of copying the same code into each of these kind of "disabled" widgets.