eronn
eronn

Reputation: 1830

Symfony 4 - Submit Ajax form

on my project Symfony 4 I have a page where I fill a form. In this one, I have to select a vehicle at a certain moment. I would like to offer the user the possibility to add one in ajax to the right of the "Vehicle" field. As soon as it is added in database, he also adds to his list so that he can select it. I watched a tutorial to do pretty much the same thing. I created my function in my controller, and I manage to generate the modal window with the form to enter a new vehicle. But I can not really submit it and make it appear in the list.

Currently, I've this :

enter image description here

It is to add a vehicle in database, and that it appears in the list of the field of my main form. The field "Véhicule de service" (the last field).

So, I did this :

I created a function controler for adding vehicle :

/**
     * Pour créer un nouveau véhicule
     * 
     * @Route("/manage/ordreMission/new/new_vehicule", name="vehicule_create")
     * @Method({"POST"})
     * @return Response
     */
    public function createVehicule(Request $request, ObjectManager $manager)
    {
        $vehicule = new Vehicule();

        $form = $this->createForm(VehiculeType::class, $vehicule, [
            'action' => $this->generateUrl($request->get('_route'))
        ])
            ->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $manager->persist($vehicule);
            $manager->flush();
            return $this->json([
                'code' => 200,
                'message' => 'OK',
                'vehicule' => $vehicule,
            ], 200);
        }

        return $this->render('ordre_mission/partials/newVehicule.html.twig', [
            'formVehicule' => $form->createView(),
        ]);
    }

I created my form view in Twig :

{# ordre_mission/partials/newVehicule.html.twig #}
{# http://127.0.0.1:8000/manage/ordreMission/new/new_vehicule #}

{{form_start(formVehicule)}}
{{ form_widget(formVehicule) }}
<div class="form-group row">
    <div class="col-sm-2"></div>
    <div class="col-sm-10">
        <button type="submit" class="btn btn-primary" data-label="Enregistrer">
            Enregistrer
        </button>
    </div>
</div>
{{ form_end(formVehicule) }}

And in my principal Twig view ( with the first form ), I added a modal and Ajax to add my vehicle :

   {% extends "base.html.twig" %}

{% block stylesheets %}
    <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/css/select2.min.css" rel="stylesheet"/>
{% endblock %}

{% block body %}

    {{form_start(form)}}
    {{form_row(form.user)}}
    {{form_row(form.accompagnateur)}}
    {{form_row(form.entreprise)}}
    {{form_row(form.lieu)}}
    {{form_row(form.motif)}}
    {{form_row(form.date)}}
    {{form_row(form.transport)}}
    {{form_row(form.immatriculationVehiculeService)}}
    {# champs où je vais pouvoir ajouter un véhicule #}
    <button class="btn btn-primary" type="submit">Enregistrer</button>
    {{form_end(form)}}

    <button class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
        <i class="fa fa-plus"></i>
        Ajouter un véhicule
    </button>

    <!-- Modal -->
    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalTitle" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalTitle">Ajout d'un article</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body"></div>
            </div>
        </div>
    </div>

    <div id="ajax-results">here comes the result</div>

{% endblock %}

{% block javascripts %}

    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/js/select2.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.form/4.2.2/jquery.form.min.js"></script>


    <script>
        $('.js-example-basic-single').select2({placeholder: 'Choisissez un agent', allowClear: true, language: 'fr'});
    </script>

    <script>
        $('#exampleModal').on('shown.bs.modal', function () {
            var modal = $(this);
            $.ajax('{{ path('vehicule_create') }}', {
                success: function (data) {
                    modal.find('.modal-body').html(data);
                }
            });
        });
        $(document).on("submit", "form", function (e) {

            e.preventDefault();
            console.log(e.target.id);

            var id = e.target.id;

            if(id == "formVehicule")
            {

                $formVehicule = $(e.target);
                modal = $('#exampleModal');


                var $submitButton = $formVehicule.find(':submit');
                $submitButton.html('<i class="fas fa-spinner fa-pulse"></i>');
                $submitButton.prop('disabled', true);

                $formVehicule.ajaxSubmit({
                    type: 'post',
                    success: function (data) {
                        if (data.message == 'OK') {
                            var sel = document.getElementById("ordre_mission_immatriculationVehiculeService");
                            var opt = document.createElement('option');
                            opt.appendChild(document.createTextNode(data.vehicule.vehiculeString));
                            opt.value = data.vehicule.immatriculation;
                            sel.appendChild(opt);
                            modal.modal('toggle');
                        } else {
                            modal.find('.modal-body').html(data);
                        }
                    },
                    error: function (jqXHR, status, error) {
                        $submitButton.html(button.data('label'));
                        $submitButton.prop('disabled', false);
                    }
                });
            }
            else
            {
                e.target.submit();
            }

        });

    </script>

{% endblock %}

UPDATE : (I updated my code, you can see it)

So everything works. But it's not clean, I think. The problem is that when I submitted the main form, it also entered the listener when it should not. So I had to add an ID to the vehicle creation form, and in the listener, I had to make a condition:

If the form ID matches the vehicle's creation ID, then it can launch the listener code. Otherwise, he must submit the form normally.

Except that I do not know if it's clean ... And most importantly, I risk being led to add another possibility of adding an object by a modal. So it's going to be more and more complicated, is not it?

Upvotes: 0

Views: 932

Answers (1)

LeVerbeux
LeVerbeux

Reputation: 43

Your error shows that symfony can't find a route for

"POST /manage/ordreMission/new/new_vehicule" (from "http://127.0.0.1:8000/manage/ordreMission/new")

Your route seem good so either you are not sending a "POST" request (you can check using the Network Profiler in your Browser) or your JS code is not working properly and you may actually send a request which is not XmlHttpRequest(). Try to remove condition="request.isXmlHttpRequest()" in your route definition to see if it works.

Upvotes: 1

Related Questions