There are cases you want to update a record on CGridview directly
In this wiki I will show how to do that
In your view file:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $dataProvider,
'id' => 'grid-view-id',
'columns' => array(
array(
'header' => 'attribute1',
'value' => 'CHtml::textField("TheModel[attribute1]",$data->attribute1)',
'type' => 'raw',
),
array(
'header' => 'attribute2',
'value' => 'CHtml::textField("TheModel[attribute2]",$data->attribute2)',
'type' => 'raw',
),
array(
'class' => 'CButtonColumn',
'template' => '{update}{view}{delete}',
'buttons' => array(
'update' => array(
'options' => array('class' => 'save-ajax-button'),
'url' => 'Yii::app()->createUrl("yourController/saveModel", array("id"=>$data->id))',
),
'view',
'delete',
),
),
),
));
Also in the same view file or in any way you have to load this script
<script>
$('#grid-view-id a.save-ajax-button').live('click', function(e)
{
var row = $(this).parent().parent();
var data = $('input', row).serializeObject();
$.ajax({
type: 'POST',
data: data,
url: jQuery(this).attr('href'),
success: function(data, textStatus, jqXHR) {
console.log(data);
console.log(textStatus);
console.log(jqXHR);
},
error: function(textStatus, errorThrown) {
console.log(textStatus);
console.log(errorThrown);
}
});
return false;
});
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
</script>
Now in your controller "yourController" in action "saveModel"
public function actionSaveModel($id){
//save the data as you did in the properly action. For example
if ($_POST['TheModel']) {
$model = new TheModel();
$model->attributes = $_POST['TheModel'];
$model->save();
}
}
Thats it!
Security
Don't forget validate before save!
Re: #17143
save mothod runs the validators by default
http://www.yiiframework.com/doc/api/1.1/CActiveRecord#save-detail
So, if you don't use save method like that $model->save(false); you shouldn't worry about it :)
Excelent Wiki!
Thank you very much for sharing.
Coooool
It's really nice script but can we use validation before save like this -
$valid = $model->validate(); if($valid){ $model->save(); }
or
$model->save(false);
which one is batter???
RE: #17676
Hi Rohit,
$model->save(); or $model->save(true);
is equivalent of
$valid = $model->validate(); if($valid){ $model->save(); }
$model->save(false); save the model without validation.
so in our case is better to use any mentioned code except $model->save(false);
RE: #17678
thanks for your valuable response!!
error
Undefined variable: Rptk
*/ 219 protected function performAjaxValidation($model) 220 { 221 if(isset($_POST['ajax']) && $_POST['ajax']==='rptk-form') 222 { 223 echo CActiveForm::validate($model); 224 Yii::app()->end(); 225 } 226 } 227 228 public function actionSaveModel($id){ 229 //save the data as you did in the properly action. For example 230 var_dump($Rptk['Absen']); die(); 231 if ($_POST['Rptk']) { 232 $model = new Rptk(); 233 $model->attributes = $_POST['Rptk']; 234 $valid = $model->validate(); 235 236 if($valid){ 237 $model->save(); 238 } 239 } 240 } 241 }
Re: #19462
Hi Roberto
Replace the $_POST['Rptk'] with isset($_POST['Rptk'])
In the first time when no post request exist you have to check it.
also comment the
//var_dump($Rptk['Absen']); die();
Thank you
Hi Kostas,
There's no error now. But, I can't get any value from $_POST['Rptk'].
Here is my view code
<?php /* @var $this RptkController */ /* @var $model Rptk */ $this->breadcrumbs=array( 'Rptks'=>array('index'), 'Manage', ); $this->menu=array( array('label'=>'List Rptk', 'url'=>array('index')), array('label'=>'Create Rptk', 'url'=>array('create')), ); Yii::app()->clientScript->registerScript('search', " $('.search-button').click(function(){ $('.search-form').toggle(); return false; }); $('.search-form form').submit(function(){ $('#rptk-grid').yiiGridView('update', { data: $(this).serialize() }); return false; }); "); ?> <script> $('#grid-view-id a.save-ajax-button').live('click', function(e) { var row = $(this).parent().parent(); var data = $('input', row).serializeObject(); $.ajax({ type: 'POST', data: data, url: jQuery(this).attr('href'), success: function(data, textStatus, jqXHR) { console.log(data); console.log(textStatus); console.log(jqXHR); }, error: function(textStatus, errorThrown) { console.log(textStatus); console.log(errorThrown); } }); return false; }); $.fn.serializeObject = function() { var o = {}; var a = this.serializeArray(); $.each(a, function() { if (o[this.name]) { if (!o[this.name].push) { o[this.name] = [o[this.name]]; } o[this.name].push(this.value || ''); } else { o[this.name] = this.value || ''; } }); return o; }; </script> <h1>Manage Rptks</h1> <p> You may optionally enter a comparison operator (<b><</b>, <b><=</b>, <b>></b>, <b>>=</b>, <b><></b> or <b>=</b>) at the beginning of each of your search values to specify how the comparison should be done. </p> <?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?> <div class="search-form" style="display:none"> <?php $this->renderPartial('_search',array( 'model'=>$model, )); ?> </div><!-- search-form --> <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'rptk-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'pager'=>array( 'class'=>'CLinkPager', 'firstPageLabel'=>'Pertama', 'lastPageLabel'=>'Terakhir', 'nextPageLabel'=>'Selanjutnya', 'prevPageLabel'=>'Sebelumnya', 'header'=>'', ), 'columns'=>array( // 'id', // 'AC_No', 'NIP', 'Nama', array( 'name'=>'Tanggal', 'filter'=>false, // Set the filter to false when date range searching ), 'Jadwal_Kerja', 'Jam_Masuk', 'Jam_Pulang', 'Scan_Masuk', 'Scan_Pulang', array( 'header' => 'Absen', 'value' => 'CHtml::textField("Rptk[Absen]",$data->Absen)', // this is how I make the textfield 'type' => 'raw', ), array( 'header' => 'Keterangan', 'value' => 'CHtml::textField("Rptk[Keterangan]",$data->Keterangan)', // this is how I make the textfield 'type' => 'raw', ), /* 'Terlambat', 'selisih_jam_pulang', 'Konversi_TL', 'Pot_TL', 'Pulang_Cepat', 'Konversi_PC', 'Pot_PC', 'Absen', 'Keterangan', 'Pot_Ket', 'Total_Pot_Harian', 'Total_Pot_Bulanan', 'Work_Time', 'Departmen', 'F24', */ /*array( 'class'=>'CButtonColumn', ),*/ array( 'class' => 'CButtonColumn', 'template' => '{update}{view}{delete}', 'buttons' => array( 'update' => array( 'options' => array('class' => 'save-ajax-button'), 'url' => 'Yii::app()->createUrl("Rptk/saveModel", array("id"=>$data->id))', ), 'view', 'delete', ), ), ), )); ?> <br/> <?php echo CHtml::link('Export This',array('Rptk/excel')); ?>
And here is my Controller
public function actionSaveModel($id){ //save the data as you did in the properly action. For example if (isset($_POST['Rptk'])) { $model = new Rptk(); $model->attributes = $_POST['Rptk']; $valid = $model->validate(); if($valid){ $model->save(); } } }
Javascript function
Roberto,
I got success with this code:
<script type="text/javascript"> $(document).ready( function () { $('#search-grid a.save-ajax-button').click(function (e) { var row = $(this).parent().parent(); var data = $('input', row).serializeObject(); $.ajax({ type: 'POST', data: data, url: jQuery(this).attr('href'), success: function (data, textStatus, jqXHR) { console.log(data); console.log(textStatus); console.log(jqXHR); }, error: function (textStatus, errorThrown) { console.log(textStatus); console.log(errorThrown); } }); return false; }); $.fn.serializeObject = function () { var o = {}; var a = this.serializeArray(); $.each(a, function () { if (o[this.name]) { if (!o[this.name].push) { o[this.name] = [o[this.name]]; } o[this.name].push(this.value || ''); } else { o[this.name] = this.value || ''; } }); return o; }; } ); </script>
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.