E’ un classico problema per i form da utilizzare nelle web application: selezionare in una select un elemento e popolare una seconda select con elementi ottenuti dalla scelta della prima.
Il tipico esempio è quello della scelta del Comune: per facilitare la vita all’utente gli si chiede di selezionare la provincia in una prima select per poi scegliere nella seconda tra i comuni della sola provincia selezionata.
Tra i vari modi di ottenere delle select in cascata, ho scelto di sfruttare JQuery, ma soprattutto gli oggetti messi a disposizione da CakePHP nella versione 1.3 per accedervi facilmente.
Installazione di JQuery
Si potrebbe scaricare la libreria sul proprio server e richiamarla da lì, ma preferisco richiamarle dal repository di Google.
1 | echo $this ->Html->script( array ( 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js' )); |
per inserirla nel layout, oppure
1 | $this ->Html->script( array ( 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js' ),false); |
da utilizzare occasionalmente nella view.
Nel layout
Si deve aggiungere un comando per la scrittura della cache degli script prima del tag di chiusura
1 | echo $this ->Js->writeBuffer(); // Write cached scripts |
Nel controller
Immaginiamo di dover scegliere la città per un utente, quindi nel controller Users richiamiamo l’heleper
1 | var $helpers = array ( 'Js' => array ( 'Jquery' )); |
Popoliamo la prima select con i nomi delle province (districts)
1 2 3 | function add(){ $this ->set( 'districts' , $this ->User->City->District->find( 'list' )); } |
Per ottenere l’elenco delle città in base alla provincia selezionata si deve creare un metodo del controller Cities
1 2 3 4 5 6 | function getCities(){ $this ->layout= "ajax" ; $district_id = $this ->data[ 'City' ][ 'district_id' ]; $cities = $this ->City->find( 'list' , array ( 'conditions' => array ( 'City.district_id' => $district_id ))); $this ->set( 'cities' , $cities ); } |
Nella view Cities/getCities
1 2 3 4 5 6 7 8 | foreach ( $cities as $k => $v ){ echo " <option value= "\"$k\"" > $v </option> "; } |
Nella view Users/add
1 2 3 4 | echo $this ->Form->create(); echo $this ->Form->input( 'district_id' , array ( 'empty' =>true)); echo $this ->Form->input( 'city_id' , array ( 'type' => 'select' )); echo $this ->Form-> end ( 'Invia' ); |
A questo punto bisogna inserire il codice JQuery che attiva il meccanismo, ma lo facciamo utilizzando i metodi del component JS.
Inserire prima del form il seguente codice:
01 02 03 04 05 06 07 08 09 10 11 12 | $this ->Js->get( '#UserDistrictId' )->event( 'change' , $this ->Js->request( array ( 'controller' => 'cities' , 'action' => 'getCities' ), array ( 'method' => 'POST' , 'type' => 'json' , 'async' => true, 'update' => '#UserCityId' , 'dataExpression' =>true, 'data' => $this ->Js->serializeForm( array ( 'isForm' => true, 'inline' => true)) ) ) ); |
Fare attenzione al nome delle select interessate, utilizzando la notazione CSS per la loro identificazione ‘#nomecampo’ e la convenzione di CakePHP.
5 comments for “Select multipli (o in cascata) in CakePHP con JQuery e AJAX”