submit symfony 3 form with ajax

后端 未结 1 1123
情深已故
情深已故 2021-02-05 20:02

I\'m trying to implement my symfony forms / modal ,with ajax to stop reloading page every time time I submit an add/remove and update action, but the problem that I\'m not famil

1条回答
  •  梦毁少年i
    2021-02-05 20:52

    i will answer this very basically to let you get an idea !

    so first of all you will have to separate the saving part on the server side, because it will not return a view anymore like your indexAction does. Instead it returns some json data your ajax call on the client side can receive

    your new controller action may look somelike this:

       /**
        * Creates a new Department entity.
        *
        * @Route("/department/new", name="department_new")
        * @Method({ "POST"})
        */
       public function newDepartmentAction(Request $request)
       {
            $department = new Department();
            $form = $this->createForm('EvalBundle\Form\DepartmentType', $department);
            $form->handleRequest($request);
            $status = "error";
            $message = "";
    
            if ($form->isSubmitted() && $form->isValid()) {
                $em = $this->getDoctrine()->getManager();
                $em->persist($department);
                try {
                    $em->flush();
                    $status = "success";
                    $message = "new department saved";
                } catch (\Exception $e) {
                        $message = $e->getMessage();
                }    
            }else{
                $message = "invalid form data";
            }
    
            $response = array(
                'status' => $status,
                'message' => $message
            );
    
            return new JsonResponse($response);
    
            // above is just an example of one way using formtypes, 
            // you can retrieve any parameter you send here like: 
            // $param = $request->get('param');
    
    
       }
    

    you can do above whatever you want like paginate over all departments and return them, but you would need a js way to display the returned JSON then, you cant use twig for that because the view is already returned, you definetly want to use any datadriven JS View Model lib with automatic ui refresh.

    Next, The client Side - From the client side you will have to send the the correct data to that action

    so you have to serialize the formfields to a set of properties and values that you can send to the server. We will first serialize the form to a javascript object.

    here you have a function for that that you have to include somewhere after jquery has loaded and before your further code

    $.fn.serializeObject = function()
    {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function() {
            if (o[this.name] !== undefined) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });
        return o;
    };
    

    Next you have to avoid actually submitting the form non-ajax, because clicking on the submit button will lead to submit the form and reload the page, we prevent that behaviour, assuming the form has some unique selector eG. id="newDepartmentForm"

    $(document).on("submit", "#newDepartmentForm", function(e){
        e.preventDefault();
        return  false;
    });
    

    now lets assume you want to save by clicking on a button with specific id

    $(document).on("click", "#mySubmitButton", function(e){
      e.preventDefault();
      var form = $("#newDepartmentForm");
    
      // you could make use of html5 form validation here
      if(!form[0].checkValidity()){
    
        // To show the native error hints you can fake a click() on the actual submit button
        // which must not be the button #mySubmitButton and shall be hidden with display:none;
        //  example:
        //  
        //  
        //
        $("#myHIDDENSubmitButton").click();
        return false;
      }
    
      // get the serialized properties and values of the form 
      var form_data = form.serializeObject();
    
      // always makes sense to signal user that something is happening
      $('#loadingSpinner').show();
    
      // simple approach avoid submitting multiple times
      $('#mySubmitButton').attr("disabled",true);
    
      // the actual request to your newAction
      $.ajax({
        url: '/department/new',
        type: 'POST',
        dataType: 'json',
        data: form_data,
        success:function(data){
    
          // handling the response data from the controller
          if(data.status == 'error'){
            console.log("[API] ERROR: "+data.message);
          }
          if(data.status == 'success'){
            console.log("[API] SUCCESS: "+data.message);
          }
    
          // signal to user the action is done
          $('#loadingSpinner').hide();
          $('#mySubmitButton').attr("disabled",false);
        }
      });
    });
    

    basically thats it.

    if you want to make your site full Ajax-driven, you can request any data from the server like this, for example you may want to load all existing departments first you could just do it like above. But as i mentioned, you would need a JS way to Display your data, terms like single page application, MVVM could be worth a lookup there are a lot of usefull libraries like vue, react, knockout, ember ... etc. if you prefer an easy way, they may not be neccessary depending on the complexity of your model. For your Api you also may dig more into performant serialization, REST, CRUD, authorization and dont repeat yourself. Websockets may also be very interesting.

    0 讨论(0)
提交回复
热议问题