Tweaking your forms

Nette forms documentation lacks information about enhancing your forms while still using the default renderer. I offer here a list of solutions for the most common needs, using getControlPrototype(), getLabelPrototype(), getSeparatorPrototype() and setOption().

The code goes into your form factory method in the presenter. Using the default renderer means you can’t tweak the look in your template, you have to do it when you define the form.

Formatting

Very often it’s needed to add a css style or class to a field or its label. You can modify other elements too though. For instance, you can automatically place user’s text cursor into a particular field after the page loads.

  1. $form->addText(‘subject’, ‘Subject:’)
  2.   ->getControlPrototype()->class(‘wideField’)->autofocus(true);
  3.  
  4. $form->addTextArea(‘terms’, ‘Terms and Conditions:’)
  5.   ->getLabelPrototype()->style(‘white-space: nowrap;’);
  6.  

Radio buttons on a single line

Default renderer will place each radio button/label pair on a new line. What happens in terms of Nette is that it uses a line break as a separator. Here’s how to remove (or replace) the separator.

  1. $options = array(‘one’ => "One", ‘two’ => "Two");
  2. $form->addRadioList(‘type’, ‘Type:’, $options)
  3.   ->getSeparatorPrototype()->setName(NULL);

Read-only

Make a form field (or a set of form fields) read-only – aka disabled. This field’s value will then not appear among $form->getValues().

  1.  
  2. $form[‘type’]->setDisabled(true);
  3.  

Description

Piece of text or html element printed after the form field.

  1. $form->addText(‘password’, ‘Password:’)
  2.   ->setOption(‘description’, "Leave empty if you don’t want to change.");

Will be rendered as

  1. <td><input type="text" … /> <small>Leave empty…</small></td>

What if you want the description to start on a new line? Or be something else than a plain text?

  1. $form->addText(‘password’, ‘Password:’)
  2.   ->setOption(‘description’,
  3.     NHtml::el(‘div’)->setHtml(
  4.       NHtml::el(‘small’)->setText("Leave empty if you don’t want to change.")
  5.     )
  6.   );

Printing a description with form macros

When rendering your forms semi-manually with macros {form}, {label} and {input} you may also need to print the description. Nette doesn’t ship with any handy macro for that purpose but you can create your own. Best place would be your BasePresenter:

  1.  public function templatePrepareFilters($template) {
  2.     $latte = new NLatteFilter;
  3.     $set = new NMacroSet($latte->parser);
  4.  
  5.     $set->addMacro(
  6.       ‘description’,
  7.       ‘$__desc = $form[%node.word]->getOption("description"); echo %escape($__desc);’
  8.     );
  9.  
  10.     $template->registerFilter($latte);
  11.   }

Additional information on defining your own Latte macros. Don’t expect much though, it’s pretty brief.

Other things you can set with setOption()

(taken from API for Nette\Forms\ControlGroup)

label
String or Html object – Setting this option only makes sense for a group where it replaces a label defined previously with addGroup()
container
Html object – Again, only makes for a group. Good for wrapping it with a DIV for example.
description
String or Html object – Displayed after the form field, inside of a fieldset when talking about a group. Doesn’t work for buttons (addSubmit/addButton)
visual
Wraps a group with a fieldset when true.
embedNext
Understands the next group as a child when true, or as a sibling if false (default).

(Nette\Forms\Rendering\DefaultFormRenderer)

class
css class
id
id attribute

Tags:

One Response to “Tweaking your forms”

  1. […] cookbook and the built-in n:href macro. You can also take a peek an another post of mine on how to tweak your forms using macros. As always, hopefully it’ll save you some […]

Leave a Reply