Skip to content

[Form] Update dynamic_form_modification.rst #18228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 41 additions & 26 deletions form/dynamic_form_modification.rst
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ The type would now look like::
class SportMeetupType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
{
$builder
->add('sport', EntityType::class, [
'class' => Sport::class,
Expand Down Expand Up @@ -487,6 +487,10 @@ The type would now look like::
$formModifier($event->getForm()->getParent(), $sport);
}
);

// by default, action does not appear in the form tag
// you can set this value by passing the controller route
$builder->setAction($options['action']);
}

// ...
Expand Down Expand Up @@ -518,10 +522,11 @@ your application. Assume that you have a sport meetup creation controller::

class MeetupController extends AbstractController
{
#[Route('/create', name: 'app_meetup_create', methods: ['GET', 'POST'])]
public function create(Request $request): Response
{
$meetup = new SportMeetup();
$form = $this->createForm(SportMeetupType::class, $meetup);
$form = $this->createForm(SportMeetupType::class, $meetup, ['action' => $this->generateUrl('app_meetup_create')]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// ... save the meetup, redirect etc.
Expand All @@ -541,36 +546,46 @@ field according to the current selection in the ``sport`` field:
.. code-block:: html+twig

{# templates/meetup/create.html.twig #}
{{ form_start(form) }}
{{ form_start(form, { 'attr' : { 'id' : 'supply_history_form' } }) }}
{{ form_row(form.sport) }} {# <select id="meetup_sport" ... #}
{{ form_row(form.position) }} {# <select id="meetup_position" ... #}
{# ... #}
{{ form_end(form) }}

<script>
var $sport = $('#meetup_sport');
// When sport gets selected ...
$sport.change(function() {
// ... retrieve the corresponding form.
var $form = $(this).closest('form');
// Simulate form data, but only include the selected sport value.
var data = {};
data[$sport.attr('name')] = $sport.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
complete: function(html) {
// Replace current position field ...
$('#meetup_position').replaceWith(
// ... with the returned one from the AJAX response.
$(html.responseText).find('#meetup_position')
);
// Position field now displays the appropriate positions.
}
});
});
const form = document.getElementById('sport_meetup_form');
const form_select_sport = document.getElementById('meetup_sport');
const form_select_position = document.getElementById('meetup_position');

const updateForm = async (data, url, method) => {
const req = await fetch(url, {
method: method,
body: data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'charset': 'utf-8'
}
});

const text = await req.text();
return text;
};

const parseTextToHtml = (text) => {
const parser = new DOMParser();
const html = parser.parseFromString(text, 'text/html');
return html;
};

const changeOptions = async (e) => {
const requestBody = e.target.getAttribute('name') + '=' + e.target.value;
const updateFormResponse = await updateForm(requestBody, form.getAttribute('action'), form.getAttribute('method'));
const html = parseTextToHtml(updateFormResponse);
const new_form_select_position = html.getElementById('meetup_position');
form_select_position.innerHTML = new_form_select_position.innerHTML;
};

form_select_sport.addEventListener('change', (e) => changeOptions(e));
</script>

The major benefit of submitting the whole form to just extract the updated
Expand Down