Necesito poder mandar varios campos de un formulario incluido uno de tipo "file" por ajax para luego poder guardarlos en la base de datos con Symfony2. Lo hice sin petición ajax siguiendo esta documentación: http://symfony.com/doc/2.3/cookbook/controller/upload_file.html y se guarda correctamente todo, pero a la hora de querer hacerlo por ajax tengo problema con el campo "file" y por más que busco en la web sólo se habla de FormData, pero no sé usarlo ni mandarlo junto con mis otros datos y tampoco sé cómo usarlo luego en el controlador para que funcione mi código.
El código que uso es el siguiente:
Controlador:
public function createAction(Request $request) { if ($request->isXmlHttpRequest() && !$request->isMethod('POST')) { throw new HttpException('XMLHttpRequests/AJAX calls must be POSTed'); } $entity = new Student(); $form = $this->createCreateForm($entity); $form->handleRequest($request); if ($form->isValid()) { $file = $entity->getPhoto(); $fileName = md5(uniqid()).'.'.$file->guessExtension(); $photoDir = $this->container->getParameter('kernel.root_dir').'/../web/uploads/images'; $file->move($photoDir, $fileName); $entity->setPhoto($fileName); $em = $this->getDoctrine()->getManager(); $em->persist($entity); $em->flush(); if ($request->isXmlHttpRequest()) { return new JsonResponse(array('message' => 'Success!','success' => true), 200); } if ($request->isMethod('POST')) { return new JsonResponse(array('message' => 'Invalid form','success' => false), 400); } return $this->redirect($this->generateUrl('student_show', array('id' => $entity->getId()))); } return $this->render('BackendBundle:Student:new.html.twig', array( 'entity' => $entity, 'form' => $form->createView(), )); }
Entidad:
use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; //... /** * @var string * * @ORM\Column(name="photo", type="string", length=255, nullable=true) * @Assert\File(mimeTypes={ "image/png","image/jpg" }) */ private $photo; public function setPhoto($photo) { $this->photo = $photo; return $this; } public function getPhoto() { return $this->photo; }
Formtype:
//... ->add('photo', 'file', array('required' => false)) //...
Javascript:
//... $('.form_student').on("submit",function(event) { event.preventDefault(); $.ajax({ type: 'POST', url: Routing.generate('student_create'), data: $(this).serialize(), dataType: 'json', success: function(response) { alert(response.message); }, error: function (response, desc, err){ if (response.responseJSON && response.responseJSON.message) { alert(response.responseJSON.message); } else{ alert(desc); } } }); });
Respuestas
Lo he solucionado con estos cambios:
data: new FormData($(this)[0])
en lugar de :
data: $ (this).serialize()
Y añadiendo en la petición ajax:
processData: false, contentType: false, cache: false,
@Carlos01270727
21 enero 2016, 15:35