delete event trigger something in CGridView of Yii - yii

I merge create and admin views and method in my controller,
so in admin.php I have following lines:
echo $this->renderPartial('_form', array('model'=>$create));
echo $this->renderPartial('_admin', array('model'=>$search));
and in _form I edit submit button to
echo CHtml::ajaxSubmitButton('Submit', Yii::app()->createUrl('money/income'), array('update' => '#money-grid'));
and in money controller,income method implement create method and send CGridView as ajax response.
if ($createModel->save()) {
$this->renderPartial('_admin', array('model' => $searchModel), false, true);
if data saved into database,it render _admin view which contain CGridView,this works prefect ,but problem exist, if client create something and insert into database, so after it click on delete of CGridView it will trigger more than one and it makes problem,
for example if user insert n rows ,then click on the each row to delete,it will trigger n + 1 times.(but it should be 1)
where is the problem?is it for Yii?

The problem solved by updating CGridView by jQuery instead of rendering it,so I changed my ajaxSubmitButton to
echo CHtml::ajaxSubmitButton('Submit', Yii::app()->createUrl('money/income'), array('success'=>'$.fn.yiiGridView.update("money-grid")'));
and it solved problem.
'success'=>'$.fn.yiiGridView.update("money-grid")'

Related

Yii2 Gridview get all selected row for all pagination

I wrapped my gridview with Pjax widget like this
\yii\widgets\Pjax::begin();
gridview
\yii\widgets\Pjax::end();
in order to make the gridview make ajax request when I click on each pagination.
I also use ['class' => 'yii\grid\CheckboxColumn'], in column as well.
and I find that when I'm on first pagination I checked some rows and then go to second page and check some rows but when I go back to first page what I've checked is gone.
My question is how can I keep all checkedrow for all pagination
With current conditions (Pjax, multiple pages, yii\grid\CheckboxColumn) it's impossible because of the way it works.
When you click on the pagination links all GridView html content is replaced by new one that comes from the AJAX response.
So obviously all selected checkboxes on the previous page are gone.
Few possible ways to solve that:
1) Write custom javascript and server side logic.
As one of the options, you can send AJAX request to server with parameter meaning that user has chosen to select all data for the bulk delete operation (or use separate controller action for bulk deletion). In this case actually we don't need to get the selected data from user, because we can simply get them from database (credits - Seng).
2) Increase number of displayed rows per page.
3) Use infinite scroll extension, for example this.
4) Break desired action in several iterations:
select needed rows on first page, do action (for example, delete).
repeat this again for other pages.
You can get selected rows like that:
$('#your-grid-view').yiiGridView('getSelectedRows');
[infinite scroll] : http://kop.github.io/yii2-scroll-pager/ will work good if you do not have any pjax filters. If you have filters also in play, do not use this plugin as it does not support pjax filters with it. For rest of the applications it is perfect to use.
Update1 : it seems to be straight forward than expected, here is the how I accomplished it
Add following lines to the checkbox column
'checkboxOptions' => function($data){
return ['id' => $data->id, 'onClick' => 'selectedRow(this)'];
}
Now add following JS to the common js file you will have in your project of the page where this datagrid resides
var selectedItems=[]; //global variable
/**
* Store the value of the selected row or delete it if it is unselected
*
* #param {checkbox} ele
*/
function selectedRow(ele){
if($(ele).is(':checked')) {
//push the element
if(!selectedItems.includes($(ele).attr('id'))) {
selectedItems.push($(ele).attr('id'));
}
} else {
//pop the element
if(selectedItems.includes($(ele).attr('id'))) {
selectedItems.pop($(ele).attr('id'));
}
}
}
Above function will store the selected row ids in the global variable array
Now add following lines to pjax:end event handler
$(document).on('pjax:end', function () {
//Select the already selected items on the grid view
if(!empty(selectedItems)){
$.each(selectedItems, function (index,value) {
$("#"+value).attr('checked',true);
});
}
});
Hope it helps.
I just solved this problem and it works properly with Pjax.
You may use my CheckboxColumn. I hope this can help. The checked items are recorded with cookies.
You can read the part with //add by hezll to understand how to fix it, because I didn't provide a complete general one.
Hope it works for you.
https://owncloud.xiwangkt.com/index.php/s/dGH3fezC5MGCx4H

Yii, set radio button value fetch from database

In Yii, I listed my table which is fetch from database in grid view.
'value'=> 'CHtml::radioButton("set_default",false,array(
"value"=>"$data->id",
"set"=>"1",
"disable"=>"disable",
"uncheckValue"=>null
))',
the above code I entered in normal radio button view, how do I fetch from database? Anybody help me?
CGridView lets you write any value inside row's column instead of normal database values. For modify column values, you need to add a function for value attribute. Inside of this function, you can access each data's attributes. In your case, You need to echo a radio button like this:
//$data refres to each data row in the CGridView
'value' => function ($data, $row) {
echo
CHtml::radioButton("set_default",false,array(
"value"=>$data->id,
"set"=>"1",
"disable"=>"disable",
"uncheckValue"=>null
)),
},

Yii populate a dropdown on select of another

I have a dropdown that I want to populate when an item in another dropdown is selected. Both the dropdown are tied to data/model passed on from controller. and the first dropdown is populated from DB by calling a function in the model. Heres' the form,
echo $form->dropDownListRow($modelunit,
'superunit',
$model->getSunits(),
array(
'ajax' => array(
'type'=>'POST',
'url'=>CController::createUrl('user/getunits'),
'update'=>'#unit_id',
)));
echo CHtml::dropDownList('unit_id','', array());
Here's the action user/getunits called by Ajax.
$data=Unit::model()->findAll('sid=:sid',
array(':sid'=>(int) $_POST['superunit']));
$data=CHtml::listData($data,'id','name');
foreach($data as $value=>$name)
{
echo CHtml::tag('option',
array('value'=>$value),CHtml::encode($name),true);
}
I keep getting an error "Undefined index: superunit" when first dropdown is selected. Also, you may notice I am using form->dropDownListRow for the first dropdown while using CHtml::dropDownList for the second. That's cause I am clueless on the syntax of how exactly to make sure the dropdown is populated correctly with ajax and at also properly bind to the model.
You use $form->dropDownListRow that's why you will get $_POST['MyModelName']['superunit'] on your server side
Change you code like
$data=Unit::model()->findAll('sid=:sid',
array(':sid'=>(int) $_POST['MyModelName']['superunit']));
Where MyModelName is a model that you use)
Or like
echo CHtml::dropDownList('superunit'.....
For others - this wiki may help.

Updating the dropdown list field value which is created using drop down list using create

i got a problem while updating a record for a model in yii. i have 2 models. im working on one model now. I'm creating a record for one model using create controller. in the form i've 1 fields which is the name field(im getting this name from other model(table). im getting the names from this second table and showing them in dropdown list. and storing them.
when it comes to update its again coming up with the same dropdown what i've shown using the _form.php for creating a record. can anyone pls tell me how can i show the name instead of dropdown list again??
thanks in advance.
Add a simple check in your view to see if the value has already been added or not. Something like this:
<?php if ($model->attribute && $model->attribute != ''): ?>
// Code to display a normal textfield here
<?php else: ?>
// Code to display dropdown
<?php endif; ?>

How create action is called in a master page while submitting the _form?

For example,
if we create a master page named BED
while creating a new record for the master we create it using the create bed link in the right side(which has the controller URL bed/create).
But after that entering all the fields, and clicking the save button(in _form).
We have not mentioned any controller url in the save button but how it manages to locate the bed/create
In the same way while updating if we click the link for update, it locates the update action with the id, but while saving the page again how it manages to locate the bed/create again.
By default action of form is the same url (if you create action at '/index.php?r=bed/create' action of form is set action="/index.php?r=bed/create"). But if you need to change it - just add it to attributes of ActiveForm. For example for bed/update view:
$form = $this->beginWidget('CActiveForm', array(
'id'=>'user-form',
'action'=>'/index.php?r=bed/create'
));