How can I create an "update" form in Symfony 4? - forms

With this form I want to update my database entry:
myController.php
public function index($id, $slug, Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
$item = new User();
$item= $this->getDoctrine()->getRepository(User::class)->find($id);
$form = $this->createFormBuilder($item)
->add('username', TextType::class, array('attr' => array('class' => 'form-control')))
->add('email', EmailType::class, array('attr' => array('class' => 'form-control')))
->add('is_active', HiddenType::class)
->add('plainPassword', RepeatedType::class, array('type' => PasswordType::class,'invalid_message' => 'The password fields must match.','options' => array('attr' => array('class' => 'password-field')),'required' => true,'first_options' => array('label' => 'Passwort', 'attr' => array('class' => 'form-control')),'second_options' => array('label' => 'Passwort wiederholen', 'attr' => array('class' => 'form-control')),))
->add('cancel', ButtonType::class, array('label' => 'Cancel','attr' => array('class' => 'cancel form-btn btn btn-default pull-right close_sidebar close_h')))
->add('update', SubmitType::class, array('label' => 'Update','attr' => array('class' => 'form-btn btn btn-info pull-right','style' => 'margin-right:5px')))
->getForm();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->flush();
return $this->redirectToRoute('pages', array(
'slug' => $slug,
));
}
return $this->render('form.html.twig', ['form' => $form->createView()]);
}
form.html.twig:
{{ form_start(form) }}
<div>
{{ form_label(form.username) }}
{{ form_widget(form.username) }}
{{ form_errors(form.username) }}
{{ form_help(form.username) }}
</div>
<div>
{{ form_label(form.email) }}
{{ form_widget(form.email) }}
{{ form_errors(form.email) }}
{{ form_help(form.email) }}
</div>
<div>
{{ form_widget(form.is_active) }}
{{ form_errors(form.is_active) }}
{{ form_help(form.is_active) }}
</div>
<div>
{{ form_label(form.plainPassword.first) }}
{{ form_widget(form.plainPassword.first) }}
<div class="text-red">{{ form_errors(form.plainPassword.first) }}</div>
{{ form_help(form.plainPassword.first) }}
</div>
<div>
{{ form_label(form.plainPassword.second) }}
{{ form_widget(form.plainPassword.second) }}
<div class="text-red">{{ form_errors(form.plainPassword.second) }}</div>
{{ form_help(form.plainPassword.second) }}
</div>
{{ form_end(form) }}
But when I edit for example the username in my form and I click on "Update" then I get the error message
An exception occurred while executing 'INSERT INTO members (username,
password, email, is_active) VALUES (?, ?, ?, ?)' with params ["cat2",
"123", "cat#cat.de", "1"]:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
'cat#cat.de' for key 'UNIQ_12A0D2FFE7927C74'
I actually expect the SQL make an UPDATE instead of INSERT...

You need to load the User from the UserRepository::find($id)
use App\Repository\UserRepository;
// ...
class MyController
{
public function index($id, $slug,
Request $request,
UserPasswordEncoderInterface $passwordEncoder,
UserRepository $userRepository)
{
$item = $userRepository->find($id);
if(NULL === $item) {
throw $this->createNotFoundException('could not find this user.');
}
$form = $this->createFormBuilder($item)
// ...
}
// ...
}

Related

I can not display the password field input (with 'repeat' option) with twig (Symfony2)

I have the following form and Twig template:
FormType
class UserType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name','text',array('label' => 'Name', 'max_length' => 30))
->add('surname','text',array('label' => 'Sjurname', 'max_length' => 30))
....
->add('password', 'repeated', array('error_bubbling' => true,'required' => false, 'first_options' => array('label' => 'New Password'),'second_options' => array('label' => 'Repeat Password'),'type' => 'password' ,'invalid_message'=> 'Passwords must be the same.'));
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Bundle\Entity\User',
));
}
/**
* #return string
*/
public function getName()
{
return 'user';
}
}
Twig
....
{{form_start(form, {'method':'Put','attr':{'data-toggle':"validator", 'role':"form" ,'novalidate':'novalidate', 'autocomplete':'off'}})}}
{{ form_errors(form) }}
<div class="form-group has-feedback">
{{ form_label(form.password, 'New Password:',{'label_attr':{'class': 'col-md-5'}}) }}
<div class="col-md-7">
{{ form_widget(form.password,{'attr':{'class': 'form-control', 'type': 'password','data-error': 'You must enter a minimum of 6 characters', 'placeholder': 'Min 6 characters', 'data-minlength':"6", 'required':'true' }}) }}
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
<div class="help-block with-errors"></div>
</div>
</div>
{{ form_row(form.submit,{'attr':{'class': 'btn btn-primary pull-right' }}) }}
<div class="hidden">
{{ form_rest(form) }}
</div>
{{ form_end(form) }}
...
The problem I have is that the input is not created. The label is displayed. I have tried using form.password.first and form.password.second but neither is the input (only the labels). With the other fields I do not have that problem, the only thing in this case all the others are hidden in a div. What could be the problem?
I appreciate your help.
Take a look at this. it is for symfony 2.8/3+ but you can adapt it to your needs.
FormType
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'first_options' => [
'label' => 'registration.password',
],
'second_options' => [
'label' => 'registration.retype.password',
],
]) ...
twig
<div>
{{ form_label(form.plainPassword.first) }}
{{ form_widget(form.plainPassword.first) }}
{{ form_errors(form.plainPassword.first) }}
</div>
<div>
{{ form_label(form.plainPassword.second) }}
{{ form_widget(form.plainPassword.second) }}
{{ form_errors(form.plainPassword.second) }}
</div>
Do you have a version of xDebug installed? You could place a breakpoint on the return section of the Controller and have a look inside the children element of the form. This could tell you what the names of the elements are.
**PS, I would have commented this but I don't have enough rep.

Display errors message form

i am trying to show errors messages at the top on page in my twig view but {{ Form_errors(form)}} don't display password errors! but shows other errors..
Form builder
->add('password', RepeatedType::class, array(
'type' => PasswordType::class,
'options' => array('attr' => array('class' => 'password-field')),
'required' => true,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password').
view :
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
{{ form_widget(form) }}`enter code here`
{{dump(form_errors(form))}}
<input type="submit" value="Create" />
{{ form_end(form) }}
try
{{dump(form_errors(form.password))}}
to display errors specific to the password field

Double textarea? Symfony 2 with FOSU

i have this weird problem, and i really dont know why this happens.
The text areas are doubled and their position is bad.
Look at the image.
So, the builder looks like:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imie', 'text', array('label' => false, 'translation_domain' => 'FOSUserBundle'))
->add('nazwisko', 'text', array('label' => false, 'translation_domain' => 'FOSUserBundle'))
->add('username', null, array('label' => false, 'translation_domain' => 'FOSUserBundle'))
->add('email', 'email', array('label' => false, 'translation_domain' => 'FOSUserBundle'))
->add('telefon', 'number', array('label' => false, 'translation_domain' => 'FOSUserBundle'))
->add('plainPassword', 'repeated', array(
'type' => 'password',
'options' => array('translation_domain' => 'FOSUserBundle'),
'first_options' => array('label' => false),
'second_options' => array('label' => false),
'invalid_message' => 'fos_user.password.mismatch',
))
->add('captcha', 'captcha', array(
'label' => ' ',
'width' => 200,
'height' => 50,
'length' => 6,
'invalid_message' => 'The captcha code is invalid.'
))
;
}
and the html.twig
http://pastebin.com/2pbHqNyH
Note that im using symfony with twig for 2 weeks and im begginer. And im also new to the FOSU. I just want to change the default look of register form from FOSU to suitable for my site.
That is because your repeated password contains 2 fields, so the plainPassword field rendering contains invalid css structure.
Replace:
<div class="form-group">
{{ form_label(form.plainPassword, 'Hasło:', {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
<div class="col-sm-5">
{{ form_widget(form.plainPassword, {'attr': {'class':'form-control' }}) }}
{{ form_errors(form.plainPassword) }}
</div>
</div>
By:
<div class="form-group">
{{ form_label(form.plainPassword.first, 'Hasło:', {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
<div class="col-sm-5">
{{ form_widget(form.plainPassword.first, {'attr': {'class':'form-control' }}) }}
{{ form_errors(form.plainPassword.first) }}
</div>
</div>
<div class="form-group">
{{ form_label(form.plainPassword.second, 'Hasło:', {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
<div class="col-sm-5">
{{ form_widget(form.plainPassword.second, {'attr': {'class':'form-control' }}) }}
{{ form_errors(form.plainPassword.second) }}
</div>
</div>
More details: http://symfony.com/doc/current/reference/forms/types/repeated.html

Braincrafted bootstrapbundle set input size

I'm using braincrafted BootstrapBundle.
How do i get it to render inputs using input-sm?
I have scoured the docs but only seems to be setting for col sizes and not for inputs.
Here in Italy we say to do as the ancients did.
For your needs braincrafted has nothing to offer then you just add the class to the input field to achieve your needs
{{ form_start(form, {attr:{class: 'input-sm'} }) }}
{{ form_widget(form.username, {attr:{class: 'input-sm', placeholder: 'username'} }) }}
<div class="form-group">
{{ form_widget(form.password, {attr:{class: 'input-sm', placeholder: 'password'} }) }}
{{ form_widget(form.submit, {attr:{class: 'btn btn-primary btn-sm'} }) }}
</div>
{{ form_end(form) }}
{{ form_widget(form.field, {attr:{class: 'input-sm'} }) }}
or in your builder
$builder->add(
'field',
'text',
array(
'attr' => array(
'class' => 'input-sm',
'placeholder' => 'Fill it',
),
'required' => true
)
);

How to display multiple informations of another entity in the same form?

Actually, I try to create a form on middle entity and I want to display many input for the same entity (project color and project name). I would be able to create the project entity too.
# MyNiceBundle/Form/Type/CollaborationType.php
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('project', 'entity', array(
'class' => 'MyNiceBundle:Project',
'property' => 'name'
));
$builder->add('project', 'entity', array(
'class' => 'MyNiceBundle:Project',
'property' => 'color'
));
$builder->add('participant', 'entity', array(
'class' => 'MyNiceBundle:User',
'property' => 'email',
'multiple' => true,
'expanded' => true
));
$builder->add('workgroup', 'entity', array(
'class' => 'MyNiceBundle:Workgroup',
'property' => 'name',
'multiple' => false,
'expanded' => true
));
}
# Resources/Views/project_form.html.twig
<form id="project-creation" class="form" action="{{ path('nicebundle_project_create') }}" method="post">
{{ form_errors(form) }}
<div class="project">
# Here I want to show the input for project name
{{ form_errors(form.project) }}
{{ form_widget(form.project) }}
</div>
<div id="navigation-panel">
# Here I want to show the input for project color
{{ form_errors(form.project) }}
{{ form_widget(form.project) }}
{{ form_errors(form.participant) }}
{{ form_widget(form.workgroup) }}
{{ form_widget(form._token) }}
<input class="btn" type="reset" value="reset" />
<input class="btn" type="submit" value="submit" />
</div>
</form>
What should I do?
Thanks in advance.
I passed the ProjectType in the CollaborationType like that:
# MyNiceBundle/Form/Type/CollaborationType.php
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('project', new ProjectType());
$builder->add('participant', 'entity', array(
'class' => 'BtaskUserBundle:User',
'property' => 'email',
'multiple' => false,
'expanded' => true
));
$builder->add('workgroup', 'entity', array(
'class' => 'BtaskBoardBundle:Workgroup',
'property' => 'name',
'multiple' => false,
'expanded' => true
));
}
# Resources/Views/project_form.html.twig
<form id="workgroup-form-create" class="form" action="{{ path('MyNiceBundle_project_create') }}" method="post" {{ form_enctype(form) }}>
{{ form_errors(form) }}
<div class="project">
{{ form_errors(form.project) }}
{{ form_widget(form.project) }}
</div>
<div id="navigation-panel">
{{ form_errors(form.project) }}
{{ form_widget(form.project) }}
{{ form_errors(form.participant) }}
{{ form_widget(form.participant) }}
{{ form_errors(form.workgroup) }}
{{ form_widget(form.workgroup) }}
{{ form_widget(form._token) }}
<input class="btn" type="reset" value="reset" />
<input class="btn" type="submit" value="submit" />
</div>
</form>