Chase
Chase

Reputation: 9362

Symfony 2.3 how do you group the buttons together in one form group?

Right now i have a FormType that contains the following:

$builder->add('name','text')
    ->add('save','submit',array('label'=>'Save', 'attr'=>array('class'=>'btn btn-primary')))
    ->add('reset','reset',array('label'=>'Reset Form', 'attr'=>array('class'=>'btn btn-warning')));

Right now i have a little bit of form themeing going on that renders the above as:

<form method="post" action="">
    <input type="hidden" name="_csrf_token" value="*********" />
    <div class="form-group">
        <label class="col-4">Name</label>
        <input type="text" name="form[name]" value="" placeholder="Name" />
    </div>
    <div class="form-group">
        <input type="submit" name="form[save]" value="Save" class="btn btn-primary" />
    </div>
    <div class="form-group">
        <input type="reset" name="form[reset]" value="Reset" class="btn btn-warning" />
    </div>
</form>

However what I would like the output to be is:

<form method="post" action="">
    <input type="hidden" name="_csrf_token" value="*********" />
    <div class="form-group">
        <label class="col-4">Name</label>
        <input type="text" name="form[name]" value="" placeholder="Name" />
    </div>
    <div class="form-group">
        <input type="submit" name="form[save]" value="Save" class="btn btn-primary" />
        <input type="reset" name="form[reset]" value="Reset" class="btn btn-warning" />
    </div>
</form>

Notice the buttons are in the same form group wrapper div. I want to know if there is a way to do this using only the FormType or editing the Form Theme. I dont want to change the views from using:

{{ form(form,{'method':'POST','attr':{'class':'form-horizontal'} }) }}

I am aware this can be accomplished if I render the buttons from the form in a custom manner.

Upvotes: 4

Views: 3825

Answers (2)

blamb
blamb

Reputation: 4289

I have a better answer (a more modern solution than the last accepted answer from 2 yrs ago.

Comment out in your controller where your adding those elements

 /* -   
   ->add('cancel', 'button', array())
   ->add('save', 'submit', array())
*/

Now set up your form like this

{{ form_start(form,  {'attr': {'id': 'your-form-id'},}) }}
{{ form_errors(form) }}
{{ form_row(form.name) }}

<div class="form-group">
    <button id="form_reset"name="form[reset]" type="button">Reset</button>
    <button id="form_save" name="form[save]" type="submit">Save Form</button>
</div>

{{ form_end(form) }}

You always have the option of a jQuery solution, but the above is the correct way to customize your form

or a jQuery solution might look something like this;

var formInputSave = $('input:form[save]'),
    formInputReset = $('input:form[reset]'),
    formGroupReset = formInputReset.parent();   

    //save the form group with the form[save] in it.  
    //Append the reset input to it, then remove the initial form group
    $(formInputSave).append(formInputReset);
    $(formGroupReset).empty(); 

Upvotes: -2

Chase
Chase

Reputation: 9362

Update

A bundle that solves this for you that basically does what i suggest but nicer: http://bootstrap.braincrafted.com/components.html#forms


This is far from the most elegant way to do this but i havent found any other means to do this.

I have a working solution that involves modifying the FormType a bit and also overriding some blocks in form_div_layout.html.twig

{# form_div_layout.html.twig #}

{% block button_row %}
{% spaceless %}
    {% if 'data-first-button' in attr %}
    <div class="form-group">
        <div class="col-12">
    {% endif %}
    {{ form_widget(form) }}
    {% if 'data-last-button' in attr %}
        </div>
    </div>
    {% endif %}
{% endspaceless %}
{% endblock button_row %}

{% block button_attributes %}
{% spaceless %}
    id="{{ id }}" name="{{ full_name }}"{% if disabled %} disabled="disabled"{% endif %}
    {% for attrname, attrvalue in attr %}{% if attrvalue != 'data-first-button' and attrvalue != 'data-last-button'%}{{ attrname }}="{{ attrvalue }}"{%endif%}{% endfor %}
{% endspaceless %}
{% endblock button_attributes %}

What this does is it looks for the data-first-button and data-last-button attributes on buttons and adds the containing divs for the respective ones. Then in the button attributes block we look for those attributes and ignore them. Then in the form type we just have to add the attr to the right buttons like this:

$builder->add('name','text')
   ->add('save','submit',array('label'=>'Save', 'attr'=>array('class'=>'btn btn-primary','data-first-button')))
   ->add('reset','reset',array('label'=>'Reset Form', 'attr'=>array('class'=>'btn btn-warning','data-last-button')));

Upvotes: 6

Related Questions