Running Symfony 4 with Symfony Forms, I have defined a text field in a form builder:
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// .... other fields
$builder->add('referralCode', TextType::class, [
'required' => true,
'label' => 'Referral Code',
'constraints' => [new NotBlank()],
'attr' => [
'placeholder' => 'Enter a six figures Referral Code (e.g. "6EQE7M")'
]
]);
}
According to docs and tutorials, the NotBlank-constraint should be used here. However, it does not work. If I submit the form without any data typed into this text field, no error is shown. Instead a null value will be send into the property of the entity.
What else needs to be done here?
Related
I've been looking for a solution for hours. I'am working with Symfony 3.2.
I'am using Symfony Forms in order to display a data-table (with different filter chosen in the form) with Ajax => No submit button.
I can access to different result of data-table to view more information.
What i want is that when i leave the detail page by clicking on a button and come back on the research page, that i could keep in history all filters that i have chosen.
i wanted use session but actually, it seems has 0 impact. Below is some codes.
Controller:
public function indexAction(Request $request)
{
$form = $this->createSearchForm();
$request->getSession()->set('form_data', $form->getData());
$form->handleRequest($request);
$form->setData($request->getSession()->get('form_data'));
$this->datatable($form->getData());
return $this->render('backend/jobOffer/index.html.twig', [
'form' => $form->createView()
]);
}
FormType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('publicationState', ChoiceType::class, [
'label' => 'backend.job_offer.publication_state',
'required' => false,
'choices' => JobOffer::getPublicationStateChoices(),
'choice_translation_domain' => 'choices',
])
->add('job', Select2EntityType::class, [
'label' => 'backend.job',
'required' => false,
'class' => 'AppBundle:Job',
'text_property' => 'label',
'remote_route' => 'job_autocomplete',
])
->add('ids', HiddenType::class, [
'required' => false,
])
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'csrf_protection' => false,
'method' => 'GET',
]);
}
I have a problem, there is a EntityType (or Select2EntityType) field named "job" in my form builder and i can't get the content of this field in my session. This field shows a autocomplete data-list after typing 2 letters, and we can choose one of job.
and also, when i refresh the page, i lose all filters, but i am supposed to store them in session ?
Thanks in advance for your help,
Yes you can use $form->getData() but to do that you need to do this according to the doc here with using if ($form->isSubmitted() && $form->isValid()) { among others.
In Symfony 4 form I have a form field declared with EntityType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('tags', EntityType::class, array(
'class' => Saptag::class,
'choice_label' => 'descr',
'required' => false,
'multiple' => true,
//'attr' => ['class' => 'selectpicker']
));
...
}
When form is submited my database is well updated. If I activate class 'selectpicker' then my field has the rendering I need in the template but field value do not update database when this class is used. No error occurs...
Any idea of how to handle that ?
EDIT: This issue occurs when form is placed crossed div element:
<div>
</form>
</div>
Sorry to disturb you but I would like to obtain a max value for a form validation for example it can be a numeric field but the validation of type range MaxValue will have to be retrieved in the database I explain myself for example I wish to reserve a transport the max value by default is 4 for 4 remaining places but if for this vehicle there are 3 places left, the validation would have to pass to 3
I tried to go through entitytype with events but it didn't change anything to my problem it returned in the drop down list all the number of places for each vehicle.
The goal is to make a simple form a reservation button with just a way to choose the number of places while not being able to exceed the value of the database.
For example the URL is /transport/6/book
We must find a way to pass the value of id number 6 and the validation would be between 1 and 3 for example or create a list that puts 1 2 3
If transport 7 to 1 place of availability it would have to be 1 only.
Excuse me if I misspoke but I've been working on it for more than a week and I can't get it to work so I've moved to an old commit to keep the application working.
I'm a beginner in this area so I don't know the advanced features of the form but I'm very good at the twig repository etc. It's just this part that is blocking, thanks in advance for your help.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nbPlaces', EntityType::class, [
'class' => Transport::class,
'label' => 'Nombre de places',
'attr' => [
'placeholder' => "Nombre de places",
],
'query_builder' => function (TransportRepository $transportRepository) use ($id_service) {
return $transportRepository->findOneByIdPlace($id_service);
},
'choice_label' => 'nbPlaces'
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Reservation::class,
'id_service' => null
]);
}
and controller
$booking = new Reservation();
$form = $this->createForm(ReservationType::class, $booking, ['id_service' => $service]);
and $id_service is undefined variable in use
It's because $id_service is never defined. You should get it from the options. Take a look here :
https://symfony.com/doc/current/forms.html#other-common-form-features
So your code should be a thing like this.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$id_service = $options['id_service'];
$builder
->add('nbPlaces', EntityType::class, [
'class' => Transport::class,
'label' => 'Nombre de places',
'attr' => [
'placeholder' => "Nombre de places",
],
'query_builder' => function (TransportRepository $transportRepository) use ($id_service) {
return $transportRepository->findOneByIdPlace($id_service);
},
'choice_label' => 'nbPlaces'
]);
}
Currently, I develop an app with PHP Symfony Framework. I've got a problem with Form Builder (I think).
I have two entities. Question and Choice.
Question and Choice are OneToMany Relationship Entity. One Question has many Choice.
Another two entities, Video and Category, the relationship is just the same with Question and Choice.
I create scaffolding crud for those entity with php bin/console make:crud.
Then I add the relationship symfony like in this guide from Symfony.
The logic is, I must select the Category first to create new Video. Same with the Choice, I must select the Question first to create new Choice data.
My problem appear when I open the Choice Create Form [/choice/new]. It says
Variable "expanded" does not exist.
Then the error details show on this lines
return $this->render('choice/new.html.twig', [
'choice' => $choice,
'form' => $form->createView(), // The highlighted error appear on this line
]);
But, It just happen in the Question-Choice, My Category-Video relationship is just fine. I tried to make Question-Choice as same as Category-Video (I changed the name of the entity for sure), I triple check it, but the error on Choice Create Form still occur.
This is my App\Form\ChoiceType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('content')
->add('letter')
->add('image')
->add('question', EntityType::class, [
'class' => Question::class,
'choice_label' => 'content'
])
;
}
Notice the add('question')
and this is my App\Form\VideoType buildForm method
<?php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('url', FileType::class, [
'label' => 'Video File',
'required' => false,
])
->add('thumbnail', FileType::class, [
'required' => false,
])
->add('description')
->add('category', EntityType::class, [
'class' => Category::class,
'choice_label' => 'name'
])
;
}
Notice the add('category')
So, anyone know what is happening?
I renamed App\Form\ChoiceType to App\Form\TheChoiceType, make some adjusment for class name changing on the controller. Everything is work!
I don't believe this! The solution is to rename the form type.
I'm looking for best (or just working) way to solve following problem.
I have like standard UserType form
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'username',
Type\TextType::class
)
->add(
'email',
Type\EmailType::class
)
->add(
'plainPassword',
Security\UserRepeatedPasswordType::class
)
->add(
'roles',
Type\ChoiceType::class,
[
'multiple' => true,
'expanded' => true,
'choices' => $this->getRoleChoices()
]
);
}
What is nonstandard is that UserRepeatedPasswordType, it looks like this
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'password',
Type\RepeatedType::class,
[
'type' => Type\PasswordType::class,
'required' => true,
'first_options' => [
'label' => 'Password'
],
'second_options' => [
'label' => 'Repeat Password'
],
]
);
}
And I created it because those two fields are also used in passwordReset form and userSettings form. And now I have two problems:
1.) When I use it this way, value from UserRepeatedPasswordType is not correctly mapped for my User Entity - there is an error that string is expected (duh ;) but it got array. I tried using View and Model transformer but no proper results (but I don't have much experience with those, so that maybe the case). I also tried to experiment with getParent(), and pass there UserType but it goes to some endless loop and I got 500. If I just copy paste field from UserRepeatedPasswordType to UserType it works correctly.
2.) If this is solved (or even by copy paste, if can't be done other way), there is another related (I believe) problem:
I have this ChangePasswordType form, which is used to reset your password.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'confirmationToken',
Type\HiddenType::class,
[
'required' => true,
'constraints' => [
new NotBlank(),
]
]
)
->add(
'plainPassword',
Type\RepeatedType::class,
[
'type' => Type\PasswordType::class,
'required' => true,
'first_options' => [
'label' => 'Password'
],
'second_options' => [
'label' => 'Repeat Password'
],
]
)
->add(
'changePassword',
Type\SubmitType::class
);
}
And it works fine as it is but I want to do two things with it - first, solving my first problem and use UserRepeatedPasswordType in it, second - I have some Assert\Length done in User Entity on $plainPassword and it workes correctly when I submit new user via UserType form. But I want that validation somewhat mapped to ChangePasswordType or ideally to UserRepeatedPasswordType - just to have all rules in one place. Can this even be done? Thanks for any solutions / hints / advices.
Ok, dunno if anyone is interested but that is how I completed this. If anyone have better answer, just give me a sign (mostly to the first one) ;)
1.) As i thought, solved by ViewTransformer but in parent form (In UserType not in UserRepeatedPasswordType
$builder->get('plainPassword')
->addViewTransformer(new CallbackTransformer(
function ($singleAsArray) {
return $singleAsArray;
},
function ($arrayAsSingle) {
return $arrayAsSingle['password'] ?? '';
}
));
2.) That was actually quite easy. All you have to do is to map that form to UserEntity that same way as UserType and made custom validation groups just to have everything nice and under control :)