ok, ad esempio, immagina di ripensare il tabularInput, ovvero:
-
da un autocomplete, via AJAX, selezioni oggetti (ActiveRecord)
-
una volta selezionato quello desiderato, crei un oggetto (ad esempio una riga di bom)
-
se la creazione è andata a buon fine, aggiorni una gridView (magari extended con la possibilità di modificare al volo alcuni campi)
-
riaggiorni la grid con i campi modificati
? ok ?
questa è la view, la prima parte, ovvero il registerScript, serve solo per evidenziare i caratteri trovati nell’autocomplete…
<?php
Yii::app()->clientScript->registerScript('highlightAC','$.ui.autocomplete.prototype._renderItem = function (ul, item) {
item.label = item.label.replace(new RegExp("(?![^&;]+<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/wink.gif' class='bbc_emoticon' alt=';)' />(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(this.term) + ")(?![^<>]*>)(?![^&;]+<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/wink.gif' class='bbc_emoticon' alt=';)' />", "gi"), "<strong>$1</strong>");
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "</a>")
.appendTo(ul);
};',CClientScript::POS_LOAD);
?>
<div class="control-group ">
<label class="control-label" for="searchKey"><?php echo Yii::t('labels','Search Key'); ?>: </label>
<div class="controls">
<?php
//$items=$model->getBomRows();
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
//'model'=>$model,
'name'=>'searchKey',
'id'=>'item_name',
'source'=>'js: function(request, response) {
$.ajax({
url: "'.$this->createUrl('searchKey/autocomplete').'",
dataType: "json",
data: {
term: request.term,
nodeId: '.$model->page_id.',
},
success: function (data) {
response(data);
}
})
}',
// additional javascript options for the autocomplete plugin
'options'=>array(
'showAnim'=>'fold',
'select'=>"js:function(event, ui) {
addKey(ui.item.datSearchKey.id);
$(this).val('');return false;
}",
),
'htmlOptions'=>array(
//'disabled'=>$disabled,
'class'=>'span7'
),
));
?>
</div>
</div>
<?php
$datBomDataProvider=new CActiveDataProvider('CmsSearchKeyContent', array(
'criteria'=>array(
'with'=>array('searchKey'),
'condition'=>'content_id=:fatherID',
'params'=>array(':fatherID'=>$model->id),
'order'=>'searchKey.name ASC',
),
'pagination'=>array(
'pageSize'=>200,
),
));
$this->widget('bootstrap.widgets.TbExtendedGridView', array(
'id'=>'dat-content-key-grid',
//'filter'=>$filterModel,
'type'=>'striped bordered',
'dataProvider' => $datBomDataProvider,
'template' => "{items}",
'columns' =>array(
//array('name'=>'id', 'header'=>'#', 'htmlOptions'=>array('style'=>'width: 60px')),
array('name'=>'key_id', 'value'=>'$data->searchKey!= null ? $data->searchKey->name : \'\'', 'header'=>'ID'),
array(
'name'=>'value',
'header'=>'Value',
//'headerHtmlOptions' => array('style' => 'width:50px; align:right'),
'class'=>'bootstrap.widgets.TbJEditableColumn',
'saveURL' => $this->createUrl('cmsSearchKeyContent/contentKey'),
'jEditableOptions' => array(
'type' => 'text',
// very important to get the attribute to update on the server!
'submitdata' => array('attribute'=>'value'),
'cssclass' => 'form',
//'event'=>'dblclick',
'width' => 'auto',//'180px',
//'class' => 'span12',
)
),
//if use editableSaver....
/*
array(
'class' => 'bootstrap.widgets.TbEditableColumn',
'name' => 'quantity',
'sortable'=>true,
'editable' => array(
'url' => $this->createUrl('datItem/editableSaver'),
'placement' => 'right',
'inputclass' => 'span3',
//'onRender'=>'js:alert("OK");'
)
),*/
array(
'htmlOptions' => array('nowrap'=>'nowrap'),
'class'=>'bootstrap.widgets.TbButtonColumn',
'template'=>'{delete}',
'deleteButtonUrl'=>null,
),
),
));
?>
<script>
// Add item record to dat_bom
function addKey(datSearchKeyId){
alert(datSearchKeyId);
<?php
echo CHtml::ajax(array(
// the controller/function to call
'url'=>CController::createUrl('searchKeyContent/ajaxAddKey'),
// Data to be passed to the ajax function
'data'=>array(
'content_id'=>$model->id,
'locale'=>$locale,
'raw_id'=>'js:datSearchKeyId',
),
'type'=>'post',
'dataType'=>'json',
'success'=>"function(data){
if(data.error=='false'){
$.fn.yiiGridView.update('dat-content-key-grid');
}
} ",
))?>;
}
</script>
e queste sono le action dei controller (l’action autocomplete di un altro controller, nell’esempio, il SearchKeyController la trovi sotto…)
public function actionAjaxAddKey(){
if (Yii::app()->request->isAjaxRequest)
{
$pageId = Yii::app()->request->getParam( 'page_id' );
$contentId = Yii::app()->request->getParam( 'content_id' );
$locale = Yii::app()->request->getParam( 'locale' );
$rawId = Yii::app()->request->getParam( 'raw_id' );
try{
$content = CmsPageContent::model()->findByAttributes(array('page_id'=>$pageId,'locale'=>$locale));
$bom = new CmsSearchKeyContent;
$bom->content_id=$content->id;
$bom->search_key_item_id=$rawId;
$bom->locale=$locale;
$bom->value='Inserire uno o più valori separati da ","';
$bom->save(false);
$status='Everything has gone well';
$error='false';
echo CJSON::encode(array(
'error' => $error,
'status' => $status,
));
Yii::app()->end();
}catch(Exception $e){
$status='Exception caugth in ajaxAddKey : '.$e;
echo CJSON::encode(array(
'error' => 'true',
'status' => $status,
));
Yii::app()->end();
}
}
}
public function actionEditableSaver()
{
Yii::import('bootstrap.widgets.TbEditableSaver');
$es = new TbEditableSaver('CmsSearchKeyContent');
$es->update();
//echo "<script type='text/javascript'>javascript:$.fn.yiiGridView.update('dat-attachment-grid');</script>";
}
e questa è la action autocomplete di SearchKeyController:
public function actionAutocomplete($pageId,$contentId,$language)
{
$contentKeys = $this->getContentKeys($contentId);
$results = array();
$res =array();
if (isset($_GET['term'])) {
$qtxt ="SELECT * FROM cms_search_key WHERE ((LOWER(cms_search_key.name) LIKE :name OR LOWER(cms_search_key.description) LIKE :name) AND id NOT IN ".$contentKeys.") ORDER BY cms_search_key.name";
$qtxt = "select * from cms_search_key
left join cms_search_key_item on cms_search_key_item.search_key_id
left join cms_search_key_content on cms_search_key_content.search_key_item_id
WHERE ((LOWER(cms_search_key.name) LIKE :name OR LOWER(cms_search_key.description) LIKE :name)
AND (cms_search_key_item.id NOT IN ".$contentKeys." and cms_search_key_item.locale=\"".$language."\")) ORDER BY cms_search_key.name";
$qtxt="..."; //your sql query (too long to show)
$command =Yii::app()->db->createCommand($qtxt);
$command->bindValue(":name", '%'.strtolower($_GET['term']).'%', PDO::PARAM_STR);
$res =$command->queryAll();
foreach($res as $datSK)
{
$datSearchKeyItem = CmsSearchKeyItem::model()->findByAttributes(array('search_key_id'=>$datSK['id'],'locale'=>$language));
$results[] = array(
'label'=>$datSK['name'].' - '.$datSK['description'], // viene visualizzato in search
'value'=>$datSK['name'], // viene visualizzato dopo select .' - '.$p['description'],
'id'=>$datSK['id'],
'locale'=>$language,
'datSearchKeyItem'=>$datSearchKeyItem
);
}
}
echo CJSON::encode($results);
Yii::app()->end();
}
Riassumendo:
-
hai visto come chiamare action AJAX passando parametri:
-
giocando, in poche righe di codice, con n action in m controller;
-
gestire gli oggetti ritornati dalle action;
-
…
Fammi sapere se hai bisogno di chiarimenti; probabilmente i guru AJAX mi manderebbero a quel paese (vero Zaccaria e Sensorario ?), ma, ti assicuro che funziona tutto (anche se tutto è "perfettibile")
Ciao