La mayoría de los ejemplos que aparecen en Internet sobre como codificar las funciones javascript y JQuery para select dependientes, suponen el caso de dos tablas. La tabla «padre», donde se selecciona un elemento de la lista desplegable, y luego que se elige este, aparecen las opciones disponibles de la tabla «hijo» en la segunda lista desplegable.
Pero que pasa cuando tengo tres tablas. La tabla 1, contiene campos que la relacionan con las tablas 2 y 3, en una relación «uno a muchos». A su vez, la tabla 2 sería la tabla «padre» de la tabla 3, que pasaría a ser la tabla «hijo».
Veamos la siguiente imagen que ilustra la relación:
Cuando creo un registro nuevo para la tabla 1, los valores de las tablas 2 y 3, aún no existen, y si se usan las funciones disponibles en la web, estas funcionan bien.
Pero, si quiero editar un registro existente de la tabla 1, el formulario _form.php en Symfony, debe mostrar los valores correctos de las tablas 2 y 3. En estos casos, los ejemplos de la web para dos tablas no funcionan.
Veamos mi caso, y la forma en que modifique una función JQuery, para que trabaje bien, tanto para los registros nuevos como para la edición de un registro existente.
A continuación les presento las tres tablas y sus relaciones:
Tabla 1 (simplificada):
Conflictos1: connection: doctrine tableName: conflictos_1 columns: id: type: integer(4) fixed: false unsigned: false primary: true autoincrement: true id_sector_actividad: type: integer(4) fixed: false unsigned: false primary: false notnull: true autoincrement: false id_subsector_actividad: type: integer(4) fixed: false unsigned: false primary: false notnull: false autoincrement: false relations: SectorActividadCiuTa7: local: id_sector_actividad foreign: id type: one SubsectorActividadTa8: local: id_subsector_actividad foreign: id type: one
Tablas 2 y 3:
SectorActividadCiuTa7: connection: doctrine tableName: sector_actividad_ciu_ta7 columns: id: type: integer(4) fixed: false unsigned: false primary: true autoincrement: true sector_actividad: type: string(255) fixed: false unsigned: false primary: false notnull: true autoincrement: false relations: Conflictos1: local: id foreign: id_sector_actividad type: many SubsectorActividadTa8: local: id foreign: id_sector type: many SubsectorActividadTa8: connection: doctrine tableName: subsector_actividad_ta8 columns: id: type: integer(4) fixed: false unsigned: false primary: true autoincrement: true id_sector: type: integer(4) fixed: false unsigned: false primary: false notnull: true autoincrement: false descripcion: type: string(255) fixed: false unsigned: false primary: false notnull: true autoincrement: false relations: SectorActividadCiuTa7: local: id_sector foreign: id type: one Conflictos1: local: id foreign: id_subsector_actividad type: many
La función AJAX – JQuery, en el partial _form.php en el módulo conflictos1, quedaría así:
<script type="text/javascript"> $(document).ready(function() { $("#conflictos1_id_sector_actividad").change(function() { var id_sub = $(this).val(); if(id_sub != '') { $.ajax ({ type: "POST", url: '<?php echo url_for('conflictos/subsector'); ?>'+ '?id=' + id_sub, cache: false, data: "id_sub="+ id_sub, success: function(data) { $("#conflictos1_id_subsector_actividad").html(data); // but it does not select the value of dropdown list. } }); } else { $("#conflictos1_id_subsector_actividad").html(" <option value=''>-- No se ha seleccionado subsector --</option> "); } return false; }); }); </script>
En el formulario del partial _form.php en el módulo conflictos1, la parte correspondiente al campo id_subsector_actividad, quedaría así:
<?php if (!$form->getObject()->isNew()): ?> <?php echo $form['id_subsector_actividad'] ?> <?php endif; ?> <?php if ($form->getObject()->isNew()): ?> <select name="conflictos1[id_subsector_actividad]" id="conflictos1_id_subsector_actividad"> <option value="" selected="selected">Seleccione sub-sector</option> <?php endif; ?>
La función que se llama desde la url: conflictos/subsector sería como sigue:
public function executeSubsector() { $id_sub = $_POST['id_sub']; $this->subsec= Doctrine_Core::getTable('SubsectorActividadTa8') ->createQuery('a') ->where('a.id_sector = ?', $id_sub) ->execute(); }
Luego, para los casos de edición de un registro existente, necesitamos algo de código adicional. Agregamos para el campo 'id_subsector_actividad'
en el widget de conflictos1 la propiedad 'table_method'=>'Subsector'
asociada a la función public function Subsector()
para ello creamos en el archivo SubsectorActividadTa8Table.class.php la siguiente función:
public function Subsector() { global $elsector; if (!is_null($elsector)){ $id_sub=$elsector; $query= Doctrine_Query::create() ->select('a.id') ->from('SubsectorActividadTa8 a') ->innerJoin('a.Conflictos1 c') ->where('a.id_sector = ?', $id_sub); return $query->execute(); } }
En la función executeEdit del archivo actions.class.php del módulo conflictos1 quedaría así:
public function executeEdit(sfWebRequest $request) { global $elsector; $this->forward404Unless($conflictos1 = Doctrine_Core::getTable('Conflictos1')->find(array($request->getParameter('id'))), sprintf('Object conflictos1 does not exist (%s).', $request->getParameter('id'))); $elsector= $conflictos1->getIdSectorActividad(); $this->form = new Conflictos1Form($conflictos1); }
Aquí capturamos en la variable $elsector el valor del campo id_sector_actividad que luego utilizamos en la función Subsector()