yii CGridView filter with relations

2019-05-11 03:50发布

问题:

I'm using yii for my web application. In one of my view I have CGridView and dataprovider is Mail model. In this model I have relation with with 3 other models. In the grid I show cols from three models. How can I filter the CGridView?

UPDATE:

<?php $dialog = $this->widget('ext.ecolumns.EColumnsDialog', array(
           'options'=>array(
                'title' => 'Layout settings',
                'autoOpen' => false,
                'show' =>  'fade',
                'hide' =>  'fade',
            ),
           'htmlOptions' => array('style' => 'display: none'), //disable flush of dialog content
           'ecolumns' => array(
                'gridId' => 'mails-grid', //id of related grid
                'storage' => 'session',  //where to store settings: 'db', 'session', 'cookie'
                'fixedLeft' => array('CCheckBoxColumn'), //fix checkbox to the left side 
                'model' => $dataprovider, //model is used to get attribute labels
                'columns'=>array(
                                array(
                                    'name'=>'mailTemplate.name',
                                    'filter'=>CHtml::activeTextField($dataprovider, 'mailTemplate'),
                                ),
                                'sendDate',
                                array(
                                        'name'=>'mailTemplate.subject',
                                        'filter'=>CHtml::activeTextField($dataprovider, 'mailTemplate'),
                            ),
                            array(
                                'name'=>'client.email',
                                'filter'=>CHtml::activeTextField($dataprovider, 'client'),
                            ),
                            array(
                                'name'=>'client.name',
                                'filter'=>CHtml::activeTextField($dataprovider, 'client'),
                            ),
                            array(
                                'name'=>'operator.username',
                                'filter'=>CHtml::activeTextField($dataprovider, 'operator'),
                            ),
                            array(
                                'name'=>'status',
                                'value'=>array('MailHelper', 'getEmailStatus'),
                                'filter'=> CHtml::activeDropDownList($dataprovider, 'status', Mail::getEmailStatuses()),
                            ),
                            array(
                                'class'=>'CButtonColumn',
                                'template'=>'{update}',
                                'buttons'=>array(
                                                'update' => array(
                                                        'url'=>'$this->grid->controller->createUrl("/email/editTemplate", array("templateId"=>$data->id))',
                                                ),
                                            ),
                            )
                        ),
        )
    ));

?>

<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id' => 'mails-grid',
    'dataProvider'=>$dataprovider->search(),
    'columns' => $dialog->columns(),
    'filter' => $dataprovider,
    'template' => $dialog->link()."{summary}\n{items}\n{pager}",
)); ?>

回答1:

I have Restaurant, City, Country and User models with relations between them.

Model:

public function search() {
  $criteria=new CDbCriteria;
  $criteria->together = true;
  $criteria->with= array('xCountry','xCity','User');
  $criteria->compare('Id',$this->Id,true);
  $criteria->compare('Restaurant.Name',$this->Name,true);
  $criteria->addSearchCondition('xCountry.Name',$this->Country);
  $criteria->addSearchCondition('xCity.Name',$this->City);
  $criteria->compare('Zip',$this->Zip,true);
  $criteria->compare('Address',$this->Address,true);
  $criteria->compare('Description',$this->Description,true);
  $criteria->compare('Restaurant.Active',$this->Active,true);
  $criteria->addSearchCondition('User.Username',$this->Owner);
  $criteria->compare('Lat',$this->Lat);
  $criteria->compare('Lon',$this->Lon);

  return new CActiveDataProvider($this, array(
    'criteria'=>$criteria,
  ));
}

View:

$this->widget('zii.widgets.grid.CGridView', array(
      'id'=>'restaurant-grid',
      'dataProvider'=>$model->search(),
      'filter'=>$model,
      'columns'=>array(
        'Id',
        'Name',
        'Zip',
        'Address',
        'Active',
        array(
          'name' => 'User.Username',
          'header' => 'Username',
          'filter' => CHtml::activeTextField($model, 'Owner'),
          'value' => '$data->User->Username',
            ),
        array(
          'name' => 'xCountry.Name',
          'header' => 'Country',
          'filter' => CHtml::activeTextField($model, 'Country'),
          'value' => '$data->xCountry->Name',
            ),
        array(
          'name' => 'xCity.Name',
          'header' => 'City',
          'filter' => CHtml::activeTextField($model, 'City'),
          'value' => '$data->xCity->Name',
            ),
        array(
        'class'=>'CButtonColumn',
        ),
      ),
    ));

I hope this can help you.

UPDATE:

What if you try something like this:

...
'columns'=>array(
  'mailTemplate.name',
  'sendDate',
  'mailTemplate.subject',
  'client.email',
  ...

UPDATE #2:

Prepare yourself this will be a bit dirty.

Let's say we've got two classes, A and B. B belongs to A. B's got a property, let's say "color" and we want to display it in our grid where we list the "A"s.

The first thing you have to do is, manually create a property to your data provider class (what is "A"). This property will be "colorOfB", so you have to add "public $colorOfB;" to your model A.

Add criteria for this property:

$criteria->compare('B.color',$this->colorOfB,true);

Add the column to the grid:

array(
  'name' => 'B.color',
  'header' => 'Color of B',
  'filter' => CHtml::activeTextField($model, 'colorOfB'),
  'value' => '$data->B->color'),

The final thing is to set this property manually in A's controller:

$modelA = new A('search');
$modelA->colorOfB = $_GET['A']['colorOfB'];


回答2:

this will set select list

$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'avto-ugon-grid',
'dataProvider'=>$model_data,
'filter'=>$model,
'columns'=>array(
    'id',
    array(
        'name' => 'time',
        'value' => 'date("d/m/Y", $data->time)',
        'type' => 'html',
    ),
    array(
        'name' => 'nomer',
        'value' => '$data->nomer',
        'type' => 'html',
    ),
    array(
        'name' => 'id_marka',
        'value' => '$data->idMarka->mark',
        'type' => 'html',
        'filter'=> CHtml::listData(AvtoUgon::model()->with('idMarka')->findAll(array('group'=> 'id_marka', 'order'=> 'idMarka.mark')), 'id_marka', 'idMarka.mark'),
    ),
    array(
        'name' => 'id_model',
        'value' => '$data->idModel->model',
        'type' => 'html',
        'filter'=> CHtml::listData(AvtoUgon::model()->with('idModel')->findAll(array('group'=> 'id_model', 'order'=> 'idModel.model')), 'id_model', 'idModel.model'),
    ),
    array(
        'name' => 'color',
        'value' => $data->color,
        'type' => 'raw',
    ),

    array(
        'name' => 'id_street',
        'value' => '$data->idStreet->street',
        'type' => 'html',
    ),
    array(
        'name' => 'publish',
        'value' => 'CHtml::link($data->publish ? "Опубликовано" : "Не опубликовано", Yii::app()->controller->createUrl("publish", array("id" => $data->id)))',
        'type' => 'html',
    ),
    /*'id_street',
    'nomer',
    */
    array(
        'class'=>'CButtonColumn',
    ),
),

));