Dunque dunque dunque…
Prima cosa: inutile fare tanti casini se le soluzioni sono già lì belle e fatte.
Seconda cosa: cerca prima di fare
(dalle regole del perfetto newbie… )
Studiando le specifiche e gli articoli di gridview ho trovato che posso aprire in dialog-mode sia la view che l’update.
Pertanto vi posto le modifiche fatte per avere, per ogni tab (al momento indirizzi, iban, contatti) un link Nuovo che mi apre il popup di creazione del nuovo campo messo in alto alla barra della gridview, le icone view e update mi aprono i popup di cui sopra, in dialog-mode.
Questa volta il form lo invio via post al controller adeguato che se è tutto a posta mi fa un redirect alla pagina di prima, se sbagliato mi salva nella sessione dell’utente gli errori e io li mostro con il flash sulla pagina.
(vero, usando il POST ricarico la pagina sia se il form è ok sia se no… ma pazienza)
particolarità: Ho dovuto 1: registrare il core script jui
$cs = Yii::app()->getClientScript();
$cs->packages = array(
'jquery.ui'=>array(
'js'=>array('jui/js/jquery-ui.min.js'),
'css'=>array('jui/css/base/jquery-ui.css'),
'depends'=>array('jquery'),
),
);
$cs->registerCoreScript('jquery.ui');
impostare la mia funzione scrivierrori perché scrivesse sulla sessione dell’utente
static function scrivierrori($model) {
$text='';
foreach ($model->errors as $key=>$val) {
$text.= '<b>'.$model->getAttributeLabel ($key).':</b><ul> ';
foreach ($val as $error) {
$text.= '<li>'.$error.'</li>';
}
$text.= '</ul>';
}
Yii::app()->user->setstate('errori',$text);
}
e modificare il file jquerycombobox di una estensione che causava conflitti.
pertanto ecco il mio punto d’arrivo:
IndirizziController:
<?php
class IndirizziController extends Controller {
/**
* @var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
public $layout = '//layouts/column1';
/**
* @return array action filters
*/
public function filters() {
return array(
'accessControl', // perform access control for CRUD operations
);
}
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
* @return array access control rules
*/
public function accessRules() {
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions' => array('index', 'view'),
'users' => array('@')
),
array('allow', // allow all users to perform 'index' and 'view' actions
'actions' => array('autocompleteComune'),
'users' => array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions' => array('create', 'update'),
'users' => array('@'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions' => array('admin', 'delete'),
'users' => array('@'),
),
array('deny', // deny all users
'users' => array('*'),
),
);
}
/**
* Displays a particular model.
* @param integer $id the ID of the model to be displayed
*/
public function actionView($id) {
if (Yii::app()->request->isAjaxRequest)
{
$this->renderPartial('view', array(
'model'=>$this->loadModel($id),
'asDialog'=>!empty($_GET['asDialog']),
),
false,true);
Yii::app()->end();
}
else
$this->render('_view', array(
'model'=>$this->loadModel($id),
));
}
/**
* Creates a new model.
* If creation is successful, the browser will be redirected to the 'view' page.
*/
public function actionCreate() {
$model = new Indirizzo();
if (Yii::app()->input->get('anagra_id')) $model->anagra_id=Yii::app()->input->get('anagra_id');
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['Indirizzi'])) {
$new_ind= Yii::app()->input->post('Indirizzi');
$model->attributes = $_POST['Indirizzi'];
if ($new_ind['tipo_search'] != '') {
//cerco se il tipo è gia esistente
$tipo = TipoIndirizzo::model()->find('descri LIKE "' . $new_ind['tipo_search'] . '"');
if ($tipo->id)
{$model->tipo = $tipo->id;}
else {
$tipo = new TipoIndirizzo();
$tipo->descri = $new_ind['tipo_search'];
//abbreviazione
$to = explode(' ', $tipo->descri);
if (count($to) == 1) {
echo $tipo->abbr = strtoupper(ucfirst(substr($tipo->descri, 0, 3)));
} else {
for ($i = 0; $i < 3; $i++) {
echo $tipo->abbr.= strtoupper(substr($to[$i], 0, 1));
}
}
//fine abbreviazione
$tipo->user_id = Yii::app()->user->user_id;
if(!$tipo->save())
{
Gazie_general::scrivierrori($tipo);
}else
$model->tipo = $tipo->id;
}
}
if ($model->posta=='on')$model->posta=1;
$from= Yii::app()->input->post('from');
$url=Yii::app()->createUrl($from['module'].'/'.$from['controller'].'/'.$from['action'],array('active'=>'indirizzi','id'=>$from['id_base']));
if(!$model->save())
{
Gazie_general::scrivierrori($model);
}
$this->redirect($url);
exit();
}
$tipo = new TipoIndirizzo();
$this->renderPartial('_form', array(
'model' => $model
,'asDialog'=>!empty($_GET['asDialog'])
,'from'=> Yii::app()->input->get('from')
));
}
/**
* Updates a particular model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id the ID of the model to be updated
*/
public function actionUpdate($id) {
$model = $this->loadModel($id);
if (isset($_POST['Indirizzi'])) {
$model->attributes = $_POST['Indirizzi'];
if (isset($_POST['Indirizzi'])) {
$new_ind= Yii::app()->input->post('Indirizzi');
$model->attributes = $_POST['Indirizzi'];
if ($new_ind['tipo_search'] != '') {
//cerco se il tipo è gia esistente
$tipo = TipoIndirizzo::model()->find('descri LIKE "' . $new_ind['tipo_search'] . '"');
if ($tipo->id)
{$model->tipo = $tipo->id;}
else {
$tipo = new TipoIndirizzo();
$tipo->descri = $new_ind['tipo_search'];
//abbreviazione
$to = explode(' ', $tipo->descri);
if (count($to) == 1) {
echo $tipo->abbr = strtoupper(ucfirst(substr($tipo->descri, 0, 3)));
} else {
for ($i = 0; $i < 3; $i++) {
echo $tipo->abbr.= strtoupper(substr($to[$i], 0, 1));
}
}
//fine abbreviazione
$tipo->user_id = Yii::app()->user->user_id;
if(!$tipo->save())
{
Gazie_general::scrivierrori($tipo);
}else
$model->tipo = $tipo->id;
}
}
if(!$model->save())
{
Gazie_general::scrivierrori($model);
}
else{ echo 'ok';}
exit();
}
}
else {
if (Yii::app()->request->isAjaxRequest)
{
$this->renderPartial('_form', array(
'model'=>$model,
'asDialog'=>!empty($_GET['asDialog']),
),
false,true);
Yii::app()->end();
}
else{
$this->render('update', array(
'model'=>$model
));
}}
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
}
/**
* Deletes a particular model.
* If deletion is successful, the browser will be redirected to the 'admin' page.
* @param integer $id the ID of the model to be deleted
*/
public function actionDelete($id) {
if (Yii::app()->request->isPostRequest) {
// we only allow deletion via POST request
$this->loadModel($id)->delete();
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
if (!isset($_GET['ajax']))
$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
}
else
throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
}
/**
* Lists all models.
*/
public function actionIndex() {
$dataProvider = new CActiveDataProvider('Indirizzo');
$this->render('index', array(
'dataProvider' => $dataProvider,
));
}
/**
* Manages all models.
*/
public function actionAdmin() {
$model = new Indirizzo('search');
$model->unsetAttributes(); // clear any default values
if (isset($_GET['Indirizzi']))
$model->attributes = $_GET['Indirizzi'];
$this->render('admin', array(
'model' => $model,
));
}
/**
* Returns the data model based on the primary key given in the GET variable.
* If the data model is not found, an HTTP exception will be raised.
* @param integer the ID of the model to be loaded
*/
public function loadModel($id) {
$model = Indirizzo::model()->findByPk($id);
if ($model === null)
throw new CHttpException(404, 'The requested page does not exist.');
return $model;
}
/**
* Performs the AJAX validation.
* @param CModel the model to be validated
*/
protected function performAjaxValidation($model) {
if (isset($_POST['ajax']) && $_POST['ajax'] === 'anagra-indirizzi-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
function ActionAutocompleteComune() {
//a breve lo cambiamo con GOOGLE, più preciso e meno spazio sul DB
$res = array();
if (isset($_GET['term'])) {
$qtxt = 'SELECT c.postal_code as cap,c.name as com_name, p.abbr,r.iso_country AS iso
FROM {{municipalities}} AS c
LEFT JOIN {{prov}} as p ON p.id=c.id_province
LEFT JOIN {{regions}} as r ON r.id=p.id_region
WHERE c.name LIKE :nome';
$command = Yii::app()->db->createCommand($qtxt);
$command->bindValue(":nome", '%' . $_GET['term'] . '%', PDO::PARAM_STR);
$res = $command->queryAll();
foreach ($res as $p) {
$results[] = array(
'label' => $p['com_name']
, 'value' => $p['com_name']
, 'cap' => $p['cap']
, 'prov' => $p['abbr']
, 'country_iso' => $p['iso']
);
}
}
echo CJSON::encode($results);
Yii::app()->end();
}
}
la tab indirizzi
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'address-grid',
'dataProvider' => $indirizzi,
'columns' => array(
'ind'
, 'com'
, 'prov'
, array(
'class' => 'CButtonColumn',
'header' => '<span id="new_indirizzo" name="new_indirizzo">Nuovo</span>',
'deleteButtonUrl'=>'Yii::app()->createUrl("/anagra/Indirizzi/delete",array("id"=>$data->id))'
,'buttons' => array(
'view' =>
array(
'url' => 'Yii::app()->createUrl("/anagra/Indirizzi/view", array("id"=>$data->id,"asDialog"=>1))',
'options' => array(
'ajax' => array(
'type' => 'POST',
// ajax post will use 'url' specified above
'url' => "js:$(this).attr('href')",
'update' => '#add_window',
),
),
),
'update' =>
array(
'url' => 'Yii::app()->createUrl("/anagra/Indirizzi/update", array("id"=>$data->id,"asDialog"=>1))',
'options' => array(
'ajax' => array(
'type' => 'POST',
// ajax post will use 'url' specified above
'url' => "js:$(this).attr('href')",
'update' => '#add_window',
),
),
)
)
),
),
));
$from['controller']= Yii::app()->controller->id;
$from['action']=Yii::app()->controller->getAction()->getId();
$from['module']=Yii::app()->controller->module->getId();
$from['id_base']=$anagra_id;
$scr = "
$('#new_indirizzo').button().click(function(){
$.ajax({
type:'GET',
url :'" . Yii::app()->createUrl('/anagra/Indirizzi/create',array('anagra_id'=>$anagra_id,'from'=>$from)) . "',
success: function(html){
apriAddWind(html,'Nuovo indirizzo');
}
})
})
";
Yii::app()->clientScript->registerScript('indirizzi_script', $scr);
//----------- add the div below as container for the dialog -----------------------
?>
il mio _form di indirizzi:
<?php
if (!empty($asDialog)) {
$this->beginWidget('zii.widgets.jui.CJuiDialog', array(// the dialog
'id' => 'dlg-address-view-' . $model->id,
'options' => array(
'title' => 'Modifica Indirizzo',
'autoOpen' => true,
'modal' => true,
'width' => 800,
'height' => 470,
),
));
}
?>
<form name="invio_indirizzo" method="POST" action="<?php echo Yii::app()->createUrl("/anagra/Indirizzi/create",array('anagra_id'=>$anagra_id)); ?>">
<table>
<tbody>
<tr>
<td><?php echo $model->getAttributeLabel('ind'); ?></td>
<td><input name="Indirizzi[ind]" value="<?php echo $model->ind; ?>" id="Indirizzi_ind" size="40" maxlength="100"/></td>
</tr>
<tr>
<td><?php echo $model->getAttributeLabel('com'); ?></td>
<td>
<?php
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'name'=>'Indirizzi[com]'
,'id'=>'Indirizzi_com'
,'attribute' => 'com',
'source' => $this->createUrl('/anagra/indirizzi/autocompleteComune'),
'options' => array(
'select' => "js:function(event, ui) {
$('#Indirizzi_com').val(ui.item.value);
$('#Indirizzi_cap').val(ui.item.cap);
$('#Indirizzi_country_iso').val(ui.item.country_iso);
$('#Indirizzi_prov').val(ui.item.prov);
return false;
}")
, 'htmlOptions' => array('size' => '40'),
));
?></td> <td><?php echo $model->getAttributeLabel('cap'); ?></td>
<td><input name="Indirizzi[cap]" value="<?php echo $model->cap; ?>" id="Indirizzi_cap" size="5" maxlength="5"/></td>
<td><?php echo $model->getAttributeLabel('prov'); ?></td>
<td><input name="Indirizzi[prov]" value="<?php echo $model->prov; ?>" id="Indirizzi_prov" size="2" maxlength="2"/></td>
</tr>
<tr>
<td><?php echo $model->getAttributeLabel('country_iso'); ?></td>
<td> <?php echo CHtml::dropDownList('Indirizzi[country_iso]', $model->country_iso, CHtml::listData(Country::model()->findAll(), 'iso', 'descri')); ?>
</td>
</tr>
<tr>
</tr>
<tr>
<td><?php echo $model->getAttributeLabel('tipo'); ?></td>
<td>
<?php
$this->widget('ext.combobox.EJuiComboBox', array(
'name' => 'Indirizzi[tipo_search]',
'value' => $model->indirizzitipo->descri,
// data to populate the select. Must be an array.
'data' => CHtml::listData(TipoIndirizzo::model()->findAll(), 'id', 'descri'),
// options passed to plugin
// Options passed to the text input
'htmlOptions' => array('size' => 10),
));
?> </td>
<td><?php echo $model->getAttributeLabel('posta'); ?></td>
<td><input type="checkbox" name="Indirizzi[posta]" id="Indirizzi_posta"<?php if ($model->posta == 1) echo 'checked="checked"'; ?>/></td>
</tr>
</tbody>
</table>
<input type="hidden" name="from[controller]" value="<?php echo $from['controller'];?>"/>
<input type="hidden" name="from[action]" value="<?php echo $from['action'];?>"/>
<input type="hidden" name="from[module]" value="<?php echo $from['module'];?>"/>
<input type="hidden" name="from[id_base]" value="<?php echo $from['id_base'];?>"/>
<input type="hidden" name="Indirizzi[anagra_id]" value="<?php echo $model->anagra_id;?>"/>
<input type="submit"/>
</form>
<?php
if (!empty($asDialog)) {
$this->endWidget();
} else {?>
<script>
jQuery('#Indirizzi_com').autocomplete({'select':function(event, ui) {
$('#Indirizzi_com').val(ui.item.value);
$('#Indirizzi_cap').val(ui.item.cap);
$('#Indirizzi_country_iso').val(ui.item.country_iso);
$('#Indirizzi_prov').val(ui.item.prov);
return false;
},'source':'<?php echo Yii::app()->createUrl('/anagra/indirizzi/autocompleteComune') ?>'});
jQuery('#Indirizzi_tipo_search').combobox({'allowText':true});
</script><?php }?>
Come sempre si accettano suggerimenti.