Symfony2 formbuilder - entity readonly field as label - php

Is there any possibility in symfony2 to display a readonly-field of an entity as a label rather than a text field or whatever?
I am currently using the following code, but using a disabled text field does not feel very sophisticated:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('readonlyfield', 'text', array('property_path' => 'readonlyfield.displayString','disabled' => true));
$builder->add('editablefield', 'textarea');
}
I am using symfony 2.4.4..
EDIT:
I am using this form type from within another form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('mySubEntities', 'collection', array('type' => new MySubEntryType()));
$builder->add('save_to_db', 'submit', array('label' => 'Submit'));
}
twig file:
{{ form_start(form) }}
{% for row in form.mySubEntities %}
<li>
<ul>
<table>
<tr><td>{{ form_label(row.readonlyfield) }} </td><td>{{ form_widget(row.readonlyfield) }}</td></tr>
<tr><td>{{ form_label(row.editablefield) }}</td><td> {{ form_widget(row.editablefield) }}</td></tr>
</table>
</ul>
</li>
{% endfor %}
{{ form_end(form) }}

You can access value in form using {{ form.vars.value.yourfield }}.
You have a nested/collection so use {{ row.vars.value.yourfield }}

Why don't you just render the entity property in your template instead of making it part of a form? You could make your own FieldType but that's not what I recommand. If you want the value to be displayed as a form like file I would use the readonly property.

Related

Form two Textfields in one row

I want to set two Text fields in one row in the from class. That they loke like this:
Name/surname ______ _______
I can't find something in the Internet.
I use this code in the Form class:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextareaType::class)
->add('surname', TextareaType::class);
}
But this will be shown like this:
Name ____
surname ____
and this is wrong in my situation. Is it possible to do that in the form class?
Thanks for your help.
You can show your form_rows in a more custom way by doing this:
Instead of showing your form in the more universal way:
{{ form_start(myForm) }}
{{ form_widget(myForm) }}
{{ form_end(myForm) }}
You can, in fact, do the next:
{{ form_start(myForm) }}
{{ form_row(myForm.field1) }}
{{ form_row(myForm.field2) }}
{{ form_widget(myForm) }}
{{ form_end(myForm) }}
This will allow you to show those rows how you want with extra arguments, and it will continue to show the rest, so you do not need to use form_row for every row once you have started using it.
Now, you can achieve what you are asking using display: flex, and setting it's direction as row.
Using bootstrap:
{{ form_start(myForm) }}
<div class = "d-flex flex-row">
{{ form_row(myForm.field1) }}
{{ form_row(myForm.field2) }}
</div>
{{ form_widget(myForm) }}
{{ form_end(myForm) }}
Without bootstrap:
{{ form_start(myForm) }}
<div style = "display: flex; flex-direction: row;">
{{ form_row(myForm.field1) }}
{{ form_row(myForm.field2) }}
</div>
{{ form_widget(myForm) }}
{{ form_end(myForm) }}
You can put the label you want only to field1, and so, field 2, without a label, will appear as you are asking, next to the input field of field 1.

Display custom message for checkbox (terms of service/privacy)

I am still new to Symfony and Php, so I am using the CheckboxType code from Symfony docs.
Currently no message is appearing if a user attempts to register and the checkbox is unchecked, but it will still prevent the user from making a account.
(1) I would like a error message to appear next to the checkbox in red stating the box must be checked in order to proceed. I would also like to customize this message.
Thank you!
Register.html
{% extends 'base.html.twig' %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>Register!</h1>
{{ form_start(form) }}
{{ form_row(form.username) }}
{{ form_row(form.email) }}
{{ form_row(form.plainPassword.first, {
'label': 'Password'
}) }}
{{ form_row(form.plainPassword.second, {
'label': 'Repeat Password'
}) }}
Terms of service
{{ form_widget(form.termsAccepted) }}
cancel
<button type="submit" class="btn btn-primary" formnovalidate>
Register
</button>
<br></br>
<p>Privacy Policy
{{ form_end(form) }}
</div>
</div>
</div>
{% endblock %}
RegistrationForm.php
class UserRegistrationForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class)
->add('username', TextType::class)
->add('plainPassword', RepeatedType::class, ['type' => PasswordType::class])
->add('termsAccepted', CheckboxType::class, array(
'mapped' => false,
'constraints' => new IsTrue(),));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'validation_groups' => ['Default', 'Registration']
]);
}
}
The problem is that you are using:
{{ form_widget(form.termsAccepted) }}
for rendering the checkbox. This will only render the widget, whereas:
{{ form_row(form.termsAccepted) }}
as is used by all the user fields would contain the label, the widget and the error message. If you want to keep the widget, e.g. because using form_row messes up the template somehow you could render the errors individually using:
{{ form_errors(form.termsAccepted) }}
You might also want to check out the documentation on Form Customization.

Symfony/TWIG: Unable to set custom theme for form with dynamic ID (createNamedBuilder)

I wanted to replace Symfony's default radio button widget with Bootstrap's Radio Button Group. I was trying to achieve that by setting a custom theme for an individual field in Symfony's form created with createNamedBuilder function. I failed, because custom field themes require the ID of the field which is dynamic in my case. I know that having variables in theme names is impossible in TWIG, but maybe there is an alternative approach that I could use to resolve my issue.
CODE
I have a Controller which creates multiple instances of one form type in a loop. The name of the form is dynamically created by concatenating requestform_ and the ID of the form:
public function listAction(Request $request)
{
$entityManager = $this->getDoctrine()->getManager();
$requestForms = $entityManager->getRepository('AppBundle:RequestForm')->findBy(array(), array('id' => 'ASC'));
$forms = array();
foreach ($requestForms as $requestForm) {
$formBuilder = $this->get('form.factory')->createNamedBuilder('requestform_'.$requestForm->getId(), RequestFormType::class, $requestForm);
$form = $formBuilder->getForm()->handleRequest($request);
$forms[] = $form->createView();
}
return $this->render('form/index.html.twig', array('forms' => $forms));
}
buildForm function of the RequestFormType prepares radio button widget and looks like this:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('status', EntityType::class, array(
'class' => 'AppBundle:Status',
'choice_label' => 'name',
'expanded' => true,
'multiple' => false
));
}
The Controller renders the following template:
{% block content %}
{% for form in forms %}
{{ form_start(form) }}
{{ form_widget(form.status) }}
{{ form_end(form) }}
{% endfor %}
{% endblock %}
Which is themed to show Bootstrap's button group selector instead of radio buttons:
{% block _requestform_1_status_widget %}
<div id={{ form.vars.id }} class="btn-group" data-toggle="buttons">
{% for status in form.children %}
<label for={{ status.vars.id }} class="btn btn-primary required custom-button-radio">
<input type="radio" id={{ status.vars.id }} name={{ status.vars.full_name }} required="required" value={{ status.vars.value }}>
{{ status.vars.label }}
</label>
{% endfor %}
</div>
{% endblock _requestform_1_status_widget %}
As you may have noticed this will work only for requestForm ID 1 and will not work for other ID values due to TWIG not allowing variables in block names, i.e. {% block _requestform_VARIABLE_status_widget %}.
Any help much appreciated! Thanks
My gut feeling is that you might want to have only one form that includes a CollectionType field with entry_type = RequestFormType::class, and then in the twig, apply a form to the "outer" form as a whole. You should still be able to manage things the way you wanted.

Using TBBC Money/Currency Bundle for Symfony/Bootstrap Forms

I don't think this question has been raised looking at the history and on google...
I'm discovering symfony2 for a personal project and I'm not sure to take the problem the right way when it comes to implementing a form with TBBC Money/Currency bundle (found on packagist).
I have a "Expense" class containing a price field (type "Money") and for which I want to create a form.
In my "ExpenseType" file I have the following:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('title', TextType::class)
->add('actualDate', DateType::class, array('widget' => 'single_text'))
->add('comment', TextareaType::class)
->add('price', MoneyType::class, array())
->add('user', 'entity', array(
'class' => 'VPAccountsBundle:User',
'property' => 'username'))
;
}
On my twig file displaying the form I have:
<div class="row">
<div class="col-lg-3 col-md-3 control-label">
{{ form_label(form.price, "Amount" ) }}
</div>
<div class="col-lg-4 col-md-4">
{{ form_widget(form.price , { 'attr':{ 'class':'form-control', 'placeholder':'Amount' } } ) }}
</div>
{{ form_errors(form.price) }}
</div>
What I get is this.
What I would like to get is a bootstrap input with dropdown button (see mockup). but I really don't know how to proceed.
Has anyone faced this kind of situation? Any help would be appreciated! :)
Thanks a lot.
Theme a widget or form in Symfony is well documented here and IMO you should go through Inside the same Template as the Form. You could extends from form_div_layout.html.twig and then on your custom template overrides how money_widget is render by changing the following block:
{%- block money_widget -%}
{{ money_pattern|replace({ '{{ widget }}': block('form_widget_simple') })|raw }}
{%- endblock money_widget -%}
Hope it helps
Replying to myself...
As correctly indicated in the bundle documentation I had to configure my config.yml to declare the new type to twig:
# config.yml
twig:
form:
resources:
- 'TbbcMoneyBundle:Form:fields.html.twig'
The form elements are rendered much better and should be easily customizable.

Symfony forms - password type

When I am trying to add password filed in my form type class:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', 'text');
$builder->add('email', 'email');
$builder->add('password', 'password');
$builder->add('terms', 'checkbox', array(
'mapped' => false,
'constraints' => new NotBlank()
));
}
and then render this field in twig template {{ form_row(register.password) }} it appears like text filed. But I need it to be the password type <input type='password'...
Also form type is attached to entity with password attribute:
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=32, nullable=false)
*/
private $password;
What is the reason?
The reason is that I use form theme:
{% block text_row %}
<div>
{{ block('form_label') }}
<div>
{{ block('form_widget_simple') }}
</div>
</div>
{% endblock %}
So I add new block:
{% block password_row %}
<div>
{{ block('form_label') }}
<div>
{{ block('password_widget') }}
</div>
</div>
{% endblock %}
And now all is OK
You should use Type to define field Type in $builder->add('child', 'type', ...)
$builder->add('username', TextType::class, array('label' => 'Username'))
->add('password', PasswordType::class, array('label' => 'Password'))
and in Twig
{{ form(form) }}
Not sure if this is the correct way, but did you try specifying a type to the field?
$builder->add('password', 'password', array('type'=>'password');

Categories