I'm building form using Sf2's form builder.
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('firstName')
->add('lastName')...
The Entity has a lot of fields and I'd like to put them in jQuery UI Tabs. But in twig template I'd like to use single command
<form action="#" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit" value="Save"/>
</form>
What is best solution?
edit **
To be more conrete: I have 4 fields: firstName, lastName, birthDate, deathDate. I want first 2 fields to be on first tab and the last 2 fields to be on second tab. I want to keep way of rendering the form as mentioned earlier.
I though of a solution to create my own fields not conneceted to underlaying object which will render required html tags (h3, div, etc).
I defined my own field called 'Tab' and add it when new tab should appear.
<?php
//\src\Alden\xyzBundle\Form\Type\TabsType.php
namespace Alden\BonBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormValidatorInterface;
use Symfony\Component\Form\Form;
class TabsType extends AbstractType {
public function buildForm(FormBuilder $builder, array $options)
{
$builder->setAttribute('starting', $options['starting']);
$builder->setAttribute('ending', $options['ending']);
$builder->setAttribute('header', $options['header']);
}
public function buildView(FormView $view, FormInterface $form)
{
$parent = $form->getParent();
if (is_null($parent->getParent()))
{
$tabs = $this->findTabs($parent);
}
else
{
$tabs = array();
}
$view->set('starting', $form->getAttribute('starting'));
$view->set('ending', $form->getAttribute('ending'));
$view->set('header', $form->getAttribute('header'));
$view->set('tabs', $tabs);
}
public function getDefaultOptions(array $options)
{
return array(
'property_path' => false,
'starting' => true,
'ending' => true,
'header' => false,
);
}
public function getName()
{
return 'tabs';
}
public function getParent(array $options)
{
return 'field';
}
private function findTabs(Form $form)
{
$prefix = $form->getName();
$tabs = array();
foreach ($form->getChildren() as $child)
{
foreach ($child->getTypes() as $type)
/* @var $child \Symfony\Component\Form\Form */
{
if (get_class($type) == __NAMESPACE__ . '\TabsType')
{
if ($child->getAttribute('starting'))
{
$tabs[$prefix . '_' . $child->getName()] = $child->getAttribute('label');
}
}
}
}
return $tabs;
}
}
?>
and Twig
{# \src\Alden\xyzBundle\Resources\views\Form\fields.html.twig #}
{% block tabs_row %}
{% if header %}
<ul>
{% for tid, t in tabs %}
<li>
<a href="#{{ tid }}">{{ t }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
{% if ending %}
</div>
{% endif %}
{% if starting %}
<div id="{{ id }}">
{% endif %}
{% endblock %}
and usage in form builder:
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('tabs_head', new TabsType(), array(
'ending' => false,
'starting' => false,
'header' => true
))
->add('tab_1', new TabsType(), array(
'ending' => false,
'label' => 'Podstawowe'
))
->add('firstName', null, array(
'label' => 'Imię'
))
->add('lastName', null, array(
'label' => 'Nazwisko'
))
->add('tab_contact', new TabsType(), array(
'label' => 'Kontakt'
))
->add('address', new AddressType(), array(
'label' => 'Adres zameldowania'
))
->add('tabs_end', new TabsType(), array(
'starting' => false
))
;
}
If you want a form to act like a form wizard you could look at look at the multi-step form bundle
It's pretty nice, you can for example, define step one as filling in software details and then on step2, fill out version details. or whatever you want.
Features
And here is a live demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With