getQueryParams() from gridview's url after search and create another URL with same params for anchor tag inside GridView - yii

I'm using GridView::widget, when I enter anything on search box inside gridview, it's creating url as below:
/v2/backend/web/index.php/agency/index?AgencySearch%5Bgovt_name%5D=&AgencySearch%5Bcity%5D=&AgencySearch%5Bmember_id%5D=22
Now I need to pass those paramters to url inside status icons present under GridView's Status column.
echo Url::to(['agency/change-status', 'id' => 33, 'set' => 11, Yii::$app->request->getQueryParams()]);
Above code is creating url as below:
/v2/backend/web/index.php/agency/33/change-status/11?1%5BAgencySearch%5D%5Bgovt_name%5D=&1%5BAgencySearch%5D%5Bcity%5D=&1%5BAgencySearch%5D%5Bmember_id%5D=22
And it makes sense because Yii::$app->request->getQueryParams() is an array. Note 1 inside url change-status/11?1%5BAgencySearch
Is there any simplest Yii way of achieving what I need instead of modifying Yii::$app->request->getQueryParams() as per Url::to() that is into string.
I'm trying to pass parameters in order to persist the state of gridview while loading contents again on grid after status change pjax request.

Use array_merge to combine your route and parameters and the search params.
$params = array_merge(['agency/change-status', 'id' => 33, 'set' => 11], Yii::$app->request->getQueryParams());
echo Url::to($params);

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

Passing variable from view to element in cakephp

I have a view file add_rates.ctp and in that there is one select box . when i change the optiion, it will make a ajax call and fetch some values from the controller and load an element in that view.
but my problem is iam not getting the parameter values in the element.
i am getting params in rates.ctp
$params=$this->params['pass'];
it will return an array of parameters. but when i tried this in element i am not getting the value.
also i tried to set a value in the add_rates.ctp and try to access in element, that is also not working
$this->set('params',array($params));
what to do..if anybody have idea about this please reply.. i get stucked ...
If $params is the array you are trying to pass, then try this:
<?php $this->element('your-element-name', array('params' => $params)); ?>

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.

Yii: Is is possible to link a specified CJuiTabs from external page?

I've a page with a CjuiTab, with seven tabs.
I need a link into from external page or from the same page, to REFRESH the page directly a the specified tab.
I need to use ChtmlLink, but how to append '#' to end of url ?
CHtml::link (Yii::t('general','Annulla'),
array("company/update",
'id'=> $companyId)
where / how to append '#contactTab' !?
You just need to pass a '#'=>'value'. The value of the url parameter for CHtml::link is ultimately passed to CController::createUrl, and the doc states:
additional GET parameters (name=>value). Both the name and value will be URL-encoded. If the name is '#', the corresponding value will be treated as an anchor and will be appended at the end of the URL.
So try with:
CHtml::link (Yii::t('general','Annulla'),
array(
"company/update",
'id'=> $companyId,
'#'=>'contactTab'
)
);
Update: For same page links you'll need to use some javascript to reload the page after the browser url is set:
CHtml::link (Yii::t('general','Annulla'),
array(
"company/update",
'id'=> $companyId,
'#'=>'contactTab'
),
array('onclick'=>'setTimeout("location.reload(true);",100);')
);
(Not sure if this is the best way to reload though)

Yii Retrieve and store in a variable a renderPartial file

I have a php file under protected/views/directory_controller_name with formatting like that
<p>
<?php echo $model->title;?>
</p>
...
I display the file with classic method in the controller :
$this->render('filename',array('model'=>$model));
But know, I need to send an email with the same template/layout so I want to store the render of the file in an variable like
$msgHTML = $this->renderInternal('_items', array('model'=>$model));
But it doesn't work!
How can I get render view from a file and store in a variable?
Is it possible?
I don't want to use:
$msgHTML = '<p>'.$model->title.'</p>'
...
Because the file is very long and I don't want to duplicate code!!!
Don't use the renderInternal method, use renderPartial instead. Render internal is low level method and should not be used in such context. To catch the output just set the $return parameter to true:
<?php $output = $this->renderPartial('_subView', $dataArray, true); ?>
$msgHTML = $this->renderInternal('_items', array('model'=>$model), true);
http://www.yiiframework.com/doc/api/1.1/CBaseController#renderInternal-detail
I might be missing something, but can't you just use regular render() with the return argument set to true? Then you can just use a view 'name' instead of knowing the path. (And unless my trusty stack trace logger is broken, renderFile and renderInternal take the same fully qualified path argument. At least I can see renderPartial() passing the full path to my view file to renderFile.)
you can do this with these ways
1) if you want to get the output with header and footer (i.e ) full layout then do this
//add true in the last parameter if you want a return of the output
$htmloutput=$this->render('_pdfoutput',array('data'=>'nothing'),true);
2) similarly if you don't want to get the layout files just use renderpartial in the same way
$htmloutput=$this->renderpartial('_pdfoutput',array('data'=>'nothing'),true);
you will get the html of files in the variable . use this anywhere