[Yii 1] [RISOLTO]Tabular Input. Aiuto perfavore

Salve a tutti, sto provando da settimane a cimentarmi con il TabularInput per aggiornare più record con un unico form Submit.

Nonostante abbia seguito la guida http://www.yiiframework.com/doc/guide/1.1/it/form.table e nonostante abbia letto praticamente tutti i forum possibili e immaginabbili non riesco a farlo funzionare.

Chiedo cortesemente a qualcuno di voi se può leggere un po del mio codice per capire dove sto sbagliando.

L’ action del controller mi renderizza la vista con un findAll tramite CdBCriteria.

Questa è l’ action:




public function actionClienti()


	{ 

 $filiale_id = Yii::app()->user->filiale_id;


		$codice_fiscale='Assegna CF';


		$cr = new CDbCriteria();


        $cr->condition = 'filiale_id = :filiale_id AND status = :status AND codice_fiscale = :codice_fiscale';


		$cr->params = (array(':filiale_id' => $filiale_id, ':status'=>0, ':codice_fiscale'=>$codice_fiscale));

		

		$items = Missiva::model()->findAll($cr);

		

		$this->render('frontend/_assegna_codice_fiscale',array('items'=>$items));

		

		}



Vista _assegna_codice_fiscale:




<table class="tabella_login" style="width: 85%; margin: auto;">

		<tbody>

			<tr>

				<td colspan="5" class="tabella_info_header tabella_first_form">Assegnazione Codice Fiscale</td>

			</tr>

            

			<tr class="table_data_header">

            

			<td class="table_data_l" width="auto" style="font-weight:bold;">Nome - Cognome</td>

			<td class="table_data" width="auto" style="font-weight:bold;">Citta</td>

			<td class="table_data_r" width="auto" style="font-weight:bold;">Codice Fiscale</td>

           					</tr>


					

					

					

<tr id="table_data_content" align="center">

  <?php foreach($items as $i=>$item): ?> 


<?php echo CHtml::beginForm(); ?>    





        <td id="table_data" width="auto" style="text-align:left;">

	<?php 

	$nome_cognome = 

	 CHtml::encode($item->cliente_cognome. '   ' .$item->cliente_nome);

	 echo wordwrap ($nome_cognome,85, '<br />', true);

	 ?>

       </td>   

		<td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i]citta",array('value'=>$item->citta, 'name'=>'citta')); ?>

        </td>

		<td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i]codice_fiscale",array('value'=>$item->codice_fiscale, 'name'=>'codice_fiscale')); ?>

        </td>

		

		<td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i]cliente_id",array('value'=>$item->cliente_id, 'name'=>'cliente_id', 'id'=>'cliente_id')); ?>

        </td>


	 <?php endforeach; ?>

	 <tr class="tabella_info_footer">

	     <td colspan=5 class="tabella_chiusura_form">


<?php echo CHtml::submitButton('Salva',array('class'=>'btn btn-primary btn-small', 'submit'=>array('SaveAll')));?>

<?php echo CHtml::endForm(); ?>			 

			 </td>

          </tr>

      </tbody>

</table>



Questa è l’ actionSaveAll:




public function actionSaveAll()

{


    // retrieve items to be updated in a batch mode

    // assuming each item is of model class 'Item'

    $items=$this->getItemsToUpdate();

    if(isset($_POST['Missiva']))

    {

		

        $valid=true;

        foreach($items as $i=>$item)

        {

            if(isset($_POST['Missiva'][$i]))

                $item->attributes=$_POST['Missiva'][$i];

            $valid=$item->validate() && $valid;

        }

        if($valid) ; // all items are valid

            // ...do something here

    }

	  

	

    // displays the view to collect tabular input

    $this->render('frontend/_assegna_codice_fiscale',array('items'=>$items));

}



Questa è la funzione getItemsToUpdate():




public function getItemsToUpdate() {

	

	

        // Create an empty list of records

        $items = array();

 

        // Iterate over each item from the submitted form

        if (isset($_POST['Missiva']) && is_array($_POST['Missiva'])) {

			

            foreach ($_POST['Missiva'] as $item) {

                // If item id is available, read the record from database 

                if ( array_key_exists('id', $item) ){

                    $items[] = Missiva::model()->findByPk($item['cliente_id']);


                }

                // Otherwise create a new record

                else {

                    $items[] = new Missiva();

                }

            }

        }

		

        return $items;

    }



Perfavore qualcuno salvi il mio cervello!!! sto andando in depressione !!! :D Non riesco a fargli passare i parametri via post perchè non capisco come vada strutturata in questo senso l’ actionClienti. Credo l’ errore sia in questa action…ma non riesco a risolvere :( …Ho provato a fare il render della vista nella stessa actionSaveAll…ma non cambia nulla. E’ la seconda volta che provo il Tabular Input…già la prima volta avevo abbandonato perchè non mi riusciva. Ora vorrei riuscire a farlo funzionare…per questo vi chiedo un’ aiuto. Un Saluto.

Sicuramente un errore è nella view, perchè in beginForm è dopo l’inizio del ciclo così verranno creati tanti <form> quanti sono gli elementi dell’array, quando invece il form dev’essere uno solo.

Inoltre c’era anche un errore perchè chiudevi prima il ciclo e poi il form.

Quindi puoi cambiare questo




<tr id="table_data_content" align="center">

  <?php foreach($items as $i=>$item): ?> 


<?php echo CHtml::beginForm(); ?>   

....

....

....

         <?php endforeach; ?>

         <tr class="tabella_info_footer">

             <td colspan=5 class="tabella_chiusura_form">


<?php echo CHtml::submitButton('Salva',array('class'=>'btn btn-primary btn-small', 'submit'=>array('SaveAll')));?>

<?php echo CHtml::endForm(); ?>  



con




<tr id="table_data_content" align="center">

<?php echo CHtml::beginForm(); ?>   

  <?php foreach($items as $i=>$item): ?> 

....

....

....

         <?php endforeach; ?>

         <tr class="tabella_info_footer">

             <td colspan=5 class="tabella_chiusura_form">


<?php echo CHtml::submitButton('Salva',array('class'=>'btn btn-primary btn-small', 'submit'=>array('SaveAll')));?>

<?php echo CHtml::endForm(); ?> 




Ciao Fabrizio e grazie della tua pronta risposta. Avevo già provato a metterlo prima del ciclo …come dici tu…ma il risultato non cambia…non mi aggiorna i record con quello che inserisco nei campi activeTexfield. Quei campi restano invariati. E’ come se per $_POST non passasse nulla. Succede la stessa cose anche se faccio il render della vista dentro actionSaveAll.

OK, però lascia un unico form altrimenti non funzionerà mai.

Altra cosa, nell’actionSaveAll inserisci in testa un var_dump di $_REQUEST così

vedi cosa viene passato effettivamente al server e mettici subito dopo un exit;

così il programma termina subito.

Vedi cosa ti riporta.




public function actionSaveAll()

{

    var_dump($_REQUEST);

    exit;

}



I parametri passano :open_mouth:




array(5) { ["citta"]=> string(14) "Milano" ["codice_fiscale"]=> string(7) "GNPZTN45S10Z103C" ["cliente_id"]=> string(2) "34" ["yt0"]=> string(4) "Save" ["PHPSESSID"]=> string(26) "70qdln9v7btktlj2oajtpa68r2" }



Ma allora l’ errore dove diamine è ????

E la funzione che non passa i parametri…o sbaglio nel ricavarli nella stessa action SaveAll???

Passano in modo sbagliato, senza l’array contenitore ‘Missiva’ dei campi.

Infatti tu nell’action hai in testa




if (isset($_POST['Missiva']) && is_array($_POST['Missiva'])) {



ma i campi non vengono passati nella forma [‘Missiva’][‘codice_fiscale’], [‘Missiva’][‘citta’], eccc.

ma li stai passando con ‘codice_fiscale’, ‘citta’, ecc…, cioè senza array contenitore ‘Missiva’.

Quindi o rimuovi questo controllo in testa all’action (soluzione sbagliata), oppure aggiungi l’array contenitore ai campi (soluzione corretta).

Infatti hai ragione perchè ho notato adesso (facendo la prova con piu record visualizzati nella vista) che dal foreach prende solo l’ ultimo record e non tutti i record che la vista renderizza.

Scusami allora ma nella guida passa l’ array tramite is_array($_POST[‘Model’])… quindi come gli passo l’ array se quasta soluzione non è corretta ??? $_POST[‘Model’][‘attributo’] && $_POST[‘Model’][‘attributo’] ?? non l’ ho mai fatto!!! Ho sempre sfruttato la funzione loadModel tramite id…pero per evitare perdite di tempo volevo utilizzare il tabular che velocizza il processo di aggiornamento di piu dati.

Nel caso di un array di model, nella view i nomi dei campi devono essere nella forma:




<input name="Missiva[0][citta]" />

<input name="Missiva[0][codice_fiscale]" />

...

...

...

<input name="Missiva[1][citta]" />

<input name="Missiva[1][codice_fiscale]" />

...

...

...

<input name="Missiva[2][citta]" />

<input name="Missiva[2][codice_fiscale]" />

...

...

...



e questo lo puoi rendere con Yii facendo:




<?php echo $form->textField($model, '[0]citta'); ?>

<?php echo $form->textField($model, '[0]codice_fiscale'); ?>

...

...

<?php echo $form->textField($model, '[1]citta'); ?>

<?php echo $form->textField($model, '[1]codice_fiscale'); ?>



Oddio rinizi a incasinarmi il cervello :smiley:

nel mio caso quindi …questo




          <td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i]citta",array('value'=>$item->citta, 'name'=>'citta')); ?>

        </td>

                <td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i]codice_fiscale",array('value'=>$item->codice_fiscale, 'name'=>'codice_fiscale')); ?>

        </td>

                

                <td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i]cliente_id",array('value'=>$item->cliente_id, 'name'=>'cliente_id', 'id'=>'cliente_id')); ?>

        </td>



diventa:




          <td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i][0]citta",array('value'=>$item->citta, 'name'=>'citta')); ?>

        </td>

                <td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i][0]codice_fiscale",array('value'=>$item->codice_fiscale, 'name'=>'codice_fiscale')); ?>

        </td>

                

                <td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i][0]cliente_id",array('value'=>$item->cliente_id, 'name'=>'cliente_id', 'id'=>'cliente_id')); ?>

        </td>



giusto???

Poi il foreach ciclando aggiungera [1] - [2] etc a ogni campo ???

No era giusto come avevi fatto, solo che tu imposti manualmente il nome del campo, aggiungendo l’attributo name ad ogni activeTextField all’ultimo array, ovvero:




          <td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i]citta",array('value'=>$item->citta, 'name'=>'citta')); ?>

        </td>

                <td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i]codice_fiscale",array('value'=>$item->codice_fiscale, 'name'=>'codice_fiscale')); ?>

        </td>

                

                <td id="table_data" width="auto">

        <?php echo CHtml::activeTextField($item,"[$i]cliente_id",array('value'=>$item->cliente_id, 'name'=>'cliente_id', 'id'=>'cliente_id')); ?>

        </td>



Ma $item non è un model? Perchè non usi:




<?php echo $form->textField($item, "[$i]citta"); ?>

....



L’oggetto $form viene restituito nel beginForm all’inizio, ovvero:




<?php $form = CHtml::beginForm(); ?>

....



Si Fabrizio $item è un model…ho fatto cosi perchè stavo seguendo la guida.

Quando riusciro a farlo funzionare mettero i nomi che uso di solito.

Ancora una cosa poi ti faccio l’ assegno :D … non mi aggiorna i record :(

Sono contento :)

Eri contento :D … ho modificato il post perchè mi sono accorto che non funziona!!! :D non aggiorna i record del foreach.

Comunque sia ti ringrazio veramente dell’ aiuto che mi hai dato…intanto continuo a provare a far si che mi aggiorni i record nel databse.

Metti un validate() prima del salvataggio e poi fai un var_dump

di $model->errors, se $model è la variabile del modello che stai salvando.

Probabilmente è solo un problema di validazione che non passa.

Ora posso dire grazie veramente di cuore a Fabrizio Caldarelli per la sua pazienza :)

Avevo dimenticato il save per salvare il modello :D

In più grazie alle tue delucidazioni adesso sono riuscito anche a fare l’ update dei record tramite altri parametri su altri Model, partendo dall’ array che ricevo dalla funzione getItemToUpdate() e creandomi altre funzioni che mi riportino i parametri che mi servono anche tramite findAllByAttributes.

Quindi mi hai veramente fatto felice come un bambino che riceve il regalo che tanto aveva desiderato :D

Grazie per aver arricchito le mie misere conoscenze di questo Framework e per avermi sbrogliato una situazione sulla quale perdevo tempo e masticavo nervi da un po di settimane.

Grazie ancora di tutto!!!! :) Un Saluto