submit form a symfony 2.8 desde ajax-jquery

En el controlador el formulario $form->isSubmited() y $form->isValid() siempre me dan FALSO. ¿¿¿????

Chicos estoy aprendiendo y me he quedado atascado en esto os dejo el código por si alguien puede ayudarme: ...php <?php // src/AppBundle/Entity/User.php namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Validator\Constraints as Assert;

/**

  • @ORM\Entity
  • @ORM\Table(name="users")
  • @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository") */ class User implements UserInterface, \Serializable{ /**
    • @ORM\Id
    • @ORM\Column(type="integer")
    • @ORM\GeneratedValue
    • */ private $id; /**
    • @ORM\Column(type="string", length=25, unique=true)
    • @Assert\NotBlank() */ private $username; /**
    • @ORM\Column(type="string",length=64)
    • @Assert\Length(min=6) */ private $password; /**
    • @ORM\Column(type="integer")
    • @Assert\Choice(choices = {0,1,2}) */ private $type; // 0.administrador| 1.protectora | 2.patrocinador.. /**
    • @ORM\Column(type="string",length=100) */ private $name; /**
    • @ORM\Column(type="string",length=60,unique=true)
    • @Assert\Email() */ private $email; ...

      <?php // src/AppBundle/Controller/UserController.php namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use AppBundle\Entity\User; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response;

class UserController extends Controller {
/**

  • @Route("/admin/updateUser/{id_user}",
  • defaults = { "id_user" = 0 },
  • name = "updateUser" ) */ public function updateUserAction($id_user=0,Request $request){ if (!$request->hasPreviousSession()){ $data = Array("result"=>'error: no login'); } if ($request->isXmlHttpRequest()){ try{ $em = $this->getDoctrine()->getManager(); $user= $em->find('AppBundle\Entity\User',$id_user); $form = $this->createForm('AppBundle\Form\UserType',$user); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em->persist($user); $em->flush(); $data = Array("result"=>'ok'); }else{ return $this->render('mto/frmUser.html.twig', array('frm' => $form->createView(),'errors'=>'submited='.($form->isSubmitted()?'si':'no').' valid='.($form->isValid()?'si':'no').' errors='.$form->getErrors()->__toString())); } } catch (\Exception $e){ $data = Array("result"=>'error: '.$e->getMessage()); } }else{ $data = Array("result"=>'error: no ajax'); } $response = new Response(json_encode($data, JSON_FORCE_OBJECT)); $response->headers->set('Content-Type', 'application/json; charset=utf-8'); return $response;

    } ...

    ...javascript / Un botón lanza en su evento clic() la siguiente función / ... function updateUser(){ var id = $('#user_id').val(); var data = $('#user_form').serialize(); $.ajax({ type: "POST", url: Routing.generate("updateUser",{'id_user':id}), contentType: "application/json; charset=utf-8", dataType: "json", data: data, success: function(data) { $("#form_user").html(data); } }); } ...

    El formulario es este: ...twig {{ form_start(frm, {'attr': {'id': 'user_form'}}) }} {{ form_errors(frm) }}

    {{ form_row(frm.id) }} {{ form_row(frm.username) }} {{ form_row(frm.password) }}
    {{ form_row(frm.type) }} {{ form_row(frm.name) }} {{ form_row(frm.address) }} {{ form_row(frm.email) }}
    {{ form_row(frm.web) }} {{ form_row(frm.socialNetwork) }}
    {{ form_row(frm.longitude) }} {{ form_row(frm.latitude) }}
    {{ form_row(frm.blockade) }}
    {{ errors }}

    {{ form_end(frm) }}

Respuestas

#1

¿Has probado a hacer algún dump del form? Para ver cual es el error, los valores que envía etc.?

Haz un die(dump($form)); en en controller cuando recibes el formulario y vete mirando a ver si falta algún campo, llega el csrf, te indica el error el form etc. Para ir descartando.

#2

Muchísimas gracias por contestar.

He puesto dump despues de "$form->handleRequest($request);"

Supongo que los datos que he enviado en el formulario están en "viewData", pero no ahí no están, están los originales de la base de datos. El csrf, es el ¿token?, ¿dónde puedo ver si es valido?

Este método del controller se ejecuta tanto la primera vez que envia los datos para cambiar (method = "GET") como los datos ya modificados (method="POST")

No entiendo la secuencia de symfony en estos dos procesos. Aparte del método GET o POST, como sabe symfony si tiene que volver a crear el formulario de nuevas o debe recibirlo para su grabación en la base de datos: ¿Este código del Controlador está bien?

/**
 * @Route("/extranet/updateUser/{id}",
 *          name = "updateUser" )
 * @Method({"GET", "POST"})
 */
public function updateUserAction(Request $request, User $user){
    if (!$request->hasPreviousSession()){
        $data = Array("result"=>'error: no login');
    }elseif ($request->isXmlHttpRequest()){
        try{
            $form = $this->createForm('AppBundle\Form\UserType',$user,array(
            'action' => $this->generateUrl('updateUser', array('id' => $user->getId())),
            'method' => 'POST'));
 
            $form->handleRequest($request);
 
            if ($request->getMethod()=='POST') die(dump($form));
 
            if ($form->isSubmitted() && $form->isValid()) {
                $em = $this->getDoctrine()->getManager();
                $em->persist($user);
                $em->flush();
                return $this->redirectToRoute('showUser', array('id' => $user->getId()));
            }
            return $this->render('mto/frmUser.html.twig', array(                        
                'user'=> $user,
                'frm' => $form->createView(),
                'errors'=>'submited='.($form->isSubmitted()?'si':'no').', valid='.($form->isValid()?'si':'no').', errors='.$form->getErrors()->__toString()));
        } catch (\Exception $e){
            $data = Array("result"=>'error: '.$e->getMessage());
        }
    }else{
        $data = Array("result"=>'error: no ajax');
    }
    $response = new Response(json_encode($data, JSON_FORCE_OBJECT));
    $response->headers->set('Content-Type', 'application/json; charset=utf-8');
    return $response;
}
#3

Ah.. ya lo veo funcionar. Me faltaba poner un método setId en el modelo o bien poner la option "mapped=false en el campo ID en el formBuilder. También la manera en que enviaba el formulario desde jquery, encontré la solución enviando el formulario con GET para mostrarlo la primera vez y con POST cuando lo envio para la actualización en la base de datos. Además lo enviaba con contentType=json, he dejado la opción por defecto de jquery (supongo que application/x-www-form-urlencoded). Finalmente quedó así: '''jquery

function updateUser(show=true,id=0){
    if(id==0) id = $('#user_id').val();
    var data = $('#user_form').serialize();
    $.ajax({
        type: show?"GET":"POST",
        url: Routing.generate("updateUser",{'id':id}),

// contentType: "application/json; charset=utf-8", data: data, success: function(data) { $("#form_user").html(data); $("#user_form").submit(function(e){ e.preventDefault(); updateUser(false,id); }); } }); }

Gracias ampersound90, por tu interés.