dropDownList da popolare

Salve ragazzi, sto cercando di capire un attimo come strutturare un applicazione e vorrei capire quel’è il modo corretto di agire seguendo la filosodia di yii.

Allora io ho creato il model e il CRUD, ora volevo andare a modificare il form di update dei contenuti perché ad esempio vorrei creare una dropDownList con un elenco di dati estratti da una tabella descrittiva per poterli ovviamente scegliere più agevolmente.

Quindi sono andato nel mio _form.php e ho sostituito al textField questo:

<?php echo $form->dropDownList($model,‘id_fornitore’,CHtml::listData(TblFornitori::model()->findAll(),‘id’,‘ditta’)); ?>

Funziona tutto, ma ora il mio desiderio è quello di compilare una dropDownList con i campi risultanti da una relazione con un’altra tabella, quindi utilizzare le relations e ottenere così ad esempio solo i listini di un determinato fornitore.

Solo che sinceramente dopo aver letto i vari manuali, forse perché alle volte in certe questioni l’inglese mi è ostico, non riesco a capirne la chiave di funzionamento.

Mi potreste aiutare?

La documentazione in italiano e’ un po’ carente, devi proprio farti andare bene l’inglese.

La chiave di funzionamento si chiama CDbCriteria. E’ un attrezzo per configurare le query degli active record.

Puoi impostare select, join, where order by, praticamente tutto e lo passi come parametro alla findAll.

Per esempio:




<?php 

$criteria=new CDbCriteria;

$criteria->condition= "fornitore= :fornitore";

$criteria->params=array(':fornitore'=> $fornitoer);

echo $form->dropDownList($model,'id_fornitore',CHtml::listData(TblFornitori::model()->findAll($criteria),'id','ditta')); ?>



Cosi’ filtri la tua ddl.

Alla find all puoi passare:

  • una stringa, che verra’ usata come condition

  • un CDbCriteria

  • una array, che sara’ usato per creare un CDbCriteria

Quindi, se ti va di fare tutto in una riga, puoi usare la terza opzione:


<?php echo $form->dropDownList($model,'id_fornitore',CHtml::listData(TblFornitori::model()->findAll(

       array(

            'condition'=> "fornitore= :fornitore";

            'params'=> array(':fornitore'=> $fornitoer);

       )

),'id','ditta')); ?>

Intanto ti faccio i miei complimenti, sto cercando sul forum in generale soluzioni a quesiti che mi interessano e trovo spesso tuoi post che mi chiariscono molti concetti, grazie davvero. ;)

Benissimo, ho capito e funziona, ora sono andato a creare una action, ho impostato che mi restituisca il listData con il filtro fatto attraverso i CDbCriteria, vorrei inserire il tutto in una chiamata Ajax per aggiornare una parte di form.

A questo punto ho due dubbi:

  1. E’ necessario fare qualcosa per abilitare Ajax e i Javascript in Yii visto che non mi sembra funzionino nemmeno con gli esempi di base riportati nei tutorial.

  2. Può andare come soluzione per ottenere ciò che voglio:




<?php echo $form->dropDownList($model,'id_fornitore',CHtml::listData(TblFornitori::model()->findAll(),'id','ditta'),array(

		'ajax' => array(

		'type'=>'POST',

		'url'=>CController::createUrl('Autisti/DropDownList'),

		'change'=>'#Formulari_id_fornitore',))); ?>



Pare corretto a livello di sintassi, ma la chiamata ajax non funziona.

Non serve fare niente per abilitare ajax, funziona gia’ tutto da solo.

In quanto al tuo ajax, mi sa che cosi’ non puo’ andare.

La dropdownlist non ha una proprieta’ ajax sua, devi metterla da qualche parte, tipo nella onChange.

Una cosa cosi’:




<?php echo $form->dropDownList($model,'id_fornitore',CHtml::listData(TblFornitori::model()->findAll(),'id','ditta'),

      array(

         'OnChange'=>CHtml::ajax( array(

                'type'=>'POST',

                'url'=>CController::createUrl('Autisti/DropDownList'),

                'change'=>'#Formulari_id_fornitore',)

           )

       ); ?>



Devi sistemare un po’ di parentesi, comunque il concetto e’ che devi mettere sull’onChange del javascript.

Tieni presente che CHtml::ajax non fa niente di piu’ (e a volte fa molto di meno) di jquery.ajax, e’ solo un helper.

Fai sempre riferimento alla documentazione di jquery.

P.S: grazie mille per i complimenti, sei il primo in assoluto… grazie!!

Intanto grazie per i chiarimenti, so di fare domande anche banali, ma ci lavoro da un paio di giorni e alcune cose le sto provando ora. :)

Diciamo che con la voce ajax funziona e il javascript generato dal seguente codice:




<?php echo $form->dropDownList($model,'id_fornitore',CHtml::listData(TblFornitori::model()->findAll(),'id','ditta'),array(

		'ajax' => array(

		'type'=>'POST',

		'url'=>CController::createUrl('Autisti/DropDownList'),

		'update'=>'#id_div_autisti',

		'data'=>array('id'=>"js:$('#Formulari_id_fornitore').val()")))); ?>



Nell’HTML della index genera il seguente javascript:




/*<![CDATA[*/

jQuery(function($) {

jQuery('body').delegate('#Formulari_id_fornitore','change',function(){jQuery.ajax({'type':'POST','url':'/index.php?r=Autisti/DropDownList','data':{'id':$('#Formulari_id_fornitore').val()},'cache':false,'success':function(html){jQuery("#id_div_autisti").html(html)}});return false;});


				if(!window.location.hash)

					$('').focus();

			

});

/*]]>*/




Che pare funzionare, benché quella chiave che tu hai impostato com onChange ancora non ho esattamente capito a che gli serve esattamente. :P

Ora chiedo, in AutistiController ho creato un metodo che fa quanto segue:




public function actionDropDownList()

	{	

$id=(int)$_POST["id"];

$model=new Autisti('search');

echo CActiveForm::labelEx($model,'id_autista');

echo CActiveForm::dropDownList($model,'id',CHtml::listData(Autisti::model()->findAll('id_fornitore='.$id),'id','FullName'));

	}	



Ma è corretto usare così la chiamata a CActiveForm per generare una DropDownList aggiornata? Così funziona, ma ci sono metodi migliori e più eleganti?

Ne arriveranno altri, ne sono sicuro ;)

Grazie ancora delle tue risposte, mi sono di aiuto, devo però dire che come frameworks è potete e ben costruito, sto facendo un applicazione nella metà del tempo seppur usando parte di questo tempo ad imparare.

Yii e’ una bomba, basta saperlo usare.

Mi piace il fatto che e’ molto “quadrato”, le cose funzionano tutte, tutte nello stesso modo e tutte assieme.

Quello che fai tu e’ corretto, comunque poco bello perche’ metti delle echo nel controller.

Inoltre scrivi in 2 punti il codice della dropdownlist.

Quello che faccio in questi casi, e’ di creare una subview per la parte da mandare con ajax:

file _formDDL.php




echo CActiveForm::labelEx($model,'id_autista');

echo CActiveForm::dropDownList($model,'id',CHtml::listData(Autisti::model()->findAll('id_fornitore='.$id),'id','FullName'));



file _form:




...

<?php $this->renderPartial('_formDDL', array(...))?>

...



E nel controller:




public function actionDropDownList()

        {       

           $id=(int)$_POST["id"];

           $model=new Autisti('search');

           $this->renderPartial('_formDDL', array(...));

        }  



Cosi se devi cambiare la ddl, lo fai in un posto solo. Dai una occhiata a questo per le regole di buona scrittura, non e’ ufficiale ma uno dei developers ha detto che e’ fico, quindi tanto sbagliato non sara’

Scusate se riapro questo thread dopo tanto tempo, ma volevo provare a condividere con voi un pezzetto del mio codice:




  <?php for($i=date("Y")+1,$y=array();$i>1910;$i--,$y[$i]=$i); ?>


  <div class="row">

    <?php echo $form->labelEx($model,'anno'); ?>

    <?php echo $form->dropDownList($model,'anno',$y); ?>

    <?php echo $form->error($model,'anno'); ?>

  </div>



Qualche volta mi piace scrivere codice estremamente sintetico =).

Ma cosa in particolare volevi condividere?


<?php for($i=date("Y")+1,$y=array();$i>1910;$i--,$y[$i]=$i); ?>

Mi piacciono i for in una riga sola =). Tutto qui :-p

E’ una questione di gusti, ma tutti sono ugualmente leciti.

In generale prefereisco adottare uno stile chiaro, in modo che i miei colleghi non mi debbano chiedere come funziona la mia roba.

Di sicuro siamo andati aut of topic…

Grande esempio, Zaccaria, ma come riempi gli array(…) ?

Grazie per i contributi che pubblichi, sono davvero molto utili.

Ma è possibile inserire il DropDownList con qualche effetto con jquery?

Certo. Ma ci vuole una domanda più specifica se vuoi una risposta più dettagliata. Partendo dal presupposto che potresti scrivere codice from scratch, puoi fare tutto.