Code snippets for symfony 1.x

Navigation

Validator to make a field read-only

Sometimes, when you display the form for a Doctrine object, you want to make some fields read-only..

You can unset the field, and just display the value in the template. But it's better to still display an input form. You can also mess with the template, etc.

Here's a validator to achive the same goal, with no need to touch the template.

class sfValidatorReadOnlyField extends sfValidatorBase
{
  /**
   * Configures the current validator
   * 
   * Available options (required):
   *
   *  * object: The current form object
   *  * field:  The current form field
   *
   * Available error codes:
   *
   * * changed
   *
   * @param array $options   An array of options
   * @param array $messages  An array of error messages
   *
   * @see sfValidatorBase
   **/
  protected function configure($options = array(), $messages = array())
  {
    $this->addRequiredOption('object');
    $this->addRequiredOption('field');
 
    $this->addMessage('changed', 'You don\'t want to mess with me, kid!');
  }
 
  /**
   * @see sfValidatorBase
   */
  protected function doClean($value)
  {
    // Ok, we could just reset the value, but it's so more fun this way
    $object = $this->getOption('object');
    if ($value != $object->get($this->getOption('field')))
    {
      throw new sfValidatorError($this, 'changed');
    }
 
    return (string) $value;
  }
}
 

In your form class, use this code :

public function configure()
{// make some fields readonly
    $this->widgetSchema['first_name']->setAttribute('readonly', 'readonly');
    $this->widgetSchema['last_name']->setAttribute('readonly', 'readonly');
    $this->widgetSchema['email_address']->setAttribute('readonly', 'readonly');
 
    $this->validatorSchema['first_name'] = new sfValidatorReadOnlyField(array('field' => 'first_name', 'object' => $this->getObject()));
    $this->validatorSchema['last_name'] = new sfValidatorReadOnlyField(array('field' => 'last_name', 'object' => $this->getObject()));
    $this->validatorSchema['email_address'] = new sfValidatorReadOnlyField(array('field' => 'email_address', 'object' => $this->getObject()));
 
…
}
 
by Thibault Jouannic on 2010-02-15, tagged form  validator 

Comments on this snippet

gravatar icon
#1 Luís Faceira on 2011-01-17 at 06:23

This is a good snippet, that I've tried to use but found a certain situation that it won't work very well.

For non-required fields, if you set it to empty, the "doClean()" isn't called, and we are able to change the value to empty without a problem.

The only option I can think of is to override the main "clean()" instead of just the "doClean()" but that is not a 'clean' solution :)

If I think of a better way, I'll post it here.