Symfony2 form builder add field between fields - forms

I have a form builder object that I am adding fields to. How do I added a field between 2 existing fields:
$formBuilder->add('name',...)
->add('phone',...);
//Somehow here add an 'email' field between the 'name' and 'phone' field
$form = $formBuilder->getForm();

You can change the order by rendering the form in parts with twig.
{{ form_row(form.name) }}
{{ form_row(form.email) }}
{{ form_row(form.phone) }}

Related

Laravel Blade Form::checkbox rendered as select

I have a form that should display as checkboxes but is appearing as a select dropdown.
In the controller I defined the variables:
$user = Auth()->user();
$users = User::all();
$assignedUsers = User::where('assigned', true)->get();
Here is where the form is defined in the view:
{{ Form::open( route('users.access', [$user->id]), ['type' => 'PUT']) }}
{{ Form::checkbox(
'Users',
[
'label' => __('Select Users'),
'options' => $users,
'value' => $assignedUsers
]
) }}
{{ Form::button('submit', ['label' => __('Save changes')]) }}
{{ Form::close() }}
The form is rendering but not as checkboxes but a select dropdown. What am I missing here?
Form::checkbox() method accepts 3 arguments, name, value, and default. You seem passing wrong arguments for the checkbox list so it renders as dropdown, to make a checkbox list, you and use a loop, should be something like so:
#foreach ($users as $user)
<label>
{{ Form::checkbox('users[]', $user->id, isset($assignedUsers[$user->id])) }}
{{ $user->name }}
</label>
#endforeach
Note that I have converted your $assignedUsers variable to key by id for more convernience. You can use your own check method.
$assignedUsers = User::where('assigned', true)->get()->keyBy('id');

Render field form type twig symfony

I would like to duplicate the same field several times with different values ​​in the drop-down list in twig. I add a simple form with a TextType, but in twig in a for loop, the rendering of the field is done only once. How can I make this system under symfony ? ( In a for loop )
When you try to create a form in your controller and then you render it to you'r view , it gonna be one and only one form , you can't duplicated with a loop because at the end, it gonna give you 2 forms with the same form_id , so if you need 2 forms you need to instantiate them with your builder the same thing with you'r fileds.
Take a look:
$task1 = new Task();
$task2 = new Task();
$form1 = $this->createFormBuilder($task1)
->add('task', TextType::class)->add('task2', TextType::class);
$form2 = $this->createFormBuilder($task2)
->add('task', TextType::class);
And about the drop down , you need to create a form with ChoiceType Field :
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
$builder->add('Tasks', ChoiceType::class, array(
'choices' => array('task1','task2','task3));
CollectionType field type is used to render a "collection" of some field or form. In the easiest sense, it could be an array of TextType fields that populate an array values.
Example:
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
// ...
$builder->add('emails', CollectionType::class, [
// each entry in the array will be an "email" field
'entry_type' => EmailType::class,
// these options are passed to each "email" type
'entry_options' => [
'attr' => ['class' => 'email-box'],
],
]);
The simplest way to render this is all at once:
{{ form_row(form.emails) }}
A much more flexible method would look like this:
{{ form_label(form.emails) }}
{{ form_errors(form.emails) }}
<ul>
{% for emailField in form.emails %}
<li>
{{ form_errors(emailField) }}
{{ form_widget(emailField) }}
</li>
{% endfor %}
</ul>
Please refer this documents for further details : https://symfony.com/doc/current/reference/forms/types/collection.html

bootstrap style conflicts with forms bound with models laravel 4

I am developing an application with laravel 4, I have forms that are filled with data from a model, in other words a model is bound to the form
I need to add some bootstrap style to the form and I do it this way
this is my view file:
{{
Form::model($user, array( $user->id))
}}
{{ Form::label('last_name', 'Last Name') }}
{{ Form::text('last_name', '', array('class' => 'form-control')) }}
{{ Form::close() }}
and this is my controller code:
public function edit(){
$user = User::find(Auth::user()->id);
return View::make('edit')->with('user',$user);
}
The Issue:
As soon as I add this class to the form's element the content of the form will disappear and no data is bound to it anymore, how should I fix it?
I found the answer the second argument of this
{{ Form::text('last_name', '', array('class' => 'form-control')) }}
is the input value of text field so it should be like this:
{{ Form::text('last_name', $user->last_name, array('class' => 'form-control')) }}

Symfony2 Accessing each entity field elements value in Twig

I have one form that contains entity type field parameters:
->add('parameters', 'entity', array(
'class' => 'SPlaceBundle:Parameter',
'query_builder' => function(ParameterRepository $er)
{
return $er
->createQueryBuilder('s')
->where('s.type = :type1 or s.type = :type2')
->setParameter('type1', 1)
->setParameter('type2', 2)
->orderBy('s.name', 'ASC');
},
'property' => 'name',
'multiple' => true,
'expanded' => true,
))
As you can see I only display parameters with type=1 or type=2.
While rendering template I would like to place hr (or something else) between checkboxes representing different parameter types.
I was trying to use {{ field.get('value').type }} trick to get parameter type:
{% for p in form.parameters %}
{{ form_widget(p) }}
{{ form_label(p) }}
{{ p.get('value').type }}
<br>
{% endfor %}
The problem is that above {{ p.get('value') }} returns parameter id (int) instead of parameter object.
Is there a way to return object?
It's not really elegant, but you could concatenate the type and name in your select, and use that as label. Then, when displaying the labels, split on the delimiter and you have both type and name.

How to deal with Form Collection on Symfony2 Beta?

I have an entity User and an entity Address. There is a relation One-to-Many between User and Address :
class User
{
/**
* #orm:OneToMany(targetEntity="Address")
*/
protected $adresses;
[...]
}
I have a class AddressType, and class UserType :
class UserType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('addresses', 'collection', array('type' => new AddressType()));
}
[...]
}
In my controller, I build form with :
$form = $this->get('form.factory')->create(new UserType());
... and create view with :
return array('form' => $form->createView());
I display form field in my twig template with :
{{ form_errors(form.name) }}
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
[...]
Okay. Now, how to display fields for one or more addresses ? (it's no {{ for_widget(form.adresses.zipcode) }} nor {{ for_widget(form.adresses[0].zipcode) }} ...)
Any ideas ?
This is how I did it in my form template:
{{ form_errors(form.addresses) }}
{% for address in form.addresses %}
<div id="{{ 'address%sDivId'|format(loop.index) }}" class="userAddressItem">
<h5> Address #{{ loop.index }}</h5>
{{ form_errors(address) }}
{{ form_widget(address) }}
</div>
{% endfor %}
And I have a small action bar, driven by jQuery, that lets the user add and remove addresses. It is a simple script appending a new div to the container with the right HTML code. For the HTML, I just used the same output has Symfony but with updated index. For example, this would be the output for the street input text of the AddressType form:
<input id="user_addresses_0_street" name="user[addresses][0][street]" ...>
Then, the next index Symfony will accept is 1 so the new input field you add would look like this:
<input id="user_addresses_1_street" name="user[addresses][1][street]" ...>
Note: The three dots are a remplacement for required="required" maxlength="255" but could change depending on your needs.
You will need more HTML code than that to add a whole new AddressType to the DOM of the browser but this give you the general idea.
Regards,
Matt
I should top that up with the fact that if you want to dynamically add fields, you need to set the key 'allow_add' to true in your collection field in UserType :
...
$builder->add('addresses', 'collection', array(
'type' => new AddressType(),
'allow_add' => true
));
Just spent hours trying to figure out what was missing, and at the time i'm writing the doc does not mention this yet. Hope it'll help fellow developers.