views:

351

answers:

2

Hi everyone, I am trying to find a better way to assign classes to form elements in symfony. Currently, I can't seem to get away from assigning each one manually. ie:

$this->widgetSchema['title']->setAttribute("class","fieldInput");
$this->widgetSchema['tag_line']->setAttribute("class","fieldInput");
$this->widgetSchema['description']->setAttribute("class","fieldInput");
// etc

Things I tried without success

1) looping through $this->widgetSchema, treating it as an array and setting attributes to each key

2) $this->widgetSchema->setAttribute() but this only applied the class to the label that was generated, not the form element

There must be a way to hit all the fields without specifically directing them?

Can anyone point me in the right direction?

+2  A: 

There is a way:

Create a sfWidgetFormSchemaFormatter in lib/widget, which contains for instance, this (code from symfonians):

class sfWidgetFormSchemaFormatterDiv extends sfWidgetFormSchemaFormatter
{
  protected
    $rowFormat       = "<div class=\"form-row%is_error%\">\n  %label%\n  %error%\n   %hel<div class='myfieldclass'%field%</div>\n p%\n%hidden_fields%</div>\n",
    $errorRowFormat  = "%errors%\n",
    $helpFormat      = '<div class="form-help">%help%</div>',
    $decoratorFormat = "\n  %content%";

  public function formatRow($label, $field, $errors = array(), $help = '', $hiddenFields = null)
  {
    return strtr(parent::formatRow($label, $field, $errors, $help, $hiddenFields), array(
      '%is_error%'    => (count($errors) > 0) ? ' field_error' : '',
      //'%is_required%' => $field,
    ));
  }
}

Then, in your form, do:

$oDecorator = new sfWidgetFormSchemaFormatterDiv($this->getWidgetSchema());
$this->getWidgetSchema()->addFormFormatter('div', $oDecorator);
$this->getWidgetSchema()->setFormFormatterName('div');

Then you can style elements with the selector .myfieldclass input or whatever you want, this is a great way to change the structure/look of your forms.

nacmartin
This is nice, but overkill. CSS suffices, generates less code, and is more maintanable.
Tom
A: 

Apply the class to a parent element, not the individual elements:

TEMPLATE:

<form class="my-form" action="" method="">
 // put widgets here
</form>

CSS:

.my-form select {}
.my-form input[type=text] {}
.my-form textarea {}
.my-form input[type=submit] {}
etc...
Tom