How to render form_rest() as hidden fields in Symfony2/Twig? - symfony

I have a Form class that contains many fields. I would like to render few of them and pass the left ones as hidden. How is this possible ?
I would like to do something like {{ form_rest(form, {'display': 'hidden'}) }} or <div display="hidden">{{ form_rest(form) }}</div>.
Example :
<form action="{{ path('fiche_intervention', {'rreid': rre.rreid}) }}" method="post" {{ form_enctype(form) }}>
{{ form_errors(form) }}
<div class="bloc-input">{{ form_label(form.rredatecommencement, "Date de retrait :") }}
{{ form_widget(form.rredatecommencement) }}
</div>
{# Some other fields... #}
{# ... #}
{# /Some other fields... #}
<div display="hidden">{{ form_rest(form) }}</div>
<input type="submit" />
</form>

You have to do it in you buildForm function, inside the "FormController". Just adding 'hidden' when you add the field is enough.
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('name');
$builder->add('email', 'email');
$builder->add('subject');
$builder->add('anyone', 'hidden');
}

Also you may set all your unneeded fields as rendered in your twig template:
<form action="{{ path('fiche_intervention', {'rreid': rre.rreid}) }}" method="post" {{ form_enctype(form) }}>
{{ form_errors(form) }}
<div class="bloc-input">{{ form_label(form.rredatecommencement, "Date de retrait :") }}
{{ form_widget(form.rredatecommencement) }}
</div>
{% do form.unneededfield1.setRendered %}
{% do form.unneededfield2.setRendered %}
{% do form.unneededfield3.setRendered %}
<div display="hidden">{{ form_rest(form) }}</div>
<input type="submit" />
</form>

form_rest() renders all non-rendered fields from your form. It just renders them as they are, so if you want to render remaining fields as 'hidden', you just have to define them as 'hidden' in your Form !

{{ form_end(form, {'render_rest': false}) }}
It's from the official documentation (v3.0) so it's pretty much best practise i guess.

Related

How i can insert contact form 7 short-code in twig file

I want to show contact form which i am using into
but shorcode not showing form on frontend
How can I show contact form 7 with .twig file?
<div class="our_form">
{{ wp.do_shortcode('[contact-form-7 id="766" title="Contact form 1"]') }}
</div>
<form action="{{ post.link }}" class="contact-form" method="post" {{ form_enctype(form) }}>
<div class="contact-form__row">
{% spaceless %}
{{ form_row(form.name, {}) }}
{{ form_row(form.email, {}) }}
{{ form_row(form.subject, {}) }}
{% endspaceless %}
</div>
{{ form_row(form.message, {}) }}
{{ form_widget(form) }}
<button class="btn btn--primary caps">Send</button>
</form>
how about running this like that:
{% filter shortcodes %}
[contact-form-7 id="766" title="Contact form 1"]
{% endfilter %}
Reference: https://timber.github.io/docs/guides/wp-integration/#shortcodes

How to Customize an individual Field in Symfony2

This is my ArticleType.php
class ArticleType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('category')
->add('tags')
->add('cover')
->add('is_recommend', null, array('attr'=>array('require' => true)))
->add('description')
;
}
how to customize filed "cover" in twig? this is my code in twig
<div class="col-xs-12">
<!-- PAGE CONTENT BEGINS -->
{% form_theme edit_form with 'AppsAdminBundle:Form:fields.html.twig'%}
{{ form_start(edit_form) }}
{{ form_errors(edit_form) }}
{% block _article_cover_widget %}
<div class="text_widget">
{{ block('form_widget_simple') }}
上传文件
</div>
{% endblock %}
{{ form_end(edit_form) }}
</div><!-- /.col -->
I want customize field cover in this twig, but, I don't know, why it's not work, I hope get help, thanks a lot!
Check docs to customize form rendering.
If you want to manage each field rendering separately, you can do it this way too:
<div class="col-xs-12">
<!-- PAGE CONTENT BEGINS -->
{% form_theme edit_form with 'AppsAdminBundle:Form:fields.html.twig'%}
{{ form_start(edit_form) }}
{{ form_errors(edit_form) }}
{{ form_row(edit_form.title) }}
{{ form_row(edit_form.category) }}
{{ form_row(edit_form.tags) }}
<div class="text_widget">
{{ form_row(edit_form.cover) }}
上传文件
</div>
{{ form_row(edit_form.is_recommend) }}
{{ form_row(edit_form.description) }}
{{ form_end(edit_form) }}
</div>
or, simply:
<div class="col-xs-12">
<!-- PAGE CONTENT BEGINS -->
{% form_theme edit_form with 'AppsAdminBundle:Form:fields.html.twig'%}
<div class="text_widget">
{{ form_row(edit_form.cover) }}
上传文件
</div>
{{ form_rest(edit_form) }}
{{ form_end(edit_form) }}
</div>

Symfony: How to avoid custom form-types getting wrapped in a div automatically?

UserType Form:
class UserType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('email', 'email', ['label' => 'EMail']);
// various other fields....
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => array('registration'),
'data_class' => 'Vendor\Model\Entity\User',
));
}
public function getName()
{
return 'form_user';
}
}
TutorType Form:
class TutorType extends Translate
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('user', new UserType(), ['label' => false]);
$builder->add('school', 'entity', [
'class' => 'Model:School',
'property' => 'name',
'label' => 'Label'
]);
// Various other fields
$builder->add('save', 'Submit');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
//'validation_groups' => array('registration'),
'data_class' => 'Vendor\Model\Entity\Tutor',
'cascade_validation' => true,
));
}
public function getName()
{
return 'form_tutor';
}
}
When rendering, the UserType is rendered inside a div, i cant find a way to overcome this.
The Form is rendered as
<form name="form_tutor"
method="post"
action=""
novalidate="novalidate"
class="form-horizontal form-horizontal"
id="form_tutor">
<div id="form_tutor"
novalidate="novalidate"
class="form-horizontal">
<div class="form-group">
<div class="col-lg-10">
<div id="form_tutor_user">
<div class="form-group">
<label class="col-lg-2 control-label aaaa required"
for="form_tutor_user_email">EMail</label>
<div class="col-lg-10">
<input type="email"
id="form_tutor_user_email"
name="form_tutor[user][email]"
required="required"
class="form-control" />
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="col-lg-2 control-label aaaa required"
for="form_tutor_tutorType">Type</label>
<div class="col-lg-10">
<select id="form_tutor_tutorType"
name="form_tutor[tutorType]"
class="form-control">
</select>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button type="submit"
id="form_tutor_save"
name="form_tutor[save]"
class="btn btn-default">Speichern</button>
</div>
</div><input type="hidden"
id="form_tutor__token"
name="form_tutor[_token]"
class="form-control"
value="s6i6zPxJs7KU5CiEe8i6Ahg_ca8rc2t5CnSk5yAsUhk" />
</div>
</form>
The form_tutor_user is wrapped in a own form-group div.
I tried to overwrite the form_tutor_user_widget but this is one level to deep. (And only a quick fix, it should be globally applied to all form type - Classes)
How can i change the theme so all custom types are not wrapped with the default form_row template?
Or how do i know in twig when a "subform" is rendered?
so i can decide to print the <div class="form-group"> when the child-node is not a subform, or skip it, if this is the case.
TIA
By default, in the base form theme:
{% block form_row %}
{% spaceless %}
<div>
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endspaceless %}
{% endblock form_row %}
And, for custom compound forms:
{% block form_widget_compound %}
{% spaceless %}
<div {{ block('widget_container_attributes') }}>
{% if form.parent is empty %}
{{ form_errors(form) }}
{% endif %}
{{ block('form_rows') }}
{{ form_rest(form) }}
</div>
{% endspaceless %}
{% endblock form_widget_compound %}
Unless you changed something here, the DIV you see should come from either one or the other bit of template.
However, in your specfic example, if form_tutor_user_row is defined, the first bit is never used, and if form_tutor_user_widget is defined, the last bit is never used.
Back to your question. Your question is :
"How can i change the theme so all custom types are not wrapped with the default form_row template?"
Here is the problem the way I see it: you want that your TOP forms (the form in which all sub-forms are included) all have a common way of rendering, in sections. Each section will be included in a DIV with class="form-group". You may want to throw in some additional rendering operations but I will limit myself to this to keep things simple.
What you need to do then is to create a specfic form type and make all your TOP forms inherit from this new form type. For instance:
class TopType extends AbstractType
{
public function getName()
{
return 'top_form';
}
}
... and an inherited form:
class MyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
}
public function getName()
{
return 'my_form';
}
public function getParent()
{
return 'top_form';
}
}
As you can see, there is no need to make PHP inheritance for form theming inheritance to work.
Template-theming-wise (can I even say that?), if no specific form theming is set for my_form, Symfony will understand that the default form theme to use here is the form theme of top_form, that you can define as such:
{% block top_form_widget %}
{% spaceless %}
{% for child in form %}
<div class="form-group">
{{ form_widget(child) }}
</div>
{% endfor %}
{{ form_rest(form) }}
{% endspaceless %}
{% endblock top_form_widget %}
I should add that this is a problem I already encountered and solved. Tell me how that works for you.
Edit:
To sum it up, what you have to do is:
Create the TopType form type,
Add the top_form_widget block in your form theme,
For all your root forms (i.e. top-level forms, forms that have no parent), add a getParent() method that will return the name of your TopType form ("top_form")
In theory, if you override the form_widget_compound block in a global form theme this way, it should work as you want:
// app/Resources/views/form.html.twig
{% block form_widget_compound %}
{% if form.parent is empty %}
<div {{ block('widget_container_attributes') }}>
{{ form_errors(form) }}
{% endif %}
{{ block('form_rows') }}
{{ form_rest(form) }}
{% if form.parent is empty %}
</div>
{% endif %}
{% endblock %}
And register your form theme:
// app/config/config.yml
twig:
form:
resources:
- "::form.html.twig"
I usually solve this problem by rendering the nested form's fields manually:
{{ form_row(form.tutor.school) }}
{{ form_row(form.tutor.user.email) }}
Probably that's not the most elegant solution, but it works for me and I haven't looked for an elegant one yet.
Bootstrap 3.3.4 I ended up doing this.
They key part of this:
<div class="{% if form.parent.parent is empty %}form-group{% endif %}{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
Full template.
{% block form_row -%}
<div class="{% if form.parent.parent is empty %}form-group{% endif %}{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
{% if form.parent.parent is null and label is not empty %}
{{- form_label(form) -}}
{% elseif label is empty %}
{{- form_label(form) -}}
{% endif %}
{% if compound is empty %}<div class="{{ block('form_group_class') }}">{% endif %}
{{- form_widget(form) -}}
{{- form_errors(form) -}}
{% if compound is empty %}</div>{% endif %}
</div>
{%- endblock form_row %}
Maybe it is not an elegant solution, however works for me, because I was also trying to find the solution.
As an example:
{% for custom_field in form.custom_fields %}
<div class="edit_custom">
{{ form_row(custom_field.name) }}
{{ form_row(custom_field.value) }}
</div>
{% endfor %}
<script>
$('.edit_custom').find('input').unwrap();
</script>
Try using form_themes.
First, in you parent template define the form theme:
{% form_theme form with ['BundleName:ControlerName:somesubform_form.html.twig'] %}
btw replace BundleName, ControllerName and somesubform with the proper names.
then render it with:
{{ form_row(form.somesubform) }}

How to put the form view inside an inherited twig view?

In the view related to ViciousAmateur:Default:Index Controller/acction I want to add a form to filter paginated results (KnpPaginatorBundle). In my controller I create the form and return the view with the form variable. (Ahh.. If I put the form directly in the view it works as expected).
/**
* #Route("/{page}", defaults={"page" = 1}, name="homepage")
* #Route("/")
* #Template()
*/
public function indexAction(Request $request, $page)
{
$filters = new Filters();
$form = $this->createForm(new FiltersType(), $filters);
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
// Do something with form submited data
}
}
// Do something when index action loads, pagination etc...
return $this->render('ViciousAmateurBundle:Default:index.html.twig', array(
'form' => $form->createView(),
'pagination' => $pagination
)
);
}
But if I try to put the form into a twig include (to make the view inherited/separate) passing the form variable to that view... then it doesn't works. I get this response "Error 101 (net::ERR_CONNECTION_RESET): Se ha restablecido la conexión." (Some words are in Spanish) That's my view:
// file: ViciousAmateurBundle:Default:index.html.twig
{% extends '::base.html.twig' %}
{% block body %}
{{ include('ViciousAmateurBundle:Default:filters.html.twig', {'form': form}) }}
{% block filters %}
{% endblock %}
// Stuff in the body
{% endblock %}
As you can see, the form view is inherited (the extends clause) from index and adds the code to its "filters" twig block...
// file: ViciousAmateurBundle:Default:filters.html.twig
{% extends 'ViciousAmateurBundle:default:index.html.twig' %}
{% block filters %}
<section class="filters">
<form action="{{ path('homepage') }}" method="post" {{ form_enctype(form) }} class="filters">
{{ form_errors(form) }}
{{ form_errors(form.country) }}
{{ form_widget(form.country, { 'attr': { 'placeholder': 'País', 'class': 'input-block-level' } }) }}
// Some more form fields...
{{ form_rest(form) }}
<input type="submit" class="filters_submit btn btn-large btn-block" />
</form>
</section>
{% endblock %}
Then... It's possible to do that thing ? To put the form in an inherited view (the filters view from index) passing to it the form variable given by the controller ??? It should work ? What I'm missing or doing wrong ? Thank you
That's because the syntax in Symfony2.1 is:
{% include "ViciousAmateurBundle:Default:filters.html.twig" with { form: form} %}
Twig include function
What I've done was to remove the extends clause and the twig block to the filters.html.twig view. And just included it in the index.html.twig page within the filters twig block.
index.html.twig
...
{% block filters %}
{{ include('ViciousAmateurBundle:Default:filters.html.twig', {'form': form}) }}
{% endblock %}
...
filters.html.twig
<section id="filters">
<form action="{{ path('homepage') }}" method="post" {{ form_enctype(form) }} class="filters">
{{ form_errors(form) }}
{{ form_errors(form.country) }}
{{ form_widget(form.country, { 'attr': { 'placeholder': 'País', 'class': 'input-block-level' } }) }}
{{ form_errors(form.city) }}
{{ form_widget(form.city, { 'attr': { 'placeholder': 'Ciudad', 'class': 'input-block-level' } }) }}
{{ form_errors(form.gender) }}
{{ form_widget(form.gender, { 'attr': { 'placeholder': 'Género', 'class': 'input-block-level' } }) }}
{{ form_errors(form.sexual_orientation) }}
{{ form_widget(form.sexual_orientation, { 'attr': { 'placeholder': 'Orientación sexual', 'class': 'input-block-level' } }) }}
{{ form_rest(form) }}
<input type="submit" id="toggleFilters1" class="filters_submit btn btn-large btn-block" value="Filtrar" />
</form>

Printing a Form more than once. Symfony2. Twig Templates

I'm using symfony2. I have a form, and I want to print it a lot of times on a twig template.
This is what I have in the Controller:
$em=$this->getDoctrine()->getEntityManager();
$pruebas = $em->getRepository('UnetPBundle:prueba')->findAll();
$form = $this->createForm(new PruebaType(), $pruebas);
return $this->render('UnetPBundle:Nomina:prueba.html.twig', array(
'form' => $form->createView(),
'pruebas' => $pruebas
));
And this is the content of twig template.
<form action="{{ path('UnetPBundle_prueba') }}" method="post" {{ form_enctype(form) }} class="sofla">
{{ form_errors(form) }}
{% for prueba in pruebas %}
{{ form_label(form.nombre, 'Nombre')}}
{{ form_errors(form.nombre)}}
{{ form_widget(form.nombre, {'attr':{'value':prueba.nombre}})}}
{% endfor %}
<input type="submit" value="Submit" />
{{ form_rest(form) }}
</form>
It's printing the field just once.
I think you'll need to create a form from a CollectionType() initialized with $puebras. There will be no need for a loop in your template.
Try to define $puebras as entity field type.

Resources