Override registration form in FOSUserBundle Symfony - php

I am trying to override the default areas of the fosuserbundle registration form. I added all the required fields I wanted through database and customize with the bootstrap cdn. But when I try to customize the defaults fields of the registration form, I cannot find it in both register_content.html.twig and register.html.twig to edit them.
register_content.html.twig
{% trans_default_domain 'FOSUserBundle' %}
{{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register'), 'attr': {'class': 'fos_user_registration_register'}}) }}
{{ form_widget(form) }}
<div>
<input class="btn btn-success" type="submit" id="_submit" name="_submit" value="{{ 'registration.submit'|trans }}" />
</div>
{{ form_end(form) }}
register.html.twig
{% extends "#FOSUser/layout.html.twig" %}
{% block fos_user_content %}
{% include "#FOSUser/Registration/register_content.html.twig" %}
{% endblock fos_user_content %}
I would like to customize all the following textareas.
Email
Username
Password
Repeat password
Where can I find the above fields?
Thanks in advance.

You can find its at vendor/friendsofsymfony/user-bundle/Form/Type/RegistrationFormType.php if you want to change its directy
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', 'email', array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle'))
->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle'))
->add('plainPassword', 'repeated', array(
'type' => 'password',
'options' => array('translation_domain' => 'FOSUserBundle'),
'first_options' => array('label' => 'form.password'),
'second_options' => array('label' => 'form.password_confirmation'),
'invalid_message' => 'fos_user.password.mismatch',
))
;
}
But it better to override the forme type as below in config.yml (create a new formType)
fos_user:
# ...
registration:
form:
type: AppBundle\Form\RegistrationType

If you want to override existing FormType then follow that doc: http://symfony.com/doc/master/bundles/FOSUserBundle/overriding_forms.html
If you want to choose specific fields in html, you can select fields like that:
{{ form_widget(form.email) }}
{{ form_widget(form.username) }}
or
{{ form_widget(form.email, { 'attr': {'class': 'foo'} }) }}

Related

Unable to render form in Symfony 6.2

I've just updated to Symfony 6.2 (6.2.6 to be exact) and now, not sure why, unable to render form.
This is what debugger says:
Object of class Symfony\Component\Form\FormView could not be converted to string
In Symfony 6.2, according to the documentation, it should be possible to pass only FormInterface into render method in Controller. However, in both cases (meaning even using the createView()) method, it's unable to render the form itself. Any ideas where the problem might be?
Controller method:
#[Route(path: '/register', name: 'security-register')]
public function register(Request $request, MailUtil $util): Response
{
$form = $this->createForm(RegistrationForm::class);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$mail = new Mail();
$mail->setRecpient($form->get('email')->getData());
$mail->setTemplate("TestMail");
$util->sendMail($mail);
}
return $this->render("security/register.html.twig", ['form' => $form->createView()]);
}
Form class:
class RegistrationForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('email', EmailType::class, [
'required' => true
])
->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'register.error.password',
'required' => true,
'first_options' => ['label' => 'Password'],
'second_options' => ['label' => 'Repeat password']
])
->add('submit', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'csrf_protection' => true,
'csrf_field_name' => '_csrf',
'csrf_token_id' => 'user_register'
]);
}
}
Twig:
{% block container %}
<div class="row">
<div class="col s6 offset-s3">
<div class="card-panel blue-grey darken-1" data-darkmode="card-panel blue-grey darken-3">
{% if not app.user %}
<h4 class="white-text center-align ">
Register
</h4>
{{ form_start(form) }}
{{ form.email }}
{{ form_end(form) }}
<div class="white-text center-align">
You are logged in as {{ app.user.userIdentifier }}<br><br><a class="waves-effect waves-light btn" href="{{ path('app_logout') }}">Logout</a>
</div>
{% endif %}
</div>
</div>
</div>
{% endblock %}
Tried to use new, Symfony 6.2 approach as stated in documentation: https://symfony.com/doc/current/forms.html#rendering-forms
And then tried to use the old one with createView() method.
Expected result should be rendered form, however both methods are throwing the same stacktrace.
In twig {{ form.email }} is wrong. This is probably why the error occur.
Switch to {{ form_row(form.email) }} for example
Or you can use widget and label separately.
{{ form_label(form.email) }}
{{ form_widget(form.email) }}

Symfony - How to show a collection of form inputs with a loop in a twig template?

I'm a beginner with PHP and Symfony.
I'm trying to show each values of ring (which is entity) from database and trying to add checkbox at the end of the each ring.
My twig template only shows the checkbox in the first ring.
How do I show all the rings?
This is my controller:
public function testPage(Request $request) {
$ring = $this->ringRepository->customFindAll();
$jewel = $this->ringJewelRepository->customFindAll();
$custom = $this->customRingRepository->customFindAll();
$form = $this->createFormBuilder($ring)
->add('active', CheckboxType::class, [
'label'=>'Selection',
'required'=>false
])
->getForm();
$form->handleRequest($request);
return [
'rings'=>$ring,
'jewels'=>$jewel,
'custom' => $custom,
'form'=>$form->createView()
];
}
This is my Twig template:
{% for ring in rings %}
<div>
<div class="text-center">
<p>Ring Name: {{ ring.ring_name }}</p>
<p>Ring Type: {{ ring.ring_type }}</p>
{{ form_start(form) }}
{{ form_widget(form.active) }}
{{ form_end(form) }}
</div>
<div class="text-center">
Update Ring
</div>
</div>
{% endfor %}
Considering your use-case I think you might be looking for an EntityType, with the 'multiple' option set to true. The syntax would be as below. Make sure to import your Ring class as well.
->add('active', EntityType::class, [
'class' => Ring::class,
'multiple' => true,
'label' => 'Selection',
'required' => false,
'query_builder' => static fn (RingRepository $ringRepository) => $ringRepository->customFindAll(),
]);
You can read more about the EntityType in the symfony docs.

Align multiple form inputs horizontally

I have a form with a collectionType field, this field has 3 inputs and I want to align all 3 of them horizontally. Is it possible to do that in Symfony?
Also: Is it possible to choose the label for each element inside the collectionType?
Here's my form:
class WorkerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('Firstname')
->add('Lastname')
->add('tasks', CollectionType::class, [
'label' => 'Tasks',
'entry_type' => TasksType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'required' => false,
'by_reference' => false,
'delete_empty' => true,
'attr' => [
'class' => 'collection',
],
])
;
$builder->add('save', SubmitType::class, [
'label' => 'Valider',
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => worker::class,
]);
}
}
Here's my tasks form:
class TasksType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('label')
->add('start')
->add('end')
;
}
and here's my _form.html.twig:
{% block extra_js %}
<script src="{{ asset('jquery.collection.js') }}"></script>
{% endblock %}
{% block body %}
<div class="row">
{%
form_theme form
'jquery.collection.html.twig'
'TaksTemplate.html.twig'
%}
{{ form_start(form) }}
<div class="my-custom-class-for-errors">
{{ form_errors(form) }}
</div>
<div class="col">
{{ form_row(form.Firstname, {'label': 'firstname'}) }}
</div>
<div class="col" >
{{ form_row(form.Lastname, {'label': 'Lastname'}) }}
</div>
<div class="col">
{{ form_row(form.tasks, {'label': 'tasks'}) }}
</div>
</div>
{{ form_end(form) }} </div>
{% endblock %}
{% block script %}
<script type="text/javascript">
$('.collection').collection({
'drag_drop_options': {
'placeholder': null
}
});
</script>
{% endblock %}
Also: is is possible to choose the label for each element inside the collectionType ?
No. you can't have multiple label in symfony collectionType.
I want to align all 3 of them horizontally.
Ask this again with HTML CSS tags

Customize forms Symfony

I'm trying to customize my forms. I have been using
http://symfony.com/doc/current/form/form_customization.html
as reference for theme/form customization, but I'm not quite grasping the concept.
What I currently have
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('IHaveReadAndAcceptTheTermsOfService', CheckboxType::class, array(
'mapped' => false,
'constraints' => new IsTrue(),));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'validation_groups' => ['Default', 'Registration']
]);
}
Register.html.twig
{% extends 'base.html.twig' %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>Register!</h1>
{{ form_start(form, {'attr':{'class':'boxsize'}}) }}
{{ 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_row(form.IHaveReadAndAcceptTheTermsOfService) }}
cancel
<button type="submit" class="btn btn-primary" formnovalidate>
Register
</button>
<br></br>
<p>Privacy Policy
{{ form_end(form) }}
</div>
</div>
</div>
{% endblock %}
In CSS
.boxsize {
width: 200px;
}
What I am trying to do.
Make this boxsize the default size when I create a form. As it stands I would have to use class:boxsize for each form I create.

Symfony2 FosUserBundle ordering registration form fields

I just learn how to use fosuserbundle, I just added "name" column to entity and database field, and now, the registration form is shows like this :
Email :[_______________________________]
Username :[_______________________________]
Password :[_______________________________]
Verification:[_______________________________]
Name :[_______________________________]<-name
my question is how to make it orders like this since I added 'name, field later.
Email :[_______________________________]
Name :[_______________________________]<-order name here
Username :[_______________________________]
Password :[_______________________________]
Verification:[_______________________________]
should I make it ordered from database table or just from Form factory ?
thanks,
Copy vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/views/Registration/register_content.html.twig into app/Resources/FOSUserBundle/views/Registration/register_content.html.twig and make changes like:
vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/views/Registration/register_content.html.twig
<form action="{{ path('fos_user_registration_register') }}" {{ form_enctype(form) }} method="POST" class="fos_user_registration_register">
{{ form_widget(form) }}
<div>
<input type="submit" value="{{ 'registration.submit'|trans({}, 'FOSUserBundle') }}" />
</div>
</form>
app/Resources/FOSUserBundle/views/Registration/register_content.html.twig
<form action="{{ path('fos_user_registration_register') }}" {{ form_enctype(form) }} method="POST" class="fos_user_registration_register">
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_widget(form.email) }}
{{ form_widget(form.name) }}
{{ form_widget(form.username) }}
{{ form_widget(form.plainPassword.first) }}
{{ form_widget(form.plainPassword.second) }}
{{ form_end(form) }}
<input type="submit" value="{{ 'registration.submit'|trans({}, 'FOSUserBundle') }}" />
</form>
One way to do it as #repincln's answer. But other way around is to update the form builder, as you have already extended to add your field. I think it would be much easier/cleaner if you just re-arrange your form while building it. Assuming you have override the form as per FOSUserBundle Documentation
public function buildForm(FormBuilderInterface $builder, array $options){
$builder
->add('email', 'email', array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle'))
->add('name')
->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle'))
->add('plainPassword', 'repeated', array(
'type' => 'password',
'options' => array('translation_domain' => 'FOSUserBundle'),
'first_options' => array('label' => 'form.password'),
'second_options' => array('label' => 'form.password_confirmation'),
'invalid_message' => 'fos_user.password.mismatch',
))
;
}
Use which one you like.
Happy Coding...

Categories