I have a form in Symfony that contains a Choice widget (my database field is called created_group) and I need to show its value to the user but make it not editable, so that the user cannot change the value.
Using the HTML disabled attribute won’t work:
$this -> widgetSchema['created_group']->setAttribute(‘disabled’,'disable’);
as this will show the select field as blurred and thus show the content, but the selected option won’t be sent on a form submit: Symfony will mark that field as missing and will save it as NULL in the database, or generate a database error if the field cannot be NULL. The more complicated solution would be to also make Symfony skip that field in updates / creation.
The simpler solution is to create a custom widget type that just shows the Select’s option text and adds a hidden field with the Select’s option value. This way the users sees the text and Symfony gets the correct value upon update. This solution assumes that you trust that the user won’t tamper the hidden field with things like Firebug, so keep in mind that it’s not a secure option to make that field read-only and to make sure that the user cannot change it. It’s more of a cosmetic option.
You must create a custom widget class. The class’s code is the following:
<?php
class sfReadonlySelect extends sfWidgetFormDoctrineChoice
{
public function render($name, $value = null, $attributes = array(), $errors = array())
{
$choices = $this->getChoices();
$string = $choices[$value];
$string.= ‘<input type=”hidden” name=”‘.escape_once($name).’” value=”‘.escape_once($value).’”/>’;
return $string;
}
}
all you need to do is to save that in a file called sfReadonlySelect.class.php in the /lib/widget/ directory of your installation.
Then in your /lib/form/doctrine/myForm.php class (where myForm is the name of the object to which your Select field belongs) you initialize the field as following:
$this -> setWidget ( ‘created_group’, new sfReadonlySelect (array(‘model’ => $this->getRelatedModelName(‘GroupCreated’), ‘add_empty’ => true)) );
It’s a simple solution to a fairly simple problem, but I haven’t found a better one on the web so here it is! Please leave your comments/questions below.
