im new in with yii.
I'm using CGridView with a CCheckBoxColumn to select records but i don't know how to execute an action for all the checked records only. any ideas? i tried before but when i click the submit button, all rows including the one not selected are processed.
this is my coding in admin page:
array(
'id'=>'check-boxes',
'name'=>'check-boxes',
'class'=>'CCheckBoxColumn',
'selectableRows' => '50',
'checked'=>"0",
),
i dont know how to post the checkbox value and everytime i post it, it give value of check-box[].
i submit it using this coding:
echo CHtml::ajaxLink('Submit', Yii::app()->createUrl('controller/action'),
array(
'type'=>'POST',
'data'=>'js:{ids : $.fn.yiiGridView.getChecked("grid-id","check-boxes")}'
));
but the nothing happen when i use this.
how we should pass the value in controller and how the controller works?
thank you.
public function actionActionName()
{
if(isset($_POST['check-boxes'])){
foreach ($_POST['check-boxes'] as $id){
$model = $this->loadModel($id);
CVarDumper::dump($id, 5, true);
}
}
else
CVarDumper::dump('Nothing is selected', 5, true);
}
Related
In Yii, the list view used as a search result.
Controller
public function actionSearch()
{
$key=$_GET['Text'];
$criteria = new CDbCriteria();
$criteria->addSearchCondition('username',$key,true,"OR");
$criteria->select = "`username`,`country`";
$data=new CActiveDataProvider('User',
array('criteria'=>$criteria,'pagination'=>array('pageSize'=>5),
));
$this->render('search', array(
'ModelInstance' => User::model()->findAll($criteria),
'dataProvider'=>$data,
));
}
search.php
<?php
//THE WIDGET WITH ID AND DYNAMICALLY MADE SORTABLEATTRIBUTES PROPERTY
$this->widget('zii.widgets.CListView', array(
'id'=>'user-list',
'dataProvider'=>$dataProvider,
'itemView'=>'results',
'template' => '{sorter}{items}{pager}',
));
?>
<?php echo CHtml::radioButtonList('type','',array(
'1'=>'Personal',
'2'=>'Organization'),array('id'=>'type'),array( 'separator' => "<br/>",'style'=>'display:inline')
);
?>
result.php
<?php echo $data->username."<br>"; ?>
<?php echo $data->country; ?>
The user model fields are id, name , country, type, The search result shows the name and country. Now want to filter the results based on the radio button onchange (personal/organisation).
You could try to use $.fn.yiiListView.update method passing list view's id (user-list in your case) and ajax settings as arguments. data property of ajax settings is what can be used to specify GET-parameters that will be passed to your actionSearch to update the list view. So you have to analyze these parameters in the action and alter CDbCriteria instance depending on them.
The following script to bind onchange handler to your radio button list is to be registered in the view:
Yii::app()->clientScript->registerScript("init-search-radio-button-list", "
$('input[name=\"type\"]').change(function(event) {
var data = {
// your GET-parameters here
}
$.fn.yiiListView.update('user-list', {
'data': data
// another ajax settings if desired
})
});
", CClientScript::POS_READY);
You also may consider the following code as an example based on common technique of filtering CGridView results.
By the way, for performance reasons you can render your view partially in the case of ajax update:
$view = 'search';
$params = array(
'ModelInstance' => User::model()->findAll($criteria),
'dataProvider' => $data
);
if (Yii::app()->request->isAjaxRequest)
$this->renderPartial($view, $params);
else
$this->render($view, $params);
I'm new to Yii, and I'm having a hard time figuring this out. I want to show multiple CGridViews on a page depending on the options that a user chooses, with each gridview only showing the records for that option. In this case, the options are job statuses, like open, closed, in progress, etc.
I've got some code working to show multiple grid views by looping through an array, but I'm not sure how to filter them:
$test = array(1,2,3,4,5);
foreach ($test as $value) {
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'job-grid',
'dataProvider'=>$model->search(),
'columns'=>array(
'ID',
'CustomerCompany',
'FirstName',
'LastName',
/* etc */
),
));
}
Any ideas about how I can go about filtering each gridview from the values in the array?
Thanks!
UPDATE
Ok, I figured out how to do what I was trying to do. I'm handling it in the controller like this:
public function actionBoard()
{
$models = array();
$statuses = JobStatus::model()->findAll();
foreach ($statuses as $status)
{
$model=new Job('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['Job']))
$model->attributes=$_GET['Job'];
$model->Status = $status->ID;
$models[$status->Status] = $model;
}
$this->render('board',array('models'=>$models));
}
So I find all the statuses, then use the ID field to do a search, put the result in an array, then pass it to the view. I handle it like this in the view:
foreach ($models as $status)
{
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'job-grid',
'dataProvider'=>$status->search(),
'columns'=>array(
'ID',
'CustomerCompany',
'FirstName',
'LastName',
'Phone1',
'Phone2',
/* etc */
),
));
Basically, creating a gridview for each "status" in the array of "statuses". Seems to work, just took some time to think of it in MVC terms instead of the old ASP.NET databinding method that I'm used to.
You asked for different CGridViews, so here it is:
Go in your model.
Now, you need to write some new search() methods.
Within each method, you will specify the values that you want, like these 2 methods:
public function searchA() {
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id);
$criteria->compare('email', $this->email, true);
$criteria->compare('password', $this->password);
$criteria->compare('created', $this->created);
$criteria->compare('lastmodified', $this->lastmodified);
$criteria->compare('confirmed', $this->confirmed);
$criteria->compare('is_human', 1);// this is a human
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
public function searchB() {
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id);
$criteria->compare('email', $this->email, true);
$criteria->compare('password', $this->password);
$criteria->compare('created', $this->created);
$criteria->compare('lastmodified', $this->lastmodified);
$criteria->compare('confirmed', $this->confirmed);
$criteria->compare('is_human', 0);//this is not a human, maybe a donkey ... who knows
$criteria->compare('username', $this->username, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
now that you have your search methods, use the needed search method for each cgridview
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'job-grid',
'dataProvider'=>$model->searchA(),
'columns'=>array(
'ID',
'CustomerCompany',
'FirstName',
'LastName',
/* etc */
),
));
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'job-grid2',
'dataProvider'=>$model->searchB(),
'columns'=>array(
'ID',
'CustomerCompany',
'FirstName',
'LastName',
/* etc */
),
));
simple
ps: as a trick, you may want to use constants, like:
const CONSTA = 1;
const CONSTB = 2;
and use then in the model as:
self::CONSTA
or outside the model as:
ModelName::CONSTA
by using const, if your values change in time, you dont have to modify the entire code and you dont have to look all over the project for those values
You should begin at the data part of the problem: First try to create several data providers that return the results that you want. If you used Gii to auto-generate some models, you can look into the search() method there to see an example how you can create such a provider with different query conditions. You should try to keep this code in a model somewhere. For example you could create a searchByStatus($status) method, which returns a data provider for the given status.
Then in the controller you can fetch several data providers from this method, one for each status you want, send them to the view and finally feed them into different CGridViews.
Here is a wiki for dynamic gridviews in the same view.
I am working with the Yii framework.
I have set a value in one of my cgridview filter fields using:
Here is my jQuery to assign a value to the searchfield:
$('#gridviewid').find('input[type=text],textarea,select').filter(':visible:first').val('".$_GET['value']."');
And here my PHP for calling the cgridview:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'bills-grid',
'dataProvider'=>$dataProvider,
'filter'=>$model,
'cssFile'=>Yii::app()->baseUrl . '/css/gridview.css',
'pager'=>array(
'class'=>'AjaxList',
'maxButtonCount'=>25,
'header'=>''
),
'columns' => $dialog->columns(),
'template'=>"<div class=\"tools\">".$dialog->link()." ".CHtml::link($xcel.' Export to excel', array('ExcelAll'))."</div><br />{items}{summary}<div class=\"pager-fix\">{pager}</div>",));
The value appears in the search field and my cgridview works correctly without any issues, but I am unable to trigger the cgridview to refresh or filter. Does anyone know who to trigger the cgridview to filter after page load with a predefined value?
Any help would be greatly appreciated and please let me know if you need additional information.
Thank you.
You can solve the problem without any clientside code modification. In your controller action just set the default value for the attribute as shown below
public function actionAdmin()
{
$model = new Bills();
$model->unsetAttributes();
$model->attribute_name="default filter value";//where attribute_name is the attribute for which you want the default value in the filter search field
if(isset($_GET['Bills'])){
$model->attributes = $_GET['Bills'];
}
$this->render('admin',array('model'=>$model));
}
Have a look at 'default' index action that gii generates:
public function actionIndex()
{
$model = new Bills();
$model->unsetAttributes();
if(isset($_GET['Bills'])){
$model->attributes = $_GET['Bills'];
}
$this->render('index',array('model'=>$model));
}
So if you add one line like: $model->attribute = 'test';, you're done. 'attribute' is of course the attribute that has to have the default filter value (in this case value is 'test') :). So your code looks like:
public function actionIndex()
{
$model = new Bills();
$model->unsetAttributes();
if(isset($_GET['Bills'])){
$model->attributes = $_GET['Bills'];
}
if(!isset($_GET['Bills']['attribute']) {
$model->attribute = 'test';
}
$this->render('index',array('model'=>$model));
}
Of course youre attribute will have a test value (in filter) set up as long as you wont type anything in its filter field. I hope that that's what you're looking for. Your filter should work as always.
Sorry for my bad english :)
Regards
You can use Yii's update:
$.fn.yiiGridView.update('bills-grid', {
type: 'GET',
url: <?php echo Yii::app()->createUrl('controller/action') ?>"?Class[attribute]=<?php echo $_GET['value'] ?>
success: function() {
$.fn.yiiGridView.update('bills-grid');
}
});
This is how i do it, just change the URL, it should be the same controller action of the gridview and change URL parameters to the structure represented in there, should be like Bills[attribute]=value.
Because when adding the CCheckBoxColumn to my vgridview in a form, in return I have no precise index for working with the checked box data's. So I try to add the 'uncheckValue' but I am unable to link it to the reference value of my table. Is there a way to access this value for the current row ? (the $data->reference in my code return a Undefined variable).
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'gview',
'dataProvider'=>$dataProvider,
'columns'=>array(
'client',
'reference',
array(
'class'=>'CCheckBoxColumn',
'id'=>'CB',
'selectableRows'=>2,
'checkBoxHtmlOptions'=>array(
'uncheckValue'=>$data->reference, ),
)),));
Tks anyone could put me on the way (if there is one... )
I finally find one way is to extend CCheckBoxColumn.
As inside this code I have access to $data. Now my form return checkbox with his 'name' as the 'reference' column of my table, so I can do further batch treatment.
The uncheckValue hidden field was not suitable as it was only giving index for unchecked fields (!).
I believe this code should not stay in view but in extension...
Any comments still welcome....
Yii::import('zii.widgets.grid.CCheckBoxColumn');
class LIndexCheckBoxColumn extends CCheckBoxColumn {
public $linkId;
public function renderDataCellContent($row,$data)
{
if($this->value!==null)
$value=$this->evaluateExpression($this->value,array('data'=>$data,'row'=>$row));
else if($this->name!==null)
$value=CHtml::value($data,$this->name);
else
$value=$this->grid->dataProvider->keys[$row];
$checked = false;
if($this->checked!==null)
$checked=$this->evaluateExpression($this->checked,array('data'=>$data,'row'=>$row));
$options=$this->checkBoxHtmlOptions;
//$name=$options['name'];
$varLink=$this->linkId;
$name=$data->$varLink;
unset($options['name']);
$options['value']=$value;
$options['id']=$this->id.'_'.$row;
echo CHtml::checkBox($name,$checked,$options);
}
}
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'columns'=>array(
'client',
'reference',
array(
'class'=>'LIndexCheckBoxColumn',
'id'=>'cb',
'selectableRows'=>2,
'linkId'=>'reference',
)),));
I have problems regarding with pagination and Ajax form.
Here is my code for Controller:
$dataProvider = new CActiveDataProvider('User', array(
'pagination'=>array(
'pageSize'=>10,
),
));
$this->render('users',array(
'dataProvider'=>$dataProvider,
));
For view -> users:
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_user',
);
For render _users:
echo CHtml::ajaxLink($text, $this->createUrl('admin/deleteuser',array('id'=>$data->iduser)), array('success'=>"js:function(html){ alert('remove') }"), array('confirm'=>_t('Are you sure you want to delete this user?'), 'class'=>'delete-icon','id'=>'x'.$viewid));
if i have 15 rows in a database it will only show 10 and will generate a pagination (ajaxUpdate = true) for next 5. The first 10 rows has no problem with the ajaxLink because the clientscript was generated but problem is the when I move to the next page, the ajaxLink is not working because its not generated by the pagination .
any idea? thanks
An alternate method, check this post in the yii forum. So your code will become like this:
echo CHtml::link($text,
$this->createUrl('admin/deleteuser',array('id'=>$data->iduser)),
array(// for htmlOptions
'onclick'=>' {'.CHtml::ajax( array(
'beforeSend'=>'js:function(){if(confirm("Are you sure you want to delete?"))return true;else return false;}',
'success'=>"js:function(html){ alert('removed'); }")).
'return false;}',// returning false prevents the default navigation to another url on a new page
'class'=>'delete-icon',
'id'=>'x'.$viewid)
);
Your confirm is moved to jquery's ajax function's beforeSend callback. If we return false from beforeSend, the ajax call doesn't occur.
Another suggestion, you should use post variables instead of get, and also if you can, move the ajax call to a function in the index view, and just include calls to the function from the all links' onclick event.
Hope this helps.
Not fully sure, but given past experiences I think the problem is in the listview widget itself.
If the owner of the widget is a Controller, it uses renderPartial to render the item view.
Renderpartial has, as you may or may not know, a "processOutput" parameter which needs to be set to TRUE for most of the AJAX magic (its FALSE by default).
So perhaps you can try to just derive a class of the listview and add a copy in there of "renderItems()". There you would have to change it so that it calls renderPartial with the correct parameters.
In the widget Clistview, I added afterAjaxUpdate
$jsfunction = <<< EOS
js:function(){
$('.delete-icon').live('click',function(){
if(confirm('Are you sure you want to delete?'))
{
deleteUrl = $(this).attr('data-href');
jQuery.ajax({'success':function(html){ },'url':deleteUrl,'cache':false});
return false;
}
else
return false;
});
}
EOS;
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'id'=>'subscriptionDiv',
'itemView'=>'_subscription',
'afterAjaxUpdate'=>$jsfunction,
'viewData'=>array('is_user'=>$is_user,'all'=>$all),
'htmlOptions'=>($dataProvider->getData()) ? array('class'=>'table') : array('class'=>'table center'),
)
);
and in the _user just added attribute data-href
<?php echo CHtml::ajaxLink($text, $this->createUrl('admin/deletesubscription',array('id'=>$data->idsubscription)),
array('success'=>"js:function(html){ $('#tr{$viewid}').remove(); }"),
array('confirm'=>_t('Are you sure you want to unsubscribe?'),
'class'=>'delete-icon',
'id'=>'x'.$viewid,
'data-href'=>$this->createUrl('admin/deletesubscription',array('id'=>$data->idsubscription))
)); ?>
try
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_user',
'enablePagination' => true,
);
if this doesn't solve, try including the total number of records in the data provider options as -
'itemCount' => .....,