yii CGridView фильтр с отношениями

Я использую yii для моего веб-приложения. В одном из моих представлений у меня есть CGridView и поставщик данных - это модель Mail. В этой модели у меня есть связь с 3 другими моделями. В сетке я показываю cols от трех моделей. Как я могу отфильтровать CGridView?

ОБНОВИТЬ:

<?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}",
)); ?>

2 ответа

Решение

У меня есть модели Restaurant, City, Country и User с отношениями между ними.

Модель:

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

Посмотреть:

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

Я надеюсь это тебе поможет.

ОБНОВИТЬ:

Что делать, если вы попробуете что-то вроде этого:

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

ОБНОВЛЕНИЕ № 2:

Приготовьтесь, это будет немного грязно.

Допустим, у нас есть два класса, A и B. B принадлежит A. У объекта B есть, скажем, "color", и мы хотим отобразить его в нашей сетке, где мы перечисляем "A".

Первое, что вам нужно сделать, это вручную создать свойство для вашего класса провайдера данных (что такое "A"). Это свойство будет "colorOfB", поэтому вы должны добавить "public $colorOfB;" к вашей модели А.

Добавить критерии для этого свойства:

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

Добавьте столбец в сетку:

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

Последнее, что нужно сделать - установить это свойство вручную в контроллере A:

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

Это установит список выбора

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

));

Другие вопросы по тегам