Yii Framework Forum: Mini tutorial - CGridView / CRUD / CJuiDialog - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Mini tutorial - CGridView / CRUD / CJuiDialog Mini tutorial - CGridView e gestione delle CRUD in un CJuiDialog Rate Topic: -----

#1 User is offline   d4rkstar 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 21
  • Joined: 19-February 11
  • Location:Naples / Italy

Posted 10 March 2011 - 06:09 PM

Ciao a tutti, ho deciso di raccontarvi la mia prima esperienza con questo MVC ed un tentativo (abbastanza) riuscito di gestire le operazioni di CRUD dalla CGridView tramite un CJuiDialog.

La mia tecnica parte dalla generazione del codice con GII e sembra lasciare intatta la validazione ajax delle form ed è abbastanza semplice da implementare. Ho cercato di rendere, dove possibile, il codice generico.

Attendo vostri commenti. Sarei felice se collabboraste al perfezionamento di questo codice al fine di trasformare questo mini tutorial in una pagina del wiki.

Bruno

Let's go. Dopo aver generato il codice con GII, assumo che il modello si chiami MyModel

---------------------------------------------------------------------------------
Nel controller MyModelController:
---------------------------------------------------------------------------------
Esempio di azione per la creazione di un nuovo elemento da modello:

	public function actionCreate()
	{
		$model=new MyModel;

		$this->performAjaxValidation($model);
		if(isset($_POST['MyModel']))
		{
			$model->attributes=$_POST['AdsList'];
			$result = $model->save();
			if (Yii::app()->request->isAjaxRequest)
            {
            	echo $result ? "ok" : "ko";
            	exit();
            }
            else 
            {
				$this->redirect(array('view','id'=>$model->id));					
			}
			 
				
		} 
		if (Yii::app()->request->isAjaxRequest) 
        {
			$this->renderPartial('_create_dialog', array('model'=>$model),false,false);
        } 
        else 
        {
			$this->render('create',array('model'=>$model));
		}
	}


---------------------------------------------------------------------------------
Vista _create_dialog da creare all'interno della cartella delle viste
relative al modello in oggetto (es. views/MyModel/_create_dialog.php)
---------------------------------------------------------------------------------
Esempio di azione per la creazione di un nuovo elemento da modello:

<?php
// Questa riga la devo a psikocrisis!!!
Yii::app()->clientScript->scriptMap=array(
         //scripts that you don't need inside this view
        'jquery.js'=>false,       
);
$this->beginWidget('zii.widgets.jui.CJuiDialog',array(
                'id'=>'createDialog',
                'options'=>array(
                    'title'=>Yii::t('app','Create New Record'),
                    'autoOpen'=>true,  // naturalmente apriamo il dialog dopo il rendering
                    'modal'=>'true',  // finestra di modifica modale
                    'width'=>'640', // qui possiamo scegliere le dimensioni che ci gustano
                    'height'=>'500', // qui possiamo scegliere le dimensioni che ci gustano
                    'buttons'=>array(
                    	Yii::t('app','Save')=>'js:function() { submitForm(this) }',
                    	Yii::t('app','Close')=>'js:function() { $(this).dialog("close"); }'
                    	), // Notare i bottoni di SAVE e CLOSE :):):)
                    'close'=>'js:function() {  $(this).html(""); updateGrid() }' // sul salva aggiorna la grid
                ),
                
                ));

// questo renderizza la nostra classica form :)
echo $this->renderPartial('_form', array('model'=>$model),false,true); 

$this->endWidget('zii.widgets.jui.CJuiDialog');

?>


---------------------------------------------------------------------------------
Nel file della vista principale, dove viene renderizzata normalmente la
CGridView, ossia admin.php, abbiamo una serie di accorgimenti semplicissimi:
---------------------------------------------------------------------------------
A ) Dove viene registrato il javascript della ricerca:

Yii::app()->clientScript->registerScript('refreshbtn', "
$('#refresh-button').click(function(){
	$.fn.yiiGridView.update('ads-list-grid');
});
");


B ) A fianco del link che apre la ricerca avanzata metto un altro link per il
refresh della grid che richiama lo script al punto A)

<?php echo CHtml::link(Yii::t('app','Refresh'),'#',array('id'=>'refresh-button')); ?>&nbsp;


C ) Subito dopo questo link, ne aggiungo un altro per la creazione di un record:

<?php 
	echo CHtml::ajaxLink(Yii::t('app','Add New'),
		Yii::app()->createUrl("MyModel/create"),
		array(
			'type'=>'POST',
			'url'=>'js:$(this).attr("href")',
			'update'=>'#updatediv', // il target della chiamata ajax è un div che mettiamo a fine pagina
			'cache'=>'false'
		),		
		array('id'=>'new-button')); 
?>


D ) Modifica alla riga di codice predefinita che crea la CGridView:

	$grid = $this->widget('zii.widgets.grid.CGridView', array(


questa modifica serve per poter avere in $grid il widget e poter utilizzare del
codice generico nelle fasi successive:

E ) A fine pagina, inserire il seguente codice che serve per forzare l'update della
grid e per inserire nella pagina il DIV target delle chiamate per la creazione del
dialog:


<?php 
Yii::app()->clientScript->registerScript('updatedivscript','
function updateGrid() {
	$.fn.yiiGridView.update("' . $grid->id . '");
}',CClientScript::POS_END);
?>
<div id="updatediv"></div>	


---------------------------------------------------------------------------------
Modifiche al file della vista _form presente in views/MyModel/_form.php
---------------------------------------------------------------------------------
A ) In testa alla form:

<?php 

	$form=$this->beginWidget('CActiveForm', array(
	'id'=>'mymodel-list-form',
	'enableAjaxValidation' => true,	
	'clientOptions'=>array(
      'validateOnSubmit'=>false,
      'validateOnChange'=>true,
   ),
));

// Script per gestire l'invio dei dati della form al controller in modalità
// ajax ed eventualmente chiudere il form dopo il salvataggio o mostrare gli 
// errori di validazione.
Yii::app()->clientScript->registerScript($form->id . "-submit",'
function submitForm(dlg) {' .
	CHtml::ajax(array(
					'type'=>'POST',
					'cache'=>'false',
					'data'=>'js:$("form#'. $form->id . '").serialize()',
					'url'=>Yii::app()->request->requestUri,
					'success'=>'js:function(data) { if (data=="ok") { $(dlg).dialog("close"); return false; } else { alert("Error: " + data);} }'
                    )
				).'
}');


B ) Eliminare la row con i bottoni di salvataggio generati da GII


Per gestire la modifica, la tecnica è uguale. Basta modificare - in modo simile alla create - l'azione di update ed implementare le relative viste in modo affine a quanto visto sopra.
Magari è utile modificare il bottone della modifica nella CGridView, modificando il codice di default con questo snippet:

$grid = $this->widget('zii.widgets.grid.CGridView', array(
	'id'=>'mymodel-list-grid',
	'dataProvider'=>$model->search(),
	'filter'=>$model,
	'columns'=>array(
[...]
	),
	array
	(
		'class'=>'CButtonColumn',
		'template' => '{update} {delete}',
		'buttons'=>array(
			'update'=>array (
				'url'=> 'Yii::app()->createUrl("myModel/update", array("id" => $data->id))',
				'options'=>array (
					'ajax'=>array(
						'type'=>'POST',
						'url'=>'js:$(this).attr("href")',
						'update'=>'#updatediv',
						'cache'=>'false'
					),
				),
			),
		),
	),
);


Questo è quanto. Attendo speranzoso vostre idee / suggerimenti...
1

#2 User is offline   dchan 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 32
  • Joined: 28-March 11
  • Location:Italy

Posted 17 April 2011 - 04:57 PM

Grazie del post.
Volevo proprio provare ad implementare qualche cosa del genere. Farò delle prove e ti darò un riscontro.
0

#3 User is offline   zaccaria 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 2,232
  • Joined: 04-October 09
  • Location:Moscow

Posted 18 April 2011 - 01:10 AM

Dai una occhiata a questa wiki.

In particolare c'e' un suggerimento suggerimento di cui puoi fare tesoro:

1) usa

 $('#dialogClassroom div.divForForm form').submit(someFunction);


In sostanza, dopo l'update assegna una funzione al submit della form in questa maniera, altri sistemi non funzionano con Opera.
0

#4 User is offline   d4rkstar 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 21
  • Joined: 19-February 11
  • Location:Naples / Italy

Posted 19 April 2011 - 03:08 PM

View Postzaccaria, on 18 April 2011 - 01:10 AM, said:

Dai una occhiata a questa wiki.

In particolare c'e' un suggerimento suggerimento di cui puoi fare tesoro:

1) usa

 $('#dialogClassroom div.divForForm form').submit(someFunction);


In sostanza, dopo l'update assegna una funzione al submit della form in questa maniera, altri sistemi non funzionano con Opera.


Ciao Zac,
in realtà sono andato un pò oltre, anche se non ho aggiornato questo topic :) In effetti mi sono accorto che il mio codice non consentiva la validazione della form, cosa che può essere gestita sostituendo il codice della submitForm con quest'altro:

Yii::app()->clientScript->registerScript($form->id . "-submit",'
function submitForm(dlg) {
	' .
	CHtml::ajax(array(
		'type'=>'POST',
		'cache'=>'false',
		'dataType'=>'json',
		'data'=>'js:$("form#'. $form->id . '").serialize()+"&ajax='. $form->id . '"',
		'url'=>Yii::app()->request->requestUri,
		'success'=>'js:function(data) { 
			if (data!="") {
				if (data != null && typeof data == "object"){
					$.each(data, function(key, value) {
						$("#" + key).addClass("error");
						$("#" + key + "_em_").html(value[0]);
						$("#" + key + "_em_").show();
			        	});
				}
			} else {
				$.post("' . Yii::app()->request->requestUri . '",  $("form#'. $form->id . '").serialize(),
					function(res) {
						if (res.result=="ok") {
							$(dlg).dialog("close"); return false;
						}
					},"json");
			}
		}',
		'error'=>'js:function(jqXHR, textStatus,errorThrown) {  
				secondaryDialog("' . Yii::t('app','Application Error') . '", jqXHR.responseText); 
			}',
        )
	).'
}');
?>


In pratica la funzione di submit prova prima la validazione. Nel caso in cui la validazione non restituisce errori, viene fatta una POST. La post restituisce un oggetto json. Se il risultato è OK la finestra di dialogo viene chiusa. In alternativa si può eseguire il codice che si ritiene più opportuno.

Le azioni del controller vanno poi riviste in quanto devono restituire un oggetto JSON:

public function actionCreate() {
// ...
	if (Yii::app()->request->isAjaxRequest) {
		$res = new stdClass();
		$res->result = ($result ? "ok" : "ko");
		echo json_encode($res);
		Yii::app()->end();
	}
// ...
}

Ci sono anche altri punti che devo migliorare e riportare sul forum.. spero di riuscirlo a fare quanto prima!!
0

#5 User is offline   zaccaria 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 2,232
  • Joined: 04-October 09
  • Location:Moscow

Posted 21 April 2011 - 12:54 AM

Dai una occhiata alla wiki: stai seguendo lo stesso percorso che ho fatto io, credo che risparmierai un sacco di tempo con una breve lettura.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users