Widget Con Validazione Ajax

Salve ragazzi, ho sviluppato alcuni widget che mostrano dei form.

Effettuo il submit di questi form con il pulsante creato mediante: CHtml::htmlButton dove con il parametro submit imposto il controller e l’action che deve andare ad eseguire.

Siccome che l’azione è riutilizzabile in più contesti(è utilizzata nel submit di più widget dove cambia solo il nome tabella e alcuni attributi) ho creato dentro la cartella components -> actions la mia azione: "class newRecord extends CAction ".

Caricando poi nel singolo controller / action specifico i parametri che servono di volta in volta utilizzando questo sistema:

public function actions(){


	return array(


		'azione.'=>array(


				'class'=>'widgets.site.MyWidget',


				'newRecord'=>array(


						'model'=>'MioModello',


						'form'=>'MioForm',


						'url_redirect'=>Yii::app()->getRequest()->getUrlReferrer(), /*per tornare dopo il submit alla pagina che ha generato il submit*/


				),


		),


	);


}

Il problema sta nel tornare alla pagina che ha generato il submit mantenendo gli errori che il model ha riscontrato durante il salvataggio. Siccome che non li mantiene, prima del redirect faccio un setFlash inserendo un’errore generico del form, ma così perdo quella bella funzionalità di Yii che mi permette di mettere in evidenza un campo input in rosso come errato.

In pratica dovrei eseguire il controller e l’action che hanno generato la pagina precedente al submit.

Che mi consigliate di fare?

Salve ragazzi credo di aver risolto in parte, e pubblicherò poi la soluzione.

Ma per concludere la questione avrei bisogno di sapere se è possibile passare delle variabili, nel mio caso il model, ad una azione (utilizzando un widget come action provider) o una specie di variabile globale,esiste qualche sistema?

Ho notato che l’unico sistema valido per assegnare un valore ad una variabile , come segnalato in questo articolo, è il medesimo ‘property1’=>‘value1’.

Se assegno una variabile pubblica del controller e poi la passo come value1 non la trovo valorizzata all’interno della action come se non fosse stata inizializzata. Se invece passo un valore di sistema come ad esempio l’url corrente ( Yii::app()->getRequest()->getUrlReferrer() ) all’interno della mia azione leggo il valore corretto dell’url e per questo ho parlato precedentemente di variabile globale. Ma l’unico sistema credo sia quello di inserire un’oggetto in una variabile di sessione e non credo sia una buona soluzione.

Mi sono un po arrovellato sulla questione per giungere al capo della matassa, anche se ho provato una soluzione alternativa che prevede all’interno del widget il richiamo di una funzione solo se è presente la validazione ajax, il codice è il seguente:

	$model = new MioModello; 


	if (Yii::app()->request->isAjaxRequest){


		$model = Functions::newRecord($model, 'ModelName', 'MioForm');


		echo CActiveForm::validate($model);


		//Yii::app()->end();


	}


	$this->render('_MiaVista',array('name'=>$this->name,'model'=>$model/*,'url_current'=>$this->url_current*/));

Così facendo all’interno dell’oggetto $model trovo anche l’errore che mi interessa poi mostrare in front end. Ora mi resta solo di capire come far illuminare il campo input come errato e visualizzare il relativo errore in prossimità di quell’input. Avete suggerimenti?

Mi accodo a questa vecchia discussione perchè mi interessa anche a me: come si fa a far eseguire una action che si trova dentro ad un widget? non ho capito.

C’è un ottimo wiki per il riutilizzo di actions qui

Non condivido però l’utilizzo di un widget con connotati di logica applicativa (almeno questo sembra voler essere).

Un widget va utilizzato per generare elementi di interfaccia grafica complessi e non ,da iniettare nelle “viste”, con la potenza dell’approccio object oriented.

Dunque non capisco perchè non utilizzare il widget direttamente nella vista.

Era per tenere ‘racchiuso’ il codice legato ad una funzione particolare.

Immagina di avere su una colonna di un blog un widget per iscriversi alla ricezione email.

Quando l’utente preme ‘ok’, il widget dovrebbe via ajax ricevere la richiesta e aggiornarsi di conseguenza.

Capisco che si può prevedere che la parte logica la faccia un controller, ma se questo widget viene messo in diversi moduli, si dovrà ricorrere ad una classe CACtion e poi usare ‘actions()’ per far si che i vari controller coinvolti la usino.

Se fosse possibile che il widget abbia anche la propria parte di logica, sarebbe tutto piu plug-and-play, spece se il widget viene condiviso tra progetti, invece così deve installlare l’extension, installare l’action, dichiarare l’action o le action da usare dentro a ciascun controller … insomma, una rottura.

In alternativa ci sarebbe predichiarare un controller che risponda al widget, ma mi sembra ancora piu sporca.