2014-02-24 49 views
16

根據這一點:PHP,Yii2 GridView控件過濾的關係值

Yii2 how does search() in SearchModel work?

我希望能夠過濾關係數據的GridView列。這就是我的意思:

我有兩個表,TableATableB。兩者都有使用Gii生成的相應模型。 TableA具有TableB一個外鍵的值,這樣的:

TableA 
attrA1, attrA2, attrA3, TableB.attrB1 

TableB 
attrB1, attrB2, attrB3 

attrA1和attrB1是它們相應的表的主鍵。

現在,我有一個Yii2 GridViewattrA2,attrA3attrB2。我在attrA2attrA3上有一個工作過濾器,這樣我就可以搜索列值。我也有這兩列的工作排序 - 只需點擊列標題即可。我希望能夠在attrB2上添加此篩選和排序。

TableASearch模式是這樣的:

public function search($params){ 
    $query = TableA::find(); 
    $dataProvider = new ActiveDataProvider([ 
     'query' => $query, 
    ]); 

    if (!($this->load($params) && $this->validate())) { 
     return $dataProvider; 
    } 

    $this->addCondition($query, 'attrA2'); 
    $this->addCondition($query, 'attrA2', true); 
    $this->addCondition($query, 'attrA3'); 
    $this->addCondition($query, 'attrA3', true); 

    return $dataProvider; 
} 

在我TableA模式,我這樣設置

public $relationalValue; 

public function afterFind(){ 
    $b = TableB::find(['attrB1' => $this->attrB1]); 
    $this->relationalValue = $b->relationalValue; 
} 

相關值雖然可能不是這樣做的最佳方式。我想我必須在我的搜索功能中使用$ relationalValue,但我不知道如何。同樣,我希望能夠通過此列進行排序 - 就像我通過點擊標題鏈接可以獲得attrA2AttrA3一樣。任何幫助,將不勝感激。謝謝。

+0

您是否可以更新您的問題以使searchModel反映框架的最新更改。 –

回答

3

通過列過濾gridview在Yii 2.0中非常容易。請將篩選器屬性添加到具有查找值的gridview列,如下所示:

[ 
     "class" => yii\grid\DataColumn::className(), 
     "attribute" => "status_id", 
     'filter' => ArrayHelper::map(Status::find()->orderBy('name')->asArray()->all(), 'id', 'name'), 
     "value" => function($model){ 
      if ($rel = $model->getStatus()->one()) { 
       return yii\helpers\Html::a($rel->name,["crud/status/view", 'id' => $rel->id,],["data-pjax"=>0]); 
      } else { 
       return ''; 
      } 
     }, 
     "format" => "raw", 
], 
+0

只是看到了這一點,我問了一年又兩年。這是一個簡潔的答案,也是迄今爲止最簡單的解決方案。謝謝。 –

+0

它的好處,爲我工作,但所有的結果在DropDownList,如何更改像更多的過濾器文本框的Ajax文本框??? – user3770797

18

這是基於guide中的說明。 SearchModel的基本代碼來自Gii代碼生成器。這也假設$ this-> TableB已經使用hasOne()hasMany()關係設置。看到這個doc

1.設置搜索模式

TableASearch模型添加:

public function attributes() 
{ 
    // add related fields to searchable attributes 
    return array_merge(parent::attributes(), ['TableB.attrB1']); 
} 

public function rules() 
{ 
    return [ 
     /* your other rules */ 
     [['TableB.attrB1'], 'safe'] 
    ]; 
} 

然後在TableASearch->search()加($this->load()前):

$dataProvider->sort->attributes['TableB.attrB1'] = [ 
     'asc' => ['TableB.attrB1' => SORT_ASC], 
     'desc' => ['TableB.attrB1' => SORT_DESC], 
]; 

$query->joinWith(['TableB']); 

然後實際的搜索數據的(在$this->load()以下):

$query->andFilterWhere(['like','TableB.attrB1',$this->getAttribute('TableB.attrB1')); 

2.配置GridView

添加到您的視圖:

echo GridView::widget([ 
    'dataProvider' => $dataProvider, 
    'filterModel' => $searchModel, 
    'columns' => [ 
     /* Other columns */ 
     'TableB1.attrB1', 
     /* Other columns */   
    ] 
]); 
+0

'$ query-> joinWith(['companyPosition']);' 應該是 '$ query-> joinWith(['TableB']);' – pedak

+0

Thank you @pedak,fixed –

+0

很好的回答,謝謝, Yii2已經發展,我已經將「解決方案」重新分配給了更簡單的答案。乾杯。 –

3

我堅持這個問題太,我的解決方案是相當不同的。我有兩個簡單的模型:

書:

class Book extends ActiveRecord 
{ 
    .... 

    public static function tableName() 
    { 
     return 'books'; 
    } 

    public function getAuthor() 
    { 
     return $this->hasOne(Author::className(), ['id' => 'author_id']); 
    } 

和作者:

class Author extends ActiveRecord 
{ 

    public static function tableName() 
    { 
     return 'authors'; 
    } 

    public function getBooks() 
    { 
     return $this->hasMany(Book::className(), ['author_id' => 'id']); 
    } 

但我的搜索邏輯是不同的模式。而且我沒有找到如何在不創建額外字段的情況下實現搜索author_first_name。所以這是我的解決方案:

class BookSearch extends Model 
{ 
    public $id; 
    public $title; 
    public $author_first_name; 

    public function rules() 
    { 
     return [ 
      [['id', 'author_id'], 'integer'], 
      [['title', 'author_first_name'], 'safe'], 
     ]; 
    } 

    public function search($params) 
    { 
     $query = Book::find()->joinWith(['author' => function($query) { $query->from(['author' => 'authors']);}]); 
     $dataProvider = new ActiveDataProvider([ 
      'query' => $query, 
      'pagination' => array('pageSize' => 50), 
      'sort'=>[ 
       'attributes'=>[ 
        'author_first_name'=>[ 
         'asc' => ['author.first_name' => SORT_ASC], 
         'desc' => ['author.first_name' => SORT_DESC], 
        ] 
       ] 
      ] 
     ]); 

     if (!($this->load($params) && $this->validate())) { 
      return $dataProvider; 
     } 
     .... 
     $query->andWhere(['like', 'author.first_name', $this->author_first_name]); 
     return $dataProvider; 
    } 
} 

這是創建表的別名:function($query) { $query->from(['author' => 'authors']);}

和GridView代碼:

<?php echo GridView::widget([ 
    'dataProvider' => $dataProvider, 
    'filterModel' => $searchModel, 
    'columns' => [ 
     [ 
      'attribute' => 'id', 
      'filter' => false, 
     ], 
     [ 
      'attribute' => 'title', 
     ], 
     [ 
      'attribute' => 'author_first_name', 
      'value' => function ($model) { 
        if ($model->author) { 
         $model->author->getFullName(); 
        } else { 
         return ''; 
        } 
       }, 
      'filter' => true, 
     ], 
     ['class' => 'yii\grid\ActionColumn'], 
    ], 
]); ?> 

我歡迎任何批評和建議。