Wrap Symfony form fields in a div in Twig
Given the simple form build:
$form = add('a')
->add('b')
->add('c')
->add('d')
->add('e')
->add('f');
I'd like to wrap a div tag around ABC and DEF, like so:
<div class="section1">
<input type="text" name="a" />
<input type="text" name="b" />
<input type="text" name="c" />
</div>
<div class="section2">
<input type="text" name="d" />
<input type="text" name="e" />
<input type="text" name="f" />
</div>
Problem is, I am just able to use the Symfony Form Component for this project. Is there a way with twig to render the form fields in groups like above? I will need to specify logic that says something simliar to "start section 1 with 'a' and section 2 with 'd'", so this way if any fields change inbetween (say we remove the field with the name 'b') the form will still work.
My twig file looks like this, which is obviously not correct:
<form action="#" method="POST" {{ form_enctype(form) }}>
{% for child in form.children %}
<div class="form_row">
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endfor %}
</form>
The best way to do it I think is building the form outside the controller (as a class, extending AbstracType)
So, you will need these files:
So, the idea is building one single form (MyFormType) made by many individual section forms (Section1Type and Section2Type). Then calling this main form in your controller and rendering it in your template (with a "for" loop for each section).
So here you have the code:
Your controller:
<?php
# /src/Acme/DefaultBundle/Controller/DefaultController.php
namespace AcmeDefaultBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use AcmeDefaultBundleFormMyFormType;
class DefaultController extends Controller
{
public function indexAction()
{
$form = $this->createForm(new MyFormType());
return $this->render('AcmeDefaultBundle:Default:index.html.twig', array(
'form' => $form->createView()
));
}
}
Your template:
{# /src/Acme/DefaultBundle/Resources/views/Default/index.html.twig #}
{{ form_start(form) }}
<div class="section1">
{% for input in form.section1 %}
{{ form_label(input) }}
{{ form_widget(input) }}
<br>
{% endfor %}
</div>
<div class="section2">
{% for input in form.section2 %}
{{ form_label(input) }}
{{ form_widget(input) }}
<br>
{% endfor %}
</div>
{{ form_end(form) }}
The main form:
<?php
# /src/Acme/DefaultBundle/Form/MyFormType.php
namespace AcmeDefaultBundleForm;
use AcmeDefaultBundleFormSection1Type;
use AcmeDefaultBundleFormSection2Type;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
class MyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// This calls your section forms as many as you need
$builder->add('section1', new Section1Type());
$builder->add('section2', new Section2Type());
$builder->add('Send', 'submit');
}
public function getName()
{
return 'myform';
}
}
The Section1 form:
<?php
# /src/Acme/DefaultBundle/Form/Section1Type.php
namespace AcmeDefaultBundleForm;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
class Section1Type extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('a', 'text');
$builder->add('b', 'text');
$builder->add('c', 'text');
}
public function getName()
{
return 'section1';
}
}
And Section2 form:
<?php
# /src/Acme/DefaultBundle/Form/Section2Type.php
namespace AcmeDefaultBundleForm;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
class Section2Type extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('d', 'text');
$builder->add('e', 'text');
$builder->add('f', 'text');
}
public function getName()
{
return 'section2';
}
}
And that's it, you can edit each individual section (adding and removing inputs) and you will get all of them in your template without modifying it.
链接地址: http://www.djcxy.com/p/81396.html