<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog cakephp en español por Hospedaxes &#187; actualizar selects</title>
	<atom:link href="http://cakephp.hospedaxes.com/tag/actualizar-selects/feed" rel="self" type="application/rss+xml" />
	<link>http://cakephp.hospedaxes.com</link>
	<description>Blog sobre desarrollo web con cakephp en español por Hospedaxes</description>
	<lastBuildDate>Mon, 26 Apr 2010 07:11:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Actualizar el contenido de un select con ajax.</title>
		<link>http://cakephp.hospedaxes.com/actualizar-el-contenido-de-un-select-con-ajax</link>
		<comments>http://cakephp.hospedaxes.com/actualizar-el-contenido-de-un-select-con-ajax#comments</comments>
		<pubDate>Wed, 11 Jun 2008 07:44:11 +0000</pubDate>
		<dc:creator>bernal</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[cakephp-1.2]]></category>
		<category><![CDATA[actualizar selects]]></category>
		<category><![CDATA[cakephp]]></category>

		<guid isPermaLink="false">http://www.hospedaxes.com/blog-cakephp/?p=5</guid>
		<description><![CDATA[En esta entrada vamos a explicar como asociar dos selects mediante ajax y al modificar el elemento seleccionado en uno de ellos  cambie el contenido del otro.
Podemos ver el ejemplo de funcionamiento aquí.
Un ejemplo muy claro para esta situación sería dos selects, uno con provincias y el otro con localidades, lo que queremos es [...]]]></description>
			<content:encoded><![CDATA[<p>En esta entrada vamos a explicar como asociar dos selects mediante ajax y al modificar el elemento seleccionado en uno de ellos  cambie el contenido del otro.</p>
<p>Podemos ver el ejemplo de funcionamiento <a href="http://www.hospedaxes.com/blog-cakephp/pruebas" target="_blank">aquí.</a></p>
<p>Un ejemplo muy claro para esta situación sería dos selects, uno con provincias y el otro con localidades, lo que queremos es que al cambiar de provincia varíe la lista de localidades y muestre las que están en la provincia seleccionada.</p>
<p>Lo haremos utilizando el ajaxHelper, para que no sea necesario la recarga de la página y quede más atractivo.</p>
<p>Lo primero que haremos será definir los modelos de provincias ,localidades y un tercer modelo en el que usaremos los selects, por ejemplo podría ser un modelo de cliente, en el que al insertar un nuevo cliente tendríamos que elegir la provincia y localidad a la que pertenece.</p>
<h1><span style="text-decoration: underline;">Modelos</span></h1>
<p><strong>Modelo de provincia.</strong></p>
<pre class="prettyprint">/app/models/provincia.php

class Provincia extends AppModel
{
    var $name = 'Provincia';
}</pre>
<p><strong>Modelo de localidad.</strong></p>
<pre class="prettyprint">/app/models/localidade.php

class Localidade extends AppModel
{
    var $name = 'localidade';
}</pre>
<p><strong>Modelo de cliente.</strong></p>
<pre class="prettyprint">/app/models/cliente.php

class Cliente extends AppModel
{
    var $name = 'Cliente';
}</pre>
<h1><span style="text-decoration: underline;">Controladores</span></h1>
<p>Después de esto tendremos que definir los controladores.</p>
<p><strong>Controlador de localidad.</strong></p>
<pre class="prettyprint">/app/controllers/localidades_controller.php

class LocalidadesController extends AppController
{
	var $name = 'Localidades';
}</pre>
<p><strong>Controlador de provincia.</strong></p>
<pre class="prettyprint">/app/controllers/provincias_controller.php

class ProvinciasController extends AppController
{
	var $name = 'Provincias';
}</pre>
<p>Y por últino el controlador de clientes que será el que implementará la funcionalidad.</p>
<p><strong>Controlador de cliente.</strong></p>
<pre class="prettyprint">/app/controllers/clientes_controller.php

class ClientesController extends AppController
{
	var $name = 'Clientes';
	var $helpers = array('Ajax');
	var $uses = array('Cliente','Provincia','Localidade');

	function insertar()
	{
		$listadoProvincias = $this->Provincia->find('all', array('fields'=>array('id','nombre'),'order'=>'nombre ASC'));
		$this->set('provincias', Set::combine($listadoProvincias, "{n}.Provincia.id","{n}.Provincia.nombre"));
		$primera_provincia = $this->Provincia->find(null,null,'nombre ASC');
		$listadoLocalidades = $this->Localidade->find('all', array('fields'=>array('id','nombre'),'order'=>'nombre ASC','conditions'=>'Localidade.provincia_id='.$primera_provincia['Provincia']['id']));
		$this->set('localidades', Set::combine($listadoLocalidades, "{n}.Localidade.id","{n}.Localidade.nombre"));

		// RESTO DE LA FUNCIONALIDAD DE INSERCIÓN DE CLIENTES
	}

	function update_select()
	{
		if (!empty($this->data['Localidade']['provincia_id']))
		{
			$provincia_id = $this->data['Localidade']['provincia_id'];
			$localidades = $this->Localidade->find('all', array('fields'=>array('id','nombre'),'order'=>'nombre ASC','conditions'=>array('provincia_id'=>$provincia_id)));
		}
		else
		{
			$localidades = $this->Localidade->find('all', array('fields'=>array('id','nombre'),'order'=>'nombre ASC'));
		}
		$this->set('options', Set::combine($localidades, "{n}.Localidade.id","{n}.Localidade.nombre"));
		$this->render('/elements/update_select', 'ajax');
	}
}</pre>
<p>Por un lado tenemos la <strong>función insertar</strong>, que será una función genérica de inserción de clientes. La parte que a nosotros nos interesa es en la que se inicializan las variables que después utilizaremos en los selects, estas deberán ser arrays en los que cada elemento tenda un identificador y su valor, para que el select pueda utilizarlos en la vista.</p>
<p>En la versión 1.1 de cakephp, esto se podía hacer mediante la función generateList del modelo, función que se ha eliminado en la 1.2.<br />
Por ello ahora es necesario hacerlo en dos pasos, por un lado realizar la búsqueda con un findAll y después utilizar la función combine de la clase Set que genera un array con la estructura deseada, que será el que le pasemos a la vista.</p>
<pre class="prettyprint">$listadoProvincias = $this->Provincia->find('all', array('fields'=>array('id','nombre'),'order'=>'nombre ASC'));
$this->set('provincias', Set::combine($listadoProvincias, "{n}.Provincia.id","{n}.Provincia.nombre"));</pre>
<p>La segunda función <strong>update_select</strong>, es a la que llamará el ajax para actualizar el listado de localidades a partir de un identificador de provincia.</p>
<p>Como se puede ver en el código, la función coge el identificador de provincia del select y envía a la vista los arrays actualizados de provincias y localidades.</p>
<h1><span style="text-decoration: underline;">Vistas</span></h1>
<p>Localidades y provincias no tendrán vistas asociadas, ya que no hay ninguna operación en el controlador.</p>
<p>En clientes tendremos que crear la vista para la operación insertar del controlador, esta podría ser algo como esto:</p>
<pre class="prettyprint">/app/views/clientes/insertar.ctp

echo $form->create('Inscripcione',array('action'=>'insertar'));
echo $form->inputs(array('legend'=>'Actualizar Provincias',
		'Localidade.provincia_id' => array('label'=> 'Provincia','showEmpty'=>'false','id'=>'provincias'),
		'Alumno.localidade_id' => array('label'=> 'Localidad','showEmpty'=>'false','id'=>'localidades'),
			));
echo $form->end();

$options = array('url' => 'update_select','update' => 'localidades');
echo $ajax->observeField('provincias',$options);</pre>
<p>La vista será muy sencilla, un formulario con dos selects, uno de localidades y otro de provincias y una llamada al ajaxHelper en la que se indica que cada vez que se modifique el valor del select provincias, se llame a la función update_select y actualice el select de localidades.</p>
<p>Este select se actualizará con los valores devueltos por la vista de update_select, que lo único que hace es imprimir todos los nombres de localidades devueltos por la función del controlador.</p>
<pre class="prettyprint">/app/views/elements/update_select.ctp
if(!empty($options)) {
  foreach($options as $k => $v) {
    echo <code >"&lt;option value='$k'&gt;$v&lt;/option&gt;";</code>
  }
 }</pre>
<p>En este enlace se puede ver un ejemplo de <a href="http://www.hospedaxes.com/blog-cakephp/pruebas" target="_blank">funcionamiento</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/actualizar-el-contenido-de-un-select-con-ajax/feed</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
	</channel>
</rss>

