I have a gridview which contains a checkbox column and also uses pagination. When I check some checkboxes in the first page and navigate to the second page and check another one in the second page, the options I checked in the first page is not retained there. Is it posssible to retain the checkbox values during pagination?
Code for Gridview is
$widget = $this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(),
'cssFile' => Yii::app()->baseUrl . '/media/js/admin/css/admingridview.css',
//'filter' => $model,
'ajaxUpdate' => true,
'enablePagination' => true,
'columns' => array(
array(
'name' => 'id',
'header' => '#',
'value' => '$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
),
array(
'class' => 'CCheckBoxColumn',
'selectableRows' => '2',
'header' => 'Selected',
),
array(
'name' => 'fb_user_id',
'header' => 'FaceBook Id',
'value' => 'CHtml::encode($data->fb_user_id)',
),
array(
'name' => 'first_name',
'header' => 'Name',
'value' => 'CHtml::encode($data->first_name)',
),
array(
'name' => 'email_id',
'header' => 'Email',
'value' => 'CHtml::encode($data->email_id)',
),
array(
'name' => 'demo',
'type' => 'raw',
'header' => "Select",
'value' => 'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
),
),
));
Edit:
Extension for remembering the selected options in gridview,check this link Selgridview
Thanks to bool.dev
You could use sessions/cookies to store the checked values. I'm not very sure how to make cookies work, so i'll tell you how to do it with sessions. Specifically the user session that yii creates.
Now to use sessions we need to pass the checked (and unchecked) ids to the controller, therefore we'll modify the data being sent to the controller on every ajax update(i.e between paginations), to do this we exploit the beforeAjaxUpdate option of CGridView.
I'm also using CCheckBoxColumn instead of the following in your code(of course you can modify the solution to suit your own needs):
array(
'name' => 'demo',
'type'=>'raw',
'header' => "Select",
'value' => 'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
),
GridView Changes:
<?php $this->widget('zii.widgets.grid.CGridView', array(
// added id of grid-view for use with $.fn.yiiGridView.getChecked(containerID,columnID)
'id'=>'first-grid',
'dataProvider'=>$model->search(),
'cssFile' => Yii::app()->baseUrl . '/media/js/admin/css/admingridview.css',
// added this piece of code
'beforeAjaxUpdate'=>'function(id,options){options.data={checkedIds:$.fn.yiiGridView.getChecked("first-grid","someChecks").toString(),
uncheckedIds:getUncheckeds()};
return true;}',
'ajaxUpdate'=>true,
'enablePagination' => true,
'columns' => array(
array(
'name' => 'id',
'header' => '#',
'value' => '$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
),
array(
'name' => 'fb_user_id',
'header' => 'FaceBook Id',
'value' => 'CHtml::encode($data->fb_user_id)',
),
array(
'name' => 'first_name',
'header' => 'Name',
'value' => 'CHtml::encode($data->first_name)',
),
array(
'name' => 'email_id',
'header' => 'Email',
'value' => 'CHtml::encode($data->email_id)',
),
/* replaced the following with CCheckBoxColumn
array(
'name' => 'demo',
'type'=>'raw',
'header' => "Select",
'value' =>'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
),
*/
array(
'class' => 'CCheckBoxColumn',
'selectableRows' => '2',
'header'=>'Selected',
'id'=>'someChecks', // need this id for use with $.fn.yiiGridView.getChecked(containerID,columnID)
'checked'=>'Yii::app()->user->getState($data->email_id)', // we are using the user session variable to store the checked row values, also considering here that email_ids are unique for your app, it would be best to use any field that is unique in the table
),
),
));
?>
Pay special attention to the code for beforeAjaxUpdate and CCheckBoxColumn, in beforeAjaxUpdate we are passing checkedIds as a csv string of all the ids(in this case email_ids) that have been checked and uncheckedIds as a csv string of all the unchecked ids, we get the unchecked boxes by calling a function getUncheckeds(), which follows shortly. Please take note here, that when i was testing i had used an integer id field (of my table) as the unique field, and not an email field.
The getUncheckeds() function can be registered like this anywhere in the view file for gridview:
Yii::app()->clientScript->registerScript('getUnchecked', "
function getUncheckeds(){
var unch = [];
/*corrected typo: $('[name^=someChec]') => $('[name^=someChecks]') */
$('[name^=someChecks]').not(':checked,[name$=all]').each(function(){unch.push($(this).val());});
return unch.toString();
}
"
);
In the above function pay attention to the selectors and each and push function.
With that done, we need to modify the controller/action for this view.
public function actionShowGrid(){
// some code already existing
// additional code follows
if(isset($_GET['checkedIds'])){
$chkArray=explode(",", $_GET['checkedIds']);
foreach ($chkArray as $arow){
Yii::app()->user->setState($arow,1);
}
}
if(isset($_GET['uncheckedIds'])){
$unchkArray=explode(",", $_GET['uncheckedIds']);
foreach ($unchkArray as $arownon){
Yii::app()->user->setState($arownon,0);
}
}
// rest of the code namely render()
}
That's it, it should work now.
For developing that scheme you would need to know working of what happens when you navigate.
When ever you navigate to a pagination page ajax calls are made and new data is received and it is fetched from CActive Record or what ever the data source. New data is in accordance of database records or source records. when you come back to previous page again Ajax call is made and content is updated so same comes as it is in database.
what i feel is you should save data of checked items temporary and make it permanent if action is made.
You can do something like this
<script type="text/javascript">
$("input:checkbox").click(function () {
var thisCheck = $(this);
if (thisCheck.is (':checked')){
// do what you want here, the way to access the text is using the
// $(this) selector. The following code would output pop up message with
// the selected checkbox text
$(this).val());
}
});
</script>
you can save temporary storage somewhere
Also make this work on normal form submit:
I wanted to add this as a comment on bool.dev's answer, but I do not have enough reputation to do that yet. So I had to put it in a separate answer.
bool.dev, your answer is great and it works well, thanx.
However, as intended, it only works when ajax calls update the gridview. I have the gridview forming part of a form, so I wanted it to also work on normal submission of the form, otherwise the checkboxes are not loaded again when there are other validation errors on the form.
So, in ADDITION to what you did, I added hidden fields on my form e.g.:
<input type="hidden" name='checkedBox1' id='checkedBox1' value=''>
<input type="hidden" name='uncheckedBox1' id='uncheckedBox1' value=''>
Then, before submitting the form, my sumbit button runs your getChecked() and getUncheckeds() functions and store their results in the hidden fields:
if ($('#checkedBox1').length >0) {$('[name=checkedBox1]').val(getChecked());}
if ($('#uncheckedBox1').length >0) {$('[name=uncheckedBox1]').val(getUncheckeds());}
In the controller, besides from checking for $_GET['checkedIds'], you also check for $_POST['checkedBox1'] and store its values to session in the same way you do for $_GET['checkedIds'], using the same session variable.
Do the same with $_POST['uncheckedBox1'].
That should work.
Related
I am trying to use the TbEditableColumn and the type select to have a pulldown menu.
The pulldown menu I need is filled by a function that I call.
That is working for basic cases. But for a another column, the pulldown values are dependent from the row in which it is (grid-view).
So for example the function I want to call to fill the pulldown and pass the id of the current data is:
$model->getPulldownValues($data->id)
But that throws an error that the variable $data is not defined. The funny part is that outside the editable array, I can use $data as expected.
See example below:
Any ideas?
$this->widget('bootstrap.widgets.TbExtendedGridView', array(
'type' => 'striped bordered',
'id'=>'order-image-grid',
'dataProvider'=>$model->search(),
'ajaxUpdate'=>true,
'template' => "{items}\n{extendedSummary}",
'rowCssClassExpression'=>'"FMDBGridColumn".$data->order_error',
'columns'=>array(
array(
'class' => 'bootstrap.widgets.TbEditableColumn',
'name' => 'streets',
'htmlOptions'=>array('width'=>'150'),
'value' => 'CHtml::value($data, "street")',
'editable' => array(
'type' => 'select',
'source' => CHtml::listData($model->availableStreets($data->id), 'id', 'street'),
'url' => $this->createUrl('cities/editable'),
'placement' => 'right',
)
),
),
));
Try to change method "availableStreets" into getter, e.g.:
public function getAvailableStreets()
{
// we don't need to send id as parameter of method,
// we can get it directly from model
// e.g.: $id = $this->id;
//
// put your code here
}
then, in widget, use property
$model->availableStreets
instead of method
$model->availableStreets($id)
Also you can put
CHtml::listData() into your getter and use
'source' => 'availableStreets',
instead of
'source' => CHtml::listData($model->availableStreets($data->id), 'id', 'street'),
you have to consider that $data in 'value' => 'CHtml::value($data, "street")', is referring to a model object which $model->search() is providing, but $data outside of the grid is different(You haven't shared what that is).
In a YII based project I have a cgridview. Requirement is to make whole row or every column value a link and clicking on any of link in row will fire an ajax call. I have tried it from here
How to display rows of CGridView as a link
but issue it that If i make whole row as clickable it takes me to view action.
If I make individual column values in a row as a link and call ajax function i get following error.
Property "CDataColumn.options" is not defined.
I need help in making whole row as clickable and call an ajax function or individual row values to call an ajax function on click.
Any help or guidance in right direction is greatly appreciated.
//code for making trading name column in cgridview as clickable and call ajax
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'customer-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
array(
'name' => 'trading_name',
'value' => 'CHtml::link($data->trading_name, Yii::app()
->createUrl("customer/view/",array("id"=>$data->primaryKey)))',
'type' => 'raw',
'options' => array('ajax' => array('type' => 'get', 'url'=>'js:$(this).attr("href")',
'success' => 'js:function(data) {
$("#tab1").html(data);')
),
),
'email',
'site_code',
array(
'class'=>'CButtonColumn',
),
After some hassle I was able to make the row of the cgridview a link and on clicking on the each row calls an AJAX function. Below is the code. May be it is helpful for someone.
selectionChanged did the trick. On clicking any row calls an ajax function and displays
each customer's information a div below grid.
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'customer-grid',
'dataProvider'=>$model->search(),
'selectionChanged'=>'js:function(id){
n = $.fn.yiiGridView.getSelection(id);
if (n>0){
$.ajax({
url: "'.Yii::app()->urlManager->createUrl('customer/view/').'",
type: "GET",
data: {"id": parseInt(n)},
dataType: "html",
success: function(data) {
$("#customer-div").html(data);
}
});',
'filter'=>$model,
'columns'=>array(
'id',
array(
'name' => 'trading_name',
'value' => 'CHtml::link($data->trading_name, Yii::app()
->createUrl("customer/view/",array("id"=>$data->primaryKey)))',
'type' => 'raw',
'options' => array('ajax' => array('type' => 'get', 'url'=>'js:$(this).attr("href")',
'success' => 'js:function(data) {
$("#tab1").html(data);')
),
),
'email',
'site_code',
array(
'class'=>'CButtonColumn',
),
'options' is not possible for a cgridview column as said in yii documentation :
http://www.yiiframework.com/doc/api/1.1/CGridColumn#htmlOptions-detail
You have to use 'htmlOptions' if you wan to set options.
But if you want to use ajax with a link, you have to use Chtml::ajaxLink() :
http://www.yiiframework.com/doc/api/1.1/CHtml#ajaxLink-detail
I hope it helps you
I use Eselect2 Yii extension to give users multiple choice but only last choice is submitted via POST. Why?
This is my html, in which I also tried to manage all choices with array but without success
<pre>echo $form->labelEx($model,'city_id');
$this->widget('ext.select2.ESelect2', array(
'name' => 'Form[field]',
'data' => City::model()->getCitie`enter code here`s(),
'options' => array('width' => '30%','allowClear'=>true),
'htmlOptions'=>array(
'options'=>array(''=>array('value'=>null,'selected'=>null, 'name'=>'field'),),
'multiple'=>'multiple',
)
));
</pre>
I tried to specify 'name' field as single field and as an array but I have the same problem: only last value is sended.
You should simply use an array :
Instead of
'name' => 'Form[field]',
You should try :
'name' => 'Form[field][]',
I have a custom module, inside:
/Block/Adminhtml//Edit/Tab/Form.php
I am adding a bunch of fields which relate to fields in a table - all works fine and dandy.
However, I have a button on the page which executes some JavaScript, like so:
$fieldset->addField('trigger', 'submit', array(
'name' => 'trigger',
'label' => 'test',
'value' => Mage::helper('modulename')->__('Submit'),
'style' => 'width:100px;',
'onclick' => $this->getProductChooserURL(),
));
Now, for the life of me, I cannot set the value of that button - at the minute, it just shows as a blank html button - I'm just trying to get it to say something on it!
Someone else has had a similar problem here:
http://www.magentocommerce.com/boards/viewthread/283801/#t397177
But I can't make sense of the solution.
Hello if you want call javascript following code may be help you
$eventElemall=$fieldset->addField('trigger', 'submit', array(
'name' => 'trigger',
'label' => 'test',
'value' => Mage::helper('modulename')->__('Submit'),
'style' => 'width:100px;',
'onclick' => "getProductChooserURL()",
));
$eventElemall->setAfterElementHtml('
<script type="text/javascript">
function getProductChooserURL(){
document.getElementById("trigger").value }
</script>');
I want an alert that pops when user tries to click "add to favorite"
1) if there's no checkboxes checked.
2) I also want to know how to get the values of the checked boxes here's my current code on backend
<?php $this->widget('zii.widgets.grid.CGridView',array(
'id' => 'wsrecruitcvhead-grid',
'dataProvider' => $model->search(),
#'filter' => $model,
'columns' => array(
array(
'name' =>'',
'value' => 'CHtml::checkBox("rid[]",null,array("value"=>$data->ResumeID,"id"=>"rid_".$data->ResumeID))',
'type'=>'raw',
'htmlOptions' => array('width'=>5),
'visible' => !Yii::app()->user->isGuest,
),
array(
'name' => 'ResumeTitle',
'value' =>$model->ResumeTitle,
),
'ResumeSummaryIntroduction',
'Name',
array(
'class' => 'CButtonColumn',
'viewButtonUrl' => 'Yii::app()->createUrl("wsrecruitcvhead/view",array("id"=>$data["ResumeID"]))',
'template'=>'{view}',
),
),
));
?>
and here's the screen shot http://pastebin.com/sEpJBCiU
I hope this helps you.
Your code works just fine, just tried it. I would implement the functionality you mentioned using jQuery, like this:
<script type="text/javascript">
$("input:checkbox").click(function () {
var thisCheck = $(this);
if (thisCheck.is (':checked')){
// do what you want here, the way to access the text is using the
// $(this) selector. The following code would output pop up message with
// the selected checkbox text
$(this).val());
}
});
</script>
This code selects all those DOM elements of type checkbox, and then checks with the if condition if it is selected or not. Here you can find more information about this jQuery selector. jQuery is such a powerful tool!!
For get all seleccions of a Grid yii provides the follow code
var seleccions = ($.fn.yiiGridView.getSelection('id_my_cgridview'));
this return an array with the values of checkboxes selected