Alberto
Alberto

Reputation: 441

Symfony2: send form and other variables with ajax

I am using Symfony, version 2.5.3, and I am trying to submit a form with Ajax. So, in my controller I have

  $form = $this->createForm(
      new MyFormType(), 
      $formvariable
  );

  $form->handleRequest( $request );

  if ($form->isValid()) {
      // do stuff
  } else {
      // other stuff
  } 

and my jQuery script could be similar to this:

    formdata = $('form[name=MyFormTypeForm]').serialize();

    $.ajax({
        type: "POST",
        url: // my url,
        data: formdata ,
        async: true,
        dataType: "json",
        success: function(response) 
        {
            // stuff here
        },
        error: function(XMLHttpRequest, textStatus, errorThrown)
        {
            // stuff there
        },
    });

This would work fine, but unfortunately I have to send other variables together with the fields of the form.
What I want to do in my jQuery is something like:

    formdata = $('form[name=MyFormTypeForm]').serialize();

    value      = { 
                  myvar1   : data1    ,
                  myvar2   : data2    ,
                  formdata : formdata ,
                };

    $.ajax({
        type: "POST",
        url: // my url,
        data: value ,
        async: true,
        dataType: "json",
        success: function(response) 
        {
            // stuff here
        },
        error: function(XMLHttpRequest, textStatus, errorThrown)
        {
            // stuff there
        },
    });

However, in this way $form->isValid() inside the controller always returns false.

Is there a way to fix this?
Thank you in advance

Alberto

Edit: Adding some additional details, in response to comments:

I cannot add some extra fields inside my form because the additional variables are used to generate the form itself.

More details of the controller:

    $em = $this->getDoctrine()->getManager();

      $action = $request->request->get('action',   null);
      $myentid = $request->request->get('myentid',   null);

      // Here I determine if I have to create a form for a new entity or an 
      // entity already present in the database
      if ( empty($myentid) )
      {
          // New entity
          $formvariable = new MyEntity();
      } else {
          // Retrieve entity from database
          $formvariable = $this->getDoctrine()->getManager()
              ->getRepository('MyBundle:MyEntity')
              ->find($myentid);
      }

      $form = $this->createForm(
          new MyFormType(), 
          $formvariable
      );

      // I am requesting a new form: render the form and send to page
      if ($action == "newform")
      {
          $response["code"] = $this->render('MyBundle:Controller:mytwigview.html.twig', array( 
              'form' => $form->createView(), 
              ))->getContent();
          return new Response(json_encode($response));

      }

      // The form has already been filled: save
      if ($action == "save")
      {
          $form->handleRequest( $request);

          if ($form->isValid()) {
              $em->flush();
          } else {
              echo "Errors: ".$form->getErrors();
          }
      }

// And here I return the save confirmation

Upvotes: 4

Views: 5977

Answers (2)

DelphiLynx
DelphiLynx

Reputation: 921

I use the following to submit two forms at once via Ajax. It is also the answer to your question:

$.ajax({
    type: "POST",
    url: Routing.generate('ajax_report_processing_create_pdf'),
    data: $reportMainWrapper.find('form[name="report"]').serialize() + '&' +
    $reportProcessingForm.find('form').serialize(),
    dataType: "json"
})
    .done(function (data) {
        console.log('done');
        console.log(data);
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
        console.log('fail');
        console.log(jqXHR);
    })
    .always(function () {
        console.log('always');
    });

As you can see, you can just use:

data: 'myvar1=' + data1 + '&' + 'myvar2=' + data2 + '&' + formdata,

As you see I did not 'formdata=' + formdata,. That is because your variable formdata already contains key-value data as such:

form[yourinput1]  = 'string1'
form[yourinput2]  = 'string2'

So in your controller you can now simply do a $form->handleRequest($request); and it will work instantly.

Upvotes: 0

Markus Kottländer
Markus Kottländer

Reputation: 8268

The controller should look something like this I would suggest:

/**
 * @Route("/myentity/{myentid}")
 */
public function newAndEditAction(Request $request, $myentid = null)
{
    $em = $this->getDoctrine()->getManager();

    // Here I determine if I have to create a form for a new entity or an 
    // entity already present in the database
    if ($myentid)
    {
        // Retrieve entity from database
        $formvariable = $this->getDoctrine()->getManager()
            ->getRepository('MyBundle:MyEntity')
            ->find($myentid);
    } else {
        // New entity
        $formvariable = new MyEntity();
    }

    $form = $this->createForm(
        new MyFormType(),
        $formvariable
    );

    if ($request->getMethod() == 'POST') { // save
        $form->handleRequest($request);

        if ($form->isValid()) {
            $em->flush();
            // return some response
            return Response(...);
        }
    } else { // edit and new
        return new Response($this->render('MyBundle:Controller:mytwigview.html.twig', array(
            'form' => $form->createView(),
        ))->getContent());
    }
}

I made the id parameter optional for this action and decide whether to save/update and show new or edit form based on the id parameter and request method.

Upvotes: 3

Related Questions