Tengo un formulario de ubicación con tres "seleccionar" (lista de opciones): país, área y departamento. Estos "selectos" tienen por defecto todo el listado de país, zona y departamento. Quiero que mi usuario elija primero un país o un área o un departamento.
Lo que quiero hacer:
Cuando un usuario elige un país, los datos en el área cambian dependiendo de este. Lo mismo entre área y departamento.
Lo que tengo:
Aquí mi formulario:
//src/Form/LocationType.php class LocationType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('country', EntityType::class, [ 'class' => Country::class, ]) ->add('area', EntityType::class, [ 'class' => Area::class, 'required' => false ]) ->add('department', EntityType::class, [ 'class' => Department::class, 'required' => false ]); //The part I comment for makes the auto-update between area and department works $formArea = function(FormInterFace $form, Country $country = null) { if($country === null) { $form->add('area', EntityType::class, [ 'class' => Area::class, 'required' => false ]); } else { $areas = $country->getAreas(); $form->add('area', EntityType::class, [ 'class' => Area::class, 'choices' => $areas, 'required' => false ]); } }; $builder->get('country')->addEventListener( FormEvents::POST_SUBMIT, function (FormEvent $event) use ($formArea){ $country = $event->getForm()->getData(); $formArea($event->getForm()->getParent(), $country); } ); // $formDepartment = function(FormInterFace $form, Area $area = null) { if($area === null) { $form->add('department', EntityType::class, [ 'class' => Department::class, 'required' => false ]); } else { $departments = $area->getDepartments(); $form->add('department', EntityType::class, [ 'class' => Department::class, 'choices' => $departments, 'required' => false ]); } }; $builder->get('area')->addEventListener( FormEvents::POST_SUBMIT, function (FormEvent $event) use ($formDepartment){ $area = $event->getForm()->getData(); $formDepartment($event->getForm()->getParent(), $area); } ); }Y código JS con llamada AJAX:
//assets/js/selectCountryAreaDepartment.js window.onload = () => { let country = document.querySelector("#location_country"); country.addEventListener("change", function() { let form = this.closest("form"); let data = this.name + "=" + this.value; console.log(data); fetch(form.action, { method: form.getAttribute("method"), body: data, headers: { "Content-Type": "application/x-www-form-urlencoded; charset:UTF-8" } }) .then(response => response.text()) .then(html => { let content = document.createElement("html"); content.innerHTML = html; let area = content.querySelector("#location_area"); document.querySelector("#location_area").replaceWith(area); console.log(area); }) .catch(error => { console.log(error); }) }); let area = document.querySelector("#location_area"); area.addEventListener("change", function() { let formArea = this.closest("form"); let dataArea = this.name + "=" + this.value; //console.log(formArea); console.log(dataArea); fetch(formArea.action, { method: formArea.getAttribute("method"), body: dataArea, headers: { "Content-Type": "application/x-www-form-urlencoded; charset:UTF-8" } }) .then(response => response.text()) .then(html => { let contentArea = document.createElement("html"); contentArea.innerHTML = html; let department = contentArea.querySelector("#location_department"); document.querySelector("#location_department").replaceWith(department); console.log(department); }) .catch(error => { console.log(error); }) }); }Este código se basa en este tutorial en francés: https://www.youtube.com/watch?v=f7tdb30evUk