Search code examples
yiicgridview

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.


Solution

  • 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