How to get form data with session in Symfony Form - php

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.

Related

GET max value form since DB symfony 4

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'
]);
}

How to use constraints in Symfony Forms making a field required?

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?

Symfony CollectionType field with one default field

I need your advice with CollectionType field.
I've made my collection type field using this: Symfony CollectionType Field
Everything works fine. Even dynamic adding field with JQuery works properly.
But there is an issue.
I can't find out how to add one field each time the collection field renders. Right now after my page loads, my collection field is empty. However, I want the first field from the collection after every page load.
How to achieve this? Should I use Javascript or kind of form event? Any tips for finding a right chapter in documentation or code snippets will be very welcome.
This way worked for me.
// 3 default values for empty form
$configArr = [[], [], []];
if ($builder->getData()) {
$configArr = $builder->getData()->getColumns();
}
$builder->add('columns', CollectionType::class, [
'entry_type' => ColumnType::class,
'prototype' => true,
'allow_add' => true,
'allow_delete' => true,
'data' => $configArr,
'mapped' => false,
]);
I think I remember hitting this and I ended up creating data with an empty child on first load.
I'm unable to test this however I think the following should work depending on your form specifics.
public function someAction()
{
$data = [];
$data['collection_name'][] = ['text' => ''];
$form = $this->createForm(SomeType::class, $data);
return $this->templating->renderResponse('template.twig.html', [
'form' => $form,
]);
}
Adding 'required' => false, to the collection's form config should prevent empty items being persisted.
You may also investigate the configureOptions method on the form Type class:
public function configureOptions(OptionsResolver $resolver)
{
$data = [];
$data['collection_name'][] = ['text' => ''];
$resolver->setDefaults(array(
'empty_data' => $data,
));
}
This simply worked for me.
public function buildForm(FormBuilderInterface $builder, array $options) {
$data = $builder->getData(); // data passed to the form
$builder->add('textFields', CollectionType::class, [
'entry_type' => TextType::class,
'data' => $data ? $data->getTextFields() : ['']
]);
}

Nested Form / Mapping field to entity

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 :)

symfony2 choice form valid

I have got a simple smyfony2 form with one choices element. When I choose "kerosin" or "diesel" the form won't validate, what is correct. When I won't choose any of the three options and submit the form empty, $form->validate() will return true, but it shouldn't. Any ideas? Using the HTML5 required is not a solution for me.
This is my Form AbstractType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Form erzeugen
$builder->add('treibstoff', 'choice', array(
'choices' => array(
'kerosin' => 'form.quiz1.kerosin',
'benzin' => 'form.quiz1.benzin',
'diesel' => 'form.quiz1.diesel',
),
'multiple' => false,
'expanded' => true,
'label' => ' '
))
->getForm();
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
// Validierung erzeugen
$collectionConstraint = new Collection(array(
'treibstoff' => array(
new Choice(array(
'choices' => array('benzin'),
'message' => 'form.quiz.falscheantwort',
'strict' => true
)
)
)
));
$resolver->setDefaults(array(
'validation_constraint' => $collectionConstraint
));
}
public function getName()
{
...
Validation works like this:
if($Request->getMethod() == "POST") {
$form->bind($Request);
if($form->isValid()) {
echo "valid";
Thanks in advance.
Edit:
I changed the setDefaultOptions like suggested and added NotBlank. That worked out for me:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
// Validierung erzeugen
$collectionConstraint = new Collection(array(
'treibstoff' => array(
new Choice(array(
'choices' => array('benzin'),
'message' => 'form.quiz.falscheantwort',
'strict' => true,
)
),
new NotBlank()
)
));
$resolver->setDefaults(array(
'validation_constraint' => $collectionConstraint
));
}
You set only valid choice to benzin in setDefaultOptions, but you didn't specify the field as required. Note that required in form field only sets HTML5 validation on:
Also note that setting the required option to true will not result in
server-side validation to be applied. In other words, if a user
submits a blank value for the field (either with an old browser or web
service, for example), it will be accepted as a valid value unless you
use Symfony's NotBlank or NotNull validation constraint.
So, you'll have to add also NotBlank constraint to treibstoff field.

Categories