Reputation:
I have the following problem: I create a form, which has a select field and different text fields. When the select field has a certain value, than some text fields should be disabled. So I have JavaScript
code, which handles the onchange
event on my select field, and then disables/enables the text fields. And I have some PHP
logic, which disables the text fields initially depending on the value which is retrieved from the database. This all works. The problem is, that when I validate my form, and I have an validation-error, I don’t know, how to disable my text fields (without using JavaScript
) when I render the validated form again. Because in my validation, I setup an fresh and empty entity, then I create the form based on this entity, and then I handle the request. So in the moment of creating the form, I don’t have the values, which I need to determine if the text fields should be disabled or enabled initally.
So the question is, how do I disable some form fields after handling the validation?
Here is some pseudo-code with the problem pointed out in the comments
// create the form object depending on the form entity
private function createForm($formEntity) {
$attributes = [];
if ($formEntity->getType() === 'x') {
// disable fields if type === 'x'
$attributes = ['disabled' => 'disabled'];
}
$form = $this->createFormBuilder($task)
->add('type', ChoiceType::class)
->add('fieldA', TextType::class, ['attr' => $attributes])
->add('fieldB', TextType::class, ['attr' => $attributes])
->add('save', SubmitType::class, ['label' => 'Create Task'])
->getForm();
return $form;
}
// action to just view the form
public function detailsAction($id) {
$databaseEntity = $service->get(id);
$formEntity = FormEntity::fromDatabaseEntity();
// in this case, the $formEntity has the values from the database
// so inside the createForm, the fields can be disabled/enabled
$form = $this->createForm($formEntity);
// when I render the form, the fields are disabled initially
return render('views/details.twig.html', ['form' => $form->createView()]);
}
// action which handles the submit of the form, and render the form with validation constraints, if there are some
public function handleSubmitAction($id) {
$formEntity = new FormEntity();
// in this case, the $formEntity is empty
// so inside the createForm, the fields can not be disabled/enabled
$form = $this->createForm($formEntity);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->redirectToRoute('task_success');
}
// when I render the form, the fields are not disabled initially
return render('views/details.twig.html', ['form' => $form->createView()]);
}
Upvotes: 1
Views: 4687
Reputation: 512
You need to modify your form before submit, based on request data you get. This can be done before the request data gets applied to form during submit by using PRE_SUBMIT
method.
private function createForm($formEntity) {
$attributes = [];
if ($formEntity->getType() === 'x') {
// disable fields if type === 'x'
$attributes = ['disabled' => 'disabled'];
}
$form = $this->createFormBuilder($formEntity)
->add('type', ChoiceType::class)
->add('save', SubmitType::class, ['label' => 'Create Task'])
->add('fieldA', TextType::class, ['attr' => $attributes]);
->add('fieldB', TextType::class, ['attr' => $attributes]);
->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
$attributes = [];
if ($event->getData()['type'] === 'x') {
$attributes = ['disabled' => 'disabled'];
}
$form = $event->getForm();
$dataA = $form->get('fieldA')->getData();
$dataB = $form->get('fieldB')->getData();
$form->remove('fieldA');
$form->remove('fieldB');
$form->add('fieldA', TextType::class, ['attr' => $attributes]);
$form->add('fieldB', TextType::class, ['attr' => $attributes]);
$form->get('fieldA')->setData($dataA);
$form->get('fieldB')->setData($dataB);
})
->getForm();
return $form;
}
https://symfony.com/doc/current/form/events.html
And you should separate your form creation to separate FormType
and Handler
classes.
Upvotes: 1