Following on from this:
继此之后:
Yii2 how does search() in SearchModel work?
Yii2 SearchModel中的search()如何工作?
I would like to be able to filter a GridView
column of relational data. This is what I mean:
我希望能够过滤关系数据的GridView列。这就是我的意思:
I have two tables, TableA
and TableB
. Both have corresponding models generated using Gii. TableA
has a foreign key to a value in TableB
, like this:
我有两个表,TableA和TableB。两者都有使用Gii生成的相应模型。 TableA有一个表B中的值的外键,如下所示:
TableA
attrA1, attrA2, attrA3, TableB.attrB1
TableB
attrB1, attrB2, attrB3
attrA1 and attrB1 are the primary keys of their corresponding tables.
attrA1和attrB1是其相应表的主键。
Now, I have a Yii2 GridView
of attrA2
, attrA3
and attrB2
. I have a working filter on attrA2
and attrA3
so that I can search on column values. I also have a working sort for these two columns too - by just clicking on the column header. I would like to be able to add this filtering and sorting on attrB2
too.
现在,我有一个attrA2,attrA3和attrB2的Yii2 GridView。我在attrA2和attrA3上有一个工作过滤器,以便我可以搜索列值。我也对这两个列进行了工作排序 - 只需单击列标题即可。我希望能够在attrB2上添加这个过滤和排序。
My TableASearch
model looks like this:
我的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;
}
In my TableA
model, I set the related value like this
在我的TableA模型中,我设置了相关的值
public $relationalValue;
public function afterFind(){
$b = TableB::find(['attrB1' => $this->attrB1]);
$this->relationalValue = $b->relationalValue;
}
Although it is probably not the best way of doing this. I think I have to use $relationalValue somewhere in my search function but I'm not sure how. Similarly, I would like to be able to sort by this column too - just like I can for attrA2
and AttrA3
by clicking on the header link`. Any help would be appreciated. Thanks.
虽然这可能不是最好的方法。我想我必须在我的搜索功能中使用$ relationalValue,但我不确定如何。同样,我希望能够按照此列进行排序 - 就像我可以通过单击标题链接来查看attrA2和AttrA3一样。任何帮助,将不胜感激。谢谢。
3 个解决方案
#1
3
Filtering a gridview by a column is damn easy in Yii 2.0. Please add the filter attribute to a gridview column having lookup values, as under:
在Yii 2.0中,通过列过滤网格视图非常容易。请将filter属性添加到具有查找值的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",
],
#2
18
This is based on the description in the guide. The base code for the SearchModel comes from the Gii code generator. This is also assuming that $this->TableB has been setup using hasOne()
or hasMany()
relation. See this doc.
这基于指南中的描述。 SearchModel的基本代码来自Gii代码生成器。这也假设已经使用hasOne()或hasMany()关系设置了$ this-> TableB。看到这个文档。
1. Setup search model
1.设置搜索模型
In TableASearch
model add:
在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']
];
}
Then in TableASearch->search()
add (before $this->load()
):
然后在TableASearch-> search()add(在$ this-> load()之前):
$dataProvider->sort->attributes['TableB.attrB1'] = [
'asc' => ['TableB.attrB1' => SORT_ASC],
'desc' => ['TableB.attrB1' => SORT_DESC],
];
$query->joinWith(['TableB']);
Then the actual search of your data (below $this->load()
):
然后实际搜索你的数据(在$ this-> load()下面):
$query->andFilterWhere(['like','TableB.attrB1',$this->getAttribute('TableB.attrB1'));
2. Configure GridView
2.配置GridView
Add to your view:
添加到您的视图:
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
/* Other columns */
'TableB1.attrB1',
/* Other columns */
]
]);
#3
3
I'm stuck with this problem too, and my solution is rather different. I have two simple models:
我也遇到了这个问题,我的解决方案也大相径庭。我有两个简单的模型:
Book:
class Book extends ActiveRecord
{
....
public static function tableName()
{
return 'books';
}
public function getAuthor()
{
return $this->hasOne(Author::className(), ['id' => 'author_id']);
}
And Author:
class Author extends ActiveRecord
{
public static function tableName()
{
return 'authors';
}
public function getBooks()
{
return $this->hasMany(Book::className(), ['author_id' => 'id']);
}
But my search logic is in different model. And i didn't find how can i implement search without creating additional field author_first_name
. So this is my solution:
但我的搜索逻辑是不同的模型。我没有找到如何在不创建其他字段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;
}
}
This is for creating table alias: function($query) { $query->from(['author' => 'authors']);}
这是用于创建表别名:function($ query){$ query-> from(['author'=>'authors']);}
And GridView code is:
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'],
],
]); ?>
I will appreciate any critiques and advice.
我将不胜感激任何批评和建议。
#1
3
Filtering a gridview by a column is damn easy in Yii 2.0. Please add the filter attribute to a gridview column having lookup values, as under:
在Yii 2.0中,通过列过滤网格视图非常容易。请将filter属性添加到具有查找值的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",
],
#2
18
This is based on the description in the guide. The base code for the SearchModel comes from the Gii code generator. This is also assuming that $this->TableB has been setup using hasOne()
or hasMany()
relation. See this doc.
这基于指南中的描述。 SearchModel的基本代码来自Gii代码生成器。这也假设已经使用hasOne()或hasMany()关系设置了$ this-> TableB。看到这个文档。
1. Setup search model
1.设置搜索模型
In TableASearch
model add:
在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']
];
}
Then in TableASearch->search()
add (before $this->load()
):
然后在TableASearch-> search()add(在$ this-> load()之前):
$dataProvider->sort->attributes['TableB.attrB1'] = [
'asc' => ['TableB.attrB1' => SORT_ASC],
'desc' => ['TableB.attrB1' => SORT_DESC],
];
$query->joinWith(['TableB']);
Then the actual search of your data (below $this->load()
):
然后实际搜索你的数据(在$ this-> load()下面):
$query->andFilterWhere(['like','TableB.attrB1',$this->getAttribute('TableB.attrB1'));
2. Configure GridView
2.配置GridView
Add to your view:
添加到您的视图:
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
/* Other columns */
'TableB1.attrB1',
/* Other columns */
]
]);
#3
3
I'm stuck with this problem too, and my solution is rather different. I have two simple models:
我也遇到了这个问题,我的解决方案也大相径庭。我有两个简单的模型:
Book:
class Book extends ActiveRecord
{
....
public static function tableName()
{
return 'books';
}
public function getAuthor()
{
return $this->hasOne(Author::className(), ['id' => 'author_id']);
}
And Author:
class Author extends ActiveRecord
{
public static function tableName()
{
return 'authors';
}
public function getBooks()
{
return $this->hasMany(Book::className(), ['author_id' => 'id']);
}
But my search logic is in different model. And i didn't find how can i implement search without creating additional field author_first_name
. So this is my solution:
但我的搜索逻辑是不同的模型。我没有找到如何在不创建其他字段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;
}
}
This is for creating table alias: function($query) { $query->from(['author' => 'authors']);}
这是用于创建表别名:function($ query){$ query-> from(['author'=>'authors']);}
And GridView code is:
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'],
],
]); ?>
I will appreciate any critiques and advice.
我将不胜感激任何批评和建议。