0

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?

4
  • Can you please add the route file code? No route found error means you are not specifying route as POST. See here symfony.com/doc/current/routing.html#matching-http-methods Commented Oct 24, 2019 at 15:28
  • Okay, I updated my first post. But is it really a problem ? Because in my controller function, I added the route, no ? Commented Oct 24, 2019 at 15:32
  • Sorry I overlooked that part. You are missing the method type in the controller annotation. So i think this should solve this missing route problem @Route("/manage/ordreMission/new/new_vehicule", name="vehicule_create", condition="request.isXmlHttpRequest()", methods={"GET","POST"}). Commented Oct 24, 2019 at 15:42
  • Don't know if that will fix it @MuhammadTashfeen, by default, routes can handle any type of request. I believe methods flag is only for limiting the types of request. Commented Oct 24, 2019 at 15:43

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

12 Comments

Okay I removed the ", condition="request.isXmlHttpRequest()", and now, it works ! I've my new Vehicle in my database ! But suddenly I am redirected to a blank page with writing "success". I guess it's because in my controller I tell him to send me a response "success" if successful. But suddenly how could I not be redirected, and make sure my last field is "updated"?
If your page is reloaded, that because you are not sending XmlHttpRequest. It's a normal post (the same as when you send a form). So either your JS or your html is not correct. And yes your controller should return a JsonResponse.
Oh okay, and in my JsonResponse, I have to return what ? The new object maybe ?
I return a json now. But my page is going to the blank page with json response. I'm a beginner in Ajax, I don't know how can I block the redirection
Can you try to comment your ajax function ($formVehicule.ajaxSubmit({...})) and see if the form is still sent ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.