Yii ::: CGridView ::: dataprovider is not working / class is not passing data - yii

I am trying to pass data from another model to my view page with CGridView and controller. It is showing some error:
urlencode() expects parameter 1 to be string, array given
I created a function for dataProvider.
controller
public function actionClassA()
{
$dataProvider = new CActiveDataProvider('Codesparam', array(
'criteria'=>array(
'condition'=>'cm_type="Branch"',
),
));
$this->render('admina', array('dataProvider' => $dataProvider));
}
view
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'productmaster-grid',
'dataProvider'=>$dataProvider,
//'filter'=>$result,
));

Related

Add column from another table to CGridView

Hi I'm using yii crud and trying to add a column from another table to Admin view
This is my admin view CGridView widget code.
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'package-days-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'package_days_id',
'package_days_description',
array(
'header' => 'Package Title',
'name' => 'package_days_package_id',
'value' => function ($data){
echo $data->packagePackagedays->package_title;
}
),
array(
'class'=>'CButtonColumn',
),
),
)); ?>
And this is relations function in 'PackageDays' model.
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'packagePackagedays' => array(self::BELONGS_TO, 'Packages', 'package_days_package_id'),
);
}
This is search function in 'PackageDays' model.
public function search()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->with = "packagePackagedays";
$criteria->compare('package_days_id',$this->package_days_id);
$criteria->compare('packagePackagedays.package_title',$this->package_days_package_id);
$criteria->compare('package_days_description',$this->package_days_description,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
I added the column successfully but I can't search values of newly
added column.
It would be great if someone can looking to it
Make sure you added package_days_package_id as a public property of your Packages model. Otherwise $this->package_days_package_id doesn't exist
class Packages extends CActiveRecord{
public $package_days_package_id;
...
Also Make sure you added package_days_package_id in your "safe" validation rule for the "search" scenario (also in your Packages model). Without this, the value you type in the text box won't be assigned to your $this->package_days_package_id
public function rules(){
return array(
...
// The following rule is used by search()
array('bunch, of, stuff, ..., package_days_package_id', 'safe', 'on'=>'search'),
If you also want the grid column to be sortable on click, you'll also have to create a custom CSort and provide it to your CActiveDataProvider

Pass Radio Button Value Onchange

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);

Dynamically create CGridViews that show different data

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.

Yii:: Could I get the value of the view in the controller

I create a form use the CActiveForm to create a form.
<?php $form = $this->beginWidget('CActiveForm', array(
'id'=>'report-form',
'enableAjaxValidation'=>false,
'enableClientValidation'=>true,
'focus'=>array($exps[0],'productname'),
)); ?>
and when I call the ajax handler in the controller.I want to create a new html string to update the form.
but I can't find the way to get access to value $form!
could I get the value in the controller form the view?
any suggestion would be appreciated!
You could create the form object at your controller and pass it to the view via the 2nd argument of the render() function..
// inside controller
$form = $this->beginWidget('CActiveForm', array(
'id'=>'report-form',
'enableAjaxValidation'=>false,
'enableClientValidation'=>true,
'focus'=>array($exps[0],'productname'),
));
$this->render($myView, array(
'form' => $form,
));

Yii cgridview give reference to checkbox

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',
)),));