Making a choice (select) widget read-only in Symfony

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.

 

 

Advertisement

One Response

  1. Thank You very much, it works perfect. It is easy solution. To make it secure, it is still possible to add a post validator, where you check if the submitted value is same as it was before. It takes one select from DB, but if you need to make it secure, it is a way to do it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s