Update Record In Una View

Ho una view di un dettaglio: http://www.miosito/applicazione/offerte/view/139.html

al suo interno ho un pulsante o un link “mipiace”, al suo click il campo del database chiamato likeme…dovrebbe essere aggiornato con il suo attuale valore + 1.Ho creato nel controller offerte l’azione:




public function actionLike($id)

	{

		$model=$this->loadModel($id);


		$post=Offerte::model()->findByPk($id);

		$post->likeme= $post->likeme + 1;

		$post->save(); // save the change to database


				$this->redirect(array('view','id'=>$model->id));

		


	}



nelle access rules ho aggiunto like

poi nella view:


<?php


echo CHtml::ajaxSubmitButton(


    'Mi piace',


    array('offerte/like'),


);

?>

ma non funziona…non esegue l’azione secondo me, invece con il delete


       <?php echo CHtml::link('Elimina','#',array('submit'=>array('offerte/delete','id'=>$value->id),'confirm'=>'Vuoi eliminare questa Offerta?'));?>



mi manca un parametro?

io tendo a farle a mano queste cose. cioè creo uno span e via jquery faccio un




$.ajax (

 ...

).done(

   $(selettore).html(risultato_dell'_echo_della_action)

)




Praticamente io farei finire l’actionLike con un renderPartial del solo pulsante.

Ora vedo di documentarmi sui metodi ajax*

ok, vai qui: http://www.yiiframework.com/doc/api/1.1/CHtml#ajaxSubmitButton-detail

vedi, il parametro che ti manca è il più importante: quello che definisce il comportamento della chiamata ajax

e qui la documentazione di come impostarlo: http://www.yiiframework.com/doc/api/1.1/CHtml#ajax-detail

per esempio potresti provare [scusa ma non ho codice ‘aperto’ per esperimenti sotto mano] così:

Avendo ipoteticamente




<span id="like_btn_container">

    <button>18</button>

</span>


[code]


echo CHtml::ajaxSubmitButton(


    'Mi piace',


    array('offerte/like'),


    array('update' => '#like_btn_container')


);



A quel punto l’actionLike deve, come dicevo sopra, terminare con




$this->renderPartial('pulsante_aggiornato_e_basta_senza_lo_span_esterno', array(

  'like_count' => $like_count.

));



dove pulsante_aggiornato_e_basta_senza_lo_span_esterno.php è




 <button><?=$like_count?></button>



e NON fare alcun redirect.

Ho provato ma senza risultato…,ho letto anche la documentazione sembra essere tutto ok…

view:





<!-- al posto di "18", inserirei il campo del db con il valore.. ossia: $model->likeme -->

<span id="like_btn_container">

    <button>18</button>

</span>


<?php


echo CHtml::ajaxSubmitButton(


    'Mi piace',


    array('offerte/like'),


    array('update' => '#like_btn_container')


);

?>



controller:




public function actionLike($id)

	{

		$model=$this->loadModel($id);


		$post=Offerte::model()->findByPk($id);

		$post->likeme= $post->likeme + 1;

		$like_count = $post->likeme;

		$post->save(); // save the change to database


		$this->renderPartial('_mipiace', array(

  		'likeme' => $like_count,'id'=>$model->id

		));


		

			

				//$this->redirect(array('view','id'=>$model->id));

		


	}



view _mipiace




<button><?php $like_count ?></button>



però non esegue nulla

1° la renderPartial passa la variabile $likeme, ma tu la cerchi come $like_count.

Se non sai questa cosa di Yii te la spiego ora: l’array associativo che passi a render o a renderPartial.crea delle variabili per la view con il nome che tu hai scelto come chiave, e gli da come valore quello passato

così


'likeme' => '$lke_count' 

passa alla view il VALORE $like_count ma COL NOME $likeme

per cui questo è sbagliato


<button><?php $like_count ?></button>

e questo è corretto


<button><?php $likeme ?></button>

E’ buona norma NON cambiare nome alle variabili nel passarle alla view; agevola il debug

2° qui si tratta di fare un po di debug di base .

Abilita con ini_set("display_errors","on") la visualizzazione degli errori, fa comodo…

se non lo stai facendo, usa firefox con firebug. Apri il pannello console e il pannello net, abilitati, ricarica la pagina e guarda cosa succede dietro le quinte. console ti dice eventuali errori js, il pannello net invece segue la chiamata ajax (clicca su xhr per la precisione)

3° Sai vero che yii logga gli errori nei file dentro a protected/runtime ? Controlla specie application.log.

Se non c’è scritto nulla nei file di log, che è strano, posa la configurazione delle tue rotte di log [le trovi nel config/main.php].

Lo dico perchè così come è scritto, php DEVE darti un errore di variabile non trovata; solo che è un warning, non è un error. per cui questo errori lo trovi dentro all’application.log [o almeno dovresti], e quindi per questo ti ho consigliato di attivare, in sviluppo, la visualizzazione a video degli errori. Così Yii ‘ti sputa’ addosso gli errori, ed aiuta veramente molto.

Mi puoi postare anche l’action che renderizza la prima view per favore?

E magari anche, dal sorgente html della pagina, il pezzo di js che yii ha generato per l’ajax? E’ quasi certamente in fondo

La view che contiene il tutto è questa




public function actionView($id)

	{




		$this->render('view',array(

			'model'=>$this->loadModel($id),

		));






<script type="text/javascript">

/*<![CDATA[*/

jQuery(function($) {

jQuery('body').on('click','#yt0',function(){jQuery.ajax({'type':'POST','url':'/Macerataemraz/offerte/like.html','cache':false,'data':jQuery(this).parents("form").serialize(),'success':function(html){jQuery("#like_btn_container").html(html)}});return false;});

});

/*]]>*/

</script> 



si il file di log lo crea

mi da un errore firebug: "NetworkError: 400 Bad Request

e in xhr:dopo che clicco…non fa richieste

ottimo ! allora, bad request, in genere è un errore di parametri non passati, o con nome diverso da quelli previsti.

Nota: non è firebug, è proprio yii che genera un errore di quel tipo, e firebug ubbidientemente te lo mostra

esempio: se io ho una actionProva(parametro1, parametro2)

tuti questi casi generano errore

  • chiamo actionProva via POST invece che via GET

  • uno o entrambi i parametri sono mancanti

  • uno o entrambi i parametri hanno nomi diversi ( es: ../prova&par1=bla&par2=bau )

… e forse altri casi

La tua actionLike si aspetta UNA GET (perchè ha dei parametri), quindi dentro la configurazione dell’ajax ci devi mettere “type” => “GET”

Controlla (eventualmente usando Yii::log o Yii::trace il contenuto di $_GET) e copia/incolla qui come arriva su dal javascript. Cioè, per esempio:




Yii::trace(print_r($_GET,true));



Dovresti trovare l’output in trace.log o in application.log, non ricordo più le impostazioni predefinite di routing dei log

e poi devi dargli un unico parametro (data) cioè id, e si deve per forza chiamare id

controller:




public function actionLike($id)

        {

                $model=$this->loadModel($id);


                $post=Offerte::model()->findByPk($id);

                $post->likeme= $post->likeme + 1;

                $like_count = $post->likeme;

                $post->save(); // save the change to database


                $this->renderPartial('_mipiace', array(

                'likeme' => $like_count,'id'=>$model->id

                ));


                

                        

                                //$this->redirect(array('view','id'=>$model->id));

                


        }



view _mipiace




<button><?php echo $likeme ?></button>



view principale




<?php


echo CHtml::ajaxSubmitButton(


    'Mi piace',

    array('offerte/like',

          'type'=>'GET',),

    array('update' => '#like_btn_container')


);


Yii::trace(print_r($_GET,true));


?>



script generato: anche se mi iposta di default sempre POST…come si vede all’inizio ???




<script type="text/javascript">

/*<![CDATA[*/

jQuery(function($) {

jQuery('body').on('click','#yt0',function(){jQuery.ajax({'type':'POST','url':'/Applicazione/offerte/like.html?type=GET','cache':false,'data':jQuery(this).parents("form").serialize(),'success':function(html){jQuery("#like_btn_container").html(html)}});return false;});

});

/*]]>*/

</script>



application.log




REQUEST_URI=/applicazione/offerte/view/undefined

HTTP_REFERER=http://miosito.com/Applicazione/offerte/view/139.html



controllando da firebug non effettua chiamata, mi sto perdendo :(




<?php

    echo CHtml::ajaxButton(

                'Save',

                array('offerte/like'),

                array('data'=>array(

                                 'id'=>$model->id,

                                 'likeme'=>'js:$("#likeme").val()'),

                                 

                             

                       'type'=>'GET'

                    ));

            ?>


<div id="likeme">aggiornami </div>



lo script generato ora pare avere tutti i parametri…,ma l update non viene fatto…, non è che può esserci un conflitto di jquery??




<script type="text/javascript">

/*<![CDATA[*/

jQuery(function($) {

jQuery('body').on('click','#yt0',function(){jQuery.ajax({'data':{'id':'139','likeme':$("#likeme").val()},'type':'GET','url':'/sites/Applicazione/offerte/like.html','cache':false});return false;});

});

/*]]>*/

</script>