Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Como puedo actualizar un choice en symfony ?

17 de enero de 2017

Quiero actualizar el campo codDepartamento con los estados segun el pais que se eliga en el campo paises, El ajax envía los valores pero no resibe respuesta alguna ayuda

Formulario enc_userType con cada campo de la entidad enc_users

<?php
 
namespace UserBundle\Form;
 
use UserBundle\Form\Listener\AddStateFieldSubscriber;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 
class enc_usersType extends AbstractType 
{
 
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
 
        $builder
 
    ->add('codIdentificacion',EntityType::class,array(
 
        'placeholder'=>'Seleccionar',
        'class'=>'UserBundle:EncTipoidentificacion',
        'choice_label' => 'getTipoidentificacion'
 
    ))
            ->add('identificacion',IntegerType::class)
            ->add('password',PasswordType::class)
            ->add('username',TextType::class)
            ->add('apellidos',TextType::class)
            ->add('genero',ChoiceType::class,['choices'=>array(
                'Masculino'=>'M',
                'Femenino'=>'F',
                    'Otro'=>'O'
            ),'choice_label'=> function ($category,$index,$key) {
                    return $index;
                },'placeholder'=>'Seleccionar'
                ]
                )
            ->add('email',EmailType::class)
            ->add('fecNacimiento',DateType::class)
            ->add('telFijo',TextType::class)
            ->add('telMovil',TextType::class)
            ->add('paises',EntityType::class,array(
                'placeholder'=>'Seleccionar',
                'class'=>'UserBundle:EncPais',
                'query_builder'=>function(EntityRepository $er){
                    return $er->createQueryBuilder('u')
                        ->orderBy('u.id','ASC');
                },
                'choice_label'=>'nomPais',
 
            ))
            ->add('role',ChoiceType::class,['choices' => array('Administrador' => 'ROLE_ADMIN', 'Usuario' => 'ROLE_USER'), 'placeholder' =>'Seleccionar'])
            ->add('isActive',CheckboxType::class)
            ->add('codDepartamento',ChoiceType::class)
            ->add('codMunicipio')
            ->add('codBarrio')
            ->add('direccion',TextType::class)
            ->add('save',SubmitType::class,array('label'=>'Agregar Usuario'))
        ;
        //EVENTO PARA ACTUALIZAR codDepartamento
        $builder->addEventSubscriber(new AddStateFieldSubscriber());
 
    }
 
    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'UserBundle\Entity\enc_users'
        ));
    }
 
}

Clase de event listener para actualizar el campo

<?php
 
namespace UserBundle\Form\Listener;
 
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
 
class AddStateFieldSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::PRE_SUBMIT => 'preSubmit',
        );
    }
 
    /**
     * Cuando el usuario llene los datos del formulario y haga el envío del mismo,
     * este método será ejecutado.
     */
    public function preSubmit(FormEvent $event)
    {
        $data = $event->getData();
        //data es un arreglo con los valores establecidos por el usuario en el form.
 
        //como $data contiene el pais seleccionado por el usuario al enviar el formulario,
        // usamos el valor de la posicion $data['country'] para filtrar el sql de los estados
 
       $this->addField($event->getForm(), $data['country']);
 
    }
 
    protected function addField(Form $form, $country)
    {
        // actualizamos el campo state, pasandole el country a la opción
        // query_builder, para que el dql tome en cuenta el pais
        // y filtre la consulta por su valor.
        $form->add('codDepartamento',EntityType::class, array(
            'placeholder'=>'Seleccionar',
            'class' => 'UserBundle:EncDepartamento',
            'query_builder' => function(EntityRepository $er) use ($country){
                return $er->createQueryBuilder('state');
                    /*->where('state.codPais = :country')
                    ->setParameter('country', $country);*/
            },
            'choice_label'=>'nomDepartamento',
        ));
    }
}

Controlador para la vista y actualizacion de campo

<?php
 
namespace UserBundle\Controller;
 
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use UserBundle\Entity\enc_users;
use UserBundle\Form\enc_usersType;
 
class DefaultController extends Controller
{
     public function listadoAction()
    {
        $Doctrine = $this->getDoctrine();
        $db = $Doctrine->getConnection();
        $consulta= "SELECT * FROM enc_encuesta";
        $envio=$db->prepare($consulta);
        $envio->execute();
 
        return $this->render('UserBundle:Default:listado.html.twig',array("users"=>$envio));
    }
     //RUTA PRINCIPAL       
    public function registroAction()
    {
        $user = new enc_users();
        $form = $this->createCreateForm($user);
        return $this->render('UserBundle:Default:registro.html.twig',array('form'=>$form->createView()));
    }
 
    private function createCreateForm(enc_users $entity)
    {
     $form=$this->createForm(enc_usersType::class,$entity,array(
        'action'=>$this->generateUrl('create_index'),'method' =>'POST'));
 
        return $form;
 
    }
    // RUTA PARA ACTUALIZAR CAMPO O GUARDAR DATOS EN BASE DE DATOS
    public function createAction(Request $request)
    {
        $user = new enc_users();
        $form = $this->createCreateForm(enc_usersType::class,$user);
 
        $form->handleRequest($request);
 
        if($form->isValid()){
            $password=$form->get('password')->getData();
            $encoder=$this->container->get('security.password_encoder');
            $encoded=$encoder->encodePassword($user,$password);
            $user->setPassword($encoded);
            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            $em->flush();
            $this->addFlash('mensaje','El usuario ha sido creado exitosamente');
            return $this->redirectToRoute('Registro_index');
        }
 
        return $this->render('UserBundle:Default:registro.html.twig',array('form'=>$form->createView()));
 
    }
 
}

AJAX envia valor del campo que contiene el pais

$(document).ready(function(){
 
       var $country = $('#enc_users_paises');
 
    $('#enc_users_paises').on('change', function(event) {
 
       var $form = $country.closest('enc_users');
       var data = $country.serialize();
       $.ajax({
            url: $form.attr('action'),
            type: $form.attr('method'),
            data : data,
           success: function(html) {
               alert(html);
               $('#enc_users_codDepartamento').replaceWith($(html).find('#enc_users_codDepartamento'));
           }
        });
    });
 
});

Respuestas

#1

Buenas @YuberAndresR,

Efectivamente la forma recomendada es usando event listeners en los formularios. Te comparto un link a un post donde se explican algunos casos de uso de formularios dinamicos en Symfony.

http://manuelj555.github.io/2015/04/26/formularios-dinamicos.html

Saludos!

@manuel_j555

18 enero 2017, 14:07