@@ -487,6 +487,10 @@ The type would now look like::
487487 $formModifier($event->getForm()->getParent(), $sport);
488488 }
489489 );
490+
491+ // by default, action does not appear in the <form> tag
492+ // you can set this value by passing the controller route
493+ $builder->setAction($options['action']);
490494 }
491495
492496 // ...
@@ -518,10 +522,11 @@ your application. Assume that you have a sport meetup creation controller::
518522
519523 class MeetupController extends AbstractController
520524 {
525+ #[Route('/create', name: 'app_meetup_create', methods: ['GET', 'POST'])]
521526 public function create(Request $request): Response
522527 {
523528 $meetup = new SportMeetup();
524- $form = $this->createForm(SportMeetupType::class, $meetup);
529+ $form = $this->createForm(SportMeetupType::class, $meetup, ['action' => $this->generateUrl('app_meetup_create')] );
525530 $form->handleRequest($request);
526531 if ($form->isSubmitted() && $form->isValid()) {
527532 // ... save the meetup, redirect etc.
@@ -541,36 +546,49 @@ field according to the current selection in the ``sport`` field:
541546.. code-block :: html+twig
542547
543548 {# templates/meetup/create.html.twig #}
544- {{ form_start(form) }}
549+ {{ form_start(form, { attr: { id: 'supply_history_form' } } ) }}
545550 {{ form_row(form.sport) }} {# <select id="meetup_sport" ... #}
546551 {{ form_row(form.position) }} {# <select id="meetup_position" ... #}
547552 {# ... #}
548553 {{ form_end(form) }}
549554
550555 <script>
551- var $sport = $('#meetup_sport');
552- // When sport gets selected ...
553- $sport.change(function() {
554- // ... retrieve the corresponding form.
555- var $form = $(this).closest('form');
556- // Simulate form data, but only include the selected sport value.
557- var data = {};
558- data[$sport.attr('name')] = $sport.val();
559- // Submit data via AJAX to the form's action path.
560- $.ajax({
561- url : $form.attr('action'),
562- type: $form.attr('method'),
563- data : data,
564- complete: function(html) {
565- // Replace current position field ...
566- $('#meetup_position').replaceWith(
567- // ... with the returned one from the AJAX response.
568- $(html.responseText).find('#meetup_position')
569- );
570- // Position field now displays the appropriate positions.
571- }
572- });
573- });
556+ const form = document.getElementById('sport_meetup_form');
557+ const form_select_sport = document.getElementById('meetup_sport');
558+ const form_select_position = document.getElementById('meetup_position');
559+
560+ const updateForm = async (data, url, method) => {
561+ const req = await fetch(url, {
562+ method: method,
563+ body: data,
564+ headers: {
565+ 'Content-Type': 'application/x-www-form-urlencoded',
566+ 'charset': 'utf-8'
567+ }
568+ });
569+
570+ const text = await req.text();
571+
572+ return text;
573+ };
574+
575+ const parseTextToHtml = (text) => {
576+ const parser = new DOMParser();
577+ const html = parser.parseFromString(text, 'text/html');
578+
579+ return html;
580+ };
581+
582+ const changeOptions = async (e) => {
583+ const requestBody = e.target.getAttribute('name') + '=' + e.target.value;
584+ const updateFormResponse = await updateForm(requestBody, form.getAttribute('action'), form.getAttribute('method'));
585+ const html = parseTextToHtml(updateFormResponse);
586+
587+ const new_form_select_position = html.getElementById('meetup_position');
588+ form_select_position.innerHTML = new_form_select_position.innerHTML;
589+ };
590+
591+ form_select_sport.addEventListener('change', (e) => changeOptions(e));
574592 </script>
575593
576594The major benefit of submitting the whole form to just extract the updated
0 commit comments