I successfully displayed the 3 columns in the gridview. the attr1, attr2, and the sum of the 2 attributes. attr1 and attr2 are from the database and the 3rd column is their sum. How do I make the sorting and filtering work?
Here is the gridview.
[
'label' => 'Number of Enquiries',
'value' => function ($model) {
return $model->countEnquire + $model->countPhone + $model->countTrial;
},
'enableSorting' => true,
]
How add sorting for this column?
OK, I don't have your full source code to go by but can help with a basic example.
Ideally you should start by creating your model and CRUD files using Gii like I have for in my example below.
Here is my basic database table, record:
I added some test data:
Then I created the model and CRUD files using Gii, which I then modified to show you an example of the custom summing/sorting you wish to achieve. See below.
#app/models/Record.php
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "record".
*
* #property integer $record_id
* #property integer $attr1
* #property integer $attr2
* #property integer $sum
*/
class Record extends \yii\db\ActiveRecord
{
public $sum;
public function getSum()
{
$this->sum = 0;
if (is_numeric($this->attr1) && is_numeric($this->attr2)) {
$this->sum = $this->attr1 + $this->attr2;
}
return $this->sum;
}
/**
* #inheritdoc
*/
public static function tableName()
{
return 'record';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['record_id', 'attr1', 'attr2'], 'required'],
[['record_id', 'attr1', 'attr2', 'sum'], 'integer'],
[['sum'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'record_id' => 'Record ID',
'attr1' => 'Attr1',
'attr2' => 'Attr2',
'sum' => 'Sum',
];
}
/**
* #inheritdoc
* #return RecordQuery the active query used by this AR class.
*/
public static function find()
{
return new RecordQuery(get_called_class());
}
}
#app/models/RecordSearch.php
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Record;
/**
* RecordSearch represents the model behind the search form about `app\models\Record`.
*/
class RecordSearch extends Record
{
/**
* #inheritdoc
*/
public function attributes()
{
// add related fields to searchable attributes
return array_merge(parent::attributes(), ['sum']);
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['record_id', 'attr1', 'attr2', 'sum'], 'integer'],
[['sum'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
// find records, additionally selecting the sum of the 2 fields as 'sum'
$query = Record::find()->select('*, (`attr1` + `attr2`) AS `sum`');
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
// enable sorting for the related columns
$dataProvider->sort->attributes['sum'] = [
'asc' => ['sum' => SORT_ASC],
'desc' => ['sum' => SORT_DESC],
];
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'record_id' => $this->record_id,
'attr1' => $this->attr1,
'attr2' => $this->attr2,
]);
// if the sum has a numeric filter value set, apply the filter in the HAVING clause
if (is_numeric($this->sum)) {
$query->having([
'sum' => $this->sum,
]);
}
return $dataProvider;
}
}
#app/views/record/index.php
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use yii\widgets\Pjax;
/* #var $this yii\web\View */
/* #var $searchModel app\models\RecordSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Records';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="record-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a('Create Record', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?php Pjax::begin(); ?> <?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'record_id',
'attr1',
'attr2',
'sum',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
I hope this helps!
Related
I am trying to implement tagged articles for my new small CMS written with yii2.
This is what i have tried https://forum.yiiframework.com/t/how-to-create-tags-for-posts-in-yii2/123890
Everything is working the tagging machanism is fetching data from the tag table but it is not saving data to the table tag_assign.
This is my form.
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
//Using for Wysiwig editor
use dosamigos\ckeditor\CKEditor;
//Using for Tagging
use dosamigos\selectize\SelectizeTextInput;
/* #var $this yii\web\View */
/* #var $model common\models\Articles */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="articles-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'content')->widget(CKEditor::className(), [
'options' => ['height' => 800],
'preset' => 'basic',
'clientOptions' => ['height' => 400]
]) ?>
<?= $form->field($model, 'tags')->widget(SelectizeTextInput::className(), [
// calls an action that returns a JSON object with matched
// tags
'loadUrl' => ['tag/list'],
'options' => ['class' => 'form-control'],
'clientOptions' => [
'plugins' => ['remove_button'],
'valueField' => 'name',
'labelField' => 'name',
'searchField' => ['name'],
'create' => true,
],
])->hint('Use commas to separate tags') ?>
<?= $form->field($model, 'date')->textInput() ?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
And this is my tag model
<?php
namespace common\models;
use Yii;
use dosamigos\taggable\Taggable;
/**
* This is the model class for table "tags".
*
* #property int $id
* #property string $frequency
* #property string $name
*/
class Tag extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'tags';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['frequency', 'name'], 'required'],
[['frequency'], 'string', 'max' => 500],
[['name'], 'string', 'max' => 250],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'frequency' => 'Frequency',
'name' => 'Name',
];
}
//For Tagging
public function behaviors() {
return [
[
'class' => Taggable::className(),
],
];
}
public function findAllByName($name)
{
return Tag::find()->where('name LIKE :query')
->addParams([':query'=>"%$name%"])
->all();
}
}
Tag controller.
<?php
namespace backend\controllers;
use Yii;
use common\models\Tag;
use common\models\searchTag;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\Response;
/**
* TagController implements the CRUD actions for Tag model.
*/
class TagController extends Controller
{
/**
* {#inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Tag models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new searchTag();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Tag model.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Tag model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Tag();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', [
'model' => $model,
]);
}
public function actionList($query)
{
$models = Tag::findAllByName($query);
$items = [];
foreach ($models as $model) {
$items[] = ['name' => $model->name];
}
// We know we can use ContentNegotiator filter
// this way is easier to show you here :)
Yii::$app->response->format = Response::FORMAT_JSON;
return $items;
}
/**
* Updates an existing Tag model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
]);
}
/**
* Deletes an existing Tag model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Tag model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Tag the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Tag::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
}
And the articles
<?php
namespace common\models;
use Yii;
//For Taggable
use dosamigos\taggable\Taggable;
/**
* This is the model class for table "articles".
*
* #property int $id
* #property string $title
* #property string $content
* #property string $tags
* #property string $date
*/
class Articles extends \yii\db\ActiveRecord
{
//For taggable
public function behaviors() {
return [
[
'class' => Taggable::className(),
],
];
}
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'articles';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['title', 'content', 'tags', 'date'], 'required'],
[['content'], 'string'],
[['date'], 'safe'],
[['title', 'tags'], 'string', 'max' => 250],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'title' => 'Title',
'content' => 'Content',
'tags' => 'Tags',
'date' => 'Date',
];
}
public function getTags()
{
return $this->hasMany(Tag::className(), ['id' => 'tag_id'])->viaTable('tag_assign', ['article_id' => 'id']);
}
}
What I am missing? How can I trouble shoot at least what is going wrong?
I have 2 tables with strategy and risk_colors .
I generated Model and CRUD with GII and modified it just a little to get risk_value column in my GridView widget.
Here is my Strategy.php
<?php
namespace backend\models;
use Yii;
use yii\db\ActiveRecord;
use yii\helpers\Url;
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
use yii\db\Expression;
/**
* This is the model class for table "strategy".
*
* #property int $id
* #property string $strategy_title
* #property string $strategy_description
* #property string $strategy_current_money
* #property int $risk_colors_id
*
* #property SelectedStrategies[] $selectedStrategies
* #property RiskColors $riskColors
*/
class Strategy extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'strategy';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['strategy_title', 'strategy_description', 'strategy_current_money', 'risk_colors_id'], 'required'],
[['strategy_current_money', 'risk_colors_id'], 'integer'],
[['strategy_title'], 'string', 'max' => 255],
[['strategy_description'], 'string', 'max' => 2055],
[['risk_colors_id'], 'exist', 'skipOnError' => true, 'targetClass' => RiskColors::className(), 'targetAttribute' => ['risk_colors_id' => 'id']],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'strategy_title' => 'Strategy Title',
'strategy_description' => 'Strategy Description',
'strategy_current_money' => 'Strategy Current Money',
'risk_colors_id' => 'Risk Color ID',
'riskValue' => Yii::t('app', 'Risk'),
'colorNumber' => 'Color Number',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getSelectedStrategies()
{
return $this->hasMany(SelectedStrategies::className(), ['strategy_id' => 'id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getRiskColors()
{
return $this->hasOne(RiskColors::className(), ['id' => 'risk_colors_id']);
}
/**
* #return risk value
*/
public function getRiskValue()
{
return $this->riskColors->risk_value;
}
/**
* #return Get risk value list for dropdown
*/
public function getRiskValueList()
{
$droptions = RiskColors::find()->asArray()->all();
return ArrayHelper::map($droptions, 'id', 'risk_value');
}
/**
* #return Get risk value list for dropdown
*/
public function getColorNumberList()
{
$droptions = RiskColors::find()->asArray()->all();
return ArrayHelper::map($droptions, 'id', 'color_number');
}
}
here is my index.php.
After all i got risk_value column in my GridView, but it looks like i cant sort my table by this field. Here is .
Here is my Search Model
So my question is what should i do to make this field sortable?
In your StrategySearch.php
public function search($params)
{
$query = Strategy::find()->joinWith(['riskColors']);
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->sort->attributes['risk_colors_id'] = [
'asc' => ['risk_colors.risk_value' => SORT_ASC],
'desc' => ['risk_colors.risk_value' => SORT_DESC],
];
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'strategy_current_money' => $this->strategy_current_money,
// 'risk_colors_id' => $this->risk_colors_id,
'risk_colors.risk_value' => $this->risk_colors_id
]);
$query->andFilterWhere(['like', 'strategy_title', $this->strategy_title])
->andFilterWhere(['like', 'strategy_description', $this->strategy_description]);
return $dataProvider;
}
Refere GridView Sorting
I want to do search in Nama Mahasiswa search bar like picture below. As example I type name yuhara but there are no result whereas there are yuhara in the database.
Search model codes:
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\AlumnyS3;
use app\models\AlumniIntegrasi;
/**
* AlumnyS3Search represents the model behind the search form about `app\models\AlumnyS3`.
*/
class AlumnyS3Search extends AlumnyS3
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['Alumnys3ID'], 'integer'],
[['NRP', 'NamaMahasiswa', 'ProgramStudi', 'TanggalMasuk', 'TanggalKeluar'], 'safe'],
];
}
public $NamaMahasiswa;
/*public $TanggalMasuk;
public $tanggalMasukText;*/
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = AlumnyS3::find();
$query->joinWith('alumniIntegrasi');
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'Alumnys3ID' => $this->Alumnys3ID,
]);
$query->andFilterWhere([
'alumnys3.NRP' => $this->NRP,
'alumniintegrasi.NamaMahasiswa' => $this->NamaMahasiswa,
'alumnys3.ProgramStudi' => $this->ProgramStudi,
'alumnys3.TanggalMasuk' => $this->TanggalMasuk,
'alumnys3.TanggaKeluar' => $this->TanggalKeluar
]);
return $dataProvider;
}
}
Model codes:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "alumnys3".
*
* #property integer $Alumnys3ID
* #property string $NRP
* #property string $ProgramStudi
* #property string $TanggalMasuk
* #property string $TanggalKeluar
*
* #property AlumniIntegrasi $nRP
*/
class AlumnyS3 extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'alumnys3';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['NRP'], 'required'],
[['NRP'], 'string', 'max' => 15],
[['ProgramStudi'], 'string', 'max' => 5],
[['TanggalMasuk', 'TanggalKeluar'], 'string', 'max' => 30],
[['NRP'], 'exist', 'skipOnError' => true, 'targetClass' => AlumniIntegrasi::className(), 'targetAttribute' => ['NRP' => 'NRP']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'Alumnys3ID' => Yii::t('app', 'Alumnys3 ID'),
'NRP' => Yii::t('app', 'Nrp'),
'ProgramStudi' => Yii::t('app', 'Program Studi'),
'TanggalMasuk' => Yii::t('app', 'Tanggal Masuk'),
'TanggalKeluar' => Yii::t('app', 'Tanggal Keluar'),
'NamaMahasiswa' => Yii::t('app', 'Nama Mahasiswa'),
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getalumniIntegrasi()
{
return $this->hasOne(alumniIntegrasi::className(), ['NRP' => 'NRP']);
}
public function getNamaMahasiswa()
{
$alumniIntegrasi = alumniIntegrasi::findOne(['NRP'=> $this->NRP]);
if (empty($alumniIntegrasi))
return '';
return $alumniIntegrasi->NamaMahasiswa;
}
/*public function getTanggalMasukText()
{
$alumniIntegrasi = alumniIntegrasi::findOne(['NRP'=> $this->NRP]);
if (empty($alumniIntegrasi))
return '';
return $alumniIntegrasi->TanggalMasuk;
}*/
}
Index codes:
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel app\models\AlumnyS3Search */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('app', 'Alumny S3s');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="alumny-s3-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a(Yii::t('app', 'Create Alumny S3'), ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'Alumnys3ID',
'NRP',
'NamaMahasiswa',
'ProgramStudi',
//'tanggalMasukText',
'TanggalMasuk',
'TanggalKeluar',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
I don't know how to fix that. Could you plese help me to solve this codes? I'm really grateful if you can solve this, thanks!
Add like query in search model like below
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\AlumnyS3;
use app\models\AlumniIntegrasi;
/**
* AlumnyS3Search represents the model behind the search form about `app\models\AlumnyS3`.
*/
class AlumnyS3Search extends AlumnyS3
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['Alumnys3ID'], 'integer'],
[['NRP', 'NamaMahasiswa', 'ProgramStudi', 'TanggalMasuk', 'TanggalKeluar'], 'safe'],
];
}
public $NamaMahasiswa;
/*public $TanggalMasuk;
public $tanggalMasukText;*/
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = AlumnyS3::find();
$query->joinWith('alumniIntegrasi');
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'Alumnys3ID' => $this->Alumnys3ID,
]);
$query->andFilterWhere([
'alumnys3.NRP' => $this->NRP,
// 'alumniintegrasi.NamaMahasiswa' => $this->NamaMahasiswa,
'alumnys3.ProgramStudi' => $this->ProgramStudi,
'alumnys3.TanggalMasuk' => $this->TanggalMasuk,
'alumnys3.TanggaKeluar' => $this->TanggalKeluar
]);
$query->andFilterWhere(['like', 'alumniintegrasi.NamaMahasiswa', $this->NamaMahasiswa]);
return $dataProvider;
}
}
I'm having trouble understanding how relations work in yii 2
I have 2 tables in a mysql database, author and book.
book has a column named author which links to the id of the author table via foreign key.
I've generated CRUD using gii, and I want the author name to appear in the list view, as well as dropdowns for the author name in the create and update views.
But I cant seem to get the relation working even in the list view.
Here's my code
Book Model:
<?php
namespace app\models;
use Yii;
use app\models\Author;
/**
* This is the model class for table "book".
*
* #property integer $id
* #property string $name
* #property integer $author
*/
class Book extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'book';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['name', 'author'], 'required'],
[['author'], 'integer'],
[['name'], 'string', 'max' => 11]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Name',
'author' => 'Author',
];
}
public function getAuthor()
{
return $this->hasOne(Author::className(), ['id' => 'author']);
}
}
BookSearch Model:
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Book;
/**
* BookSearch represents the model behind the search form about `app\models\Book`.
*/
class BookSearch extends Book
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['id', 'author'], 'integer'],
[['name'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = Book::find();
$query->joinWith('author');
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
var_dump($dataProvider);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'author' => $this->author,
]);
$query->andFilterWhere(['like', 'name', $this->name]);
return $dataProvider;
}
}
Also, here's the view file:
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel app\models\BookSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Books';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="book-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a('Create Book', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'name',
[
'attribute' => 'author',
'value' => 'author.name',
],
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
Author Model:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "author".
*
* #property integer $id
* #property string $name
*/
class Author extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'author';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['name'], 'required'],
[['name'], 'string', 'max' => 200]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Name',
];
}
}
I think I may have to change something somehwhere in the author/authorSearch model.
Can someone help
thanks
You can also add columns to a gridview with value from an anonymous function as described here http://www.yiiframework.com/doc-2.0/yii-grid-datacolumn.html#$value-detail. For example you can show an author's name like this in a gridview:
<?= GridView::widget([
'dataProvider'=>$dataProvider,
'filterModel'=>$searchModel,
'columns'=>[
[
'attribute'=>'author.name',
'value'=>function ($model, $key, $index, $column) {
return $model->author->name;
},
],
//...other columns
]);
?>
you can also return a html-link to the detail-view of an author like this:
//...
'columns'=>[
[
'attribute'=>'author',
'value'=>function ($model, $key, $index, $column) {
return Html::a($model->author->name, ['/author/view', 'id'=>$model->author->id]);
},
],
//...
],
//...
You can access relation table data in any crud view file using their relation name. $model->relName->attribute_name.
And You can access relation table data in gridview at following way :
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'attribute' => 'author',
'value'=>'author.author_name', //relation name with their attribute
]
],
]);
First you need a get function in your model, but you have.
This is :
public function getAuthor()
{
return $this->hasOne(Author::className(), ['id' => 'author']);
}
Now you just need do one more thing.
Go to the index file, and to GridView, and columns.
Write this into columns:
[
'attribute' => 'author',
'value' => 'author.name',
],
In the value, the first parameter is your Get function, what named is : getAuthor, and . after your column name.
Hello in your BookSearch Mode please add below code like this.
$query->joinWith(array('author'));
$query->andFilterWhere(['id' => $this->id,])
->andFilterWhere(['like', 'author.author_name', $this->author]);
And in your view file please use below given code below code is for view file inside grid attrubute.
[
'attribute' => 'author',
'value' => 'author.name',
]
i hope this will helps you. and i hope in author table name is stored in name column.
This worked for me - inside the BookSearch Model:
public function search($params)
{
$dataProvider = new \yii\data\SqlDataProvider([
'sql' => 'SELECT book.id as id ,book.author_fk, book.name as book_name , author.name as author_name' .
' FROM book ' .
'INNER JOIN author ON (book.author_fk = author.id) '
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
return $dataProvider;
}
Only issue now is getting the ActionColumn to work correctly, they're currently linking to the wrong IDs, help anyone.
I am new at Yii framework and I am facing this problem that when i am creating search model to add filters and sorting, it's not working, i already have tried this solution Yii2 ActiveDataProvider - Invalid argument supplied for foreach() and even generated the new models and controller but the result is same, it did not work.
Please have a look at the code and kindly tell me what i am doing wrong.
Controller
namespace backend\controllers;
use Yii;
use backend\models\Contacts;
use backend\models\ContactsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* ContactsController implements the CRUD actions for Contacts model.
*/
class ContactsController extends Controller
{
...
/**
* Lists all Contacts models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new ContactsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider
]);
}
...
}
Model
namespace backend\models;
use Yii;
use backend\models\User;
/**
* This is the model class for table "user_contacts".
*
* #property string $id
* #property string $user_id
* #property string $contact_id
* #property string $created_on
* #property string $modified_on
*
* #property User $contact
* #property User $user
*/
class Contacts extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'user_contacts';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['user_id', 'contact_id'], 'integer'],
[['created_on', 'modified_on'], 'safe'],
[['user_id', 'contact_id'], 'unique', 'targetAttribute' => ['user_id', 'contact_id'], 'message' => 'The combination of User ID and Contact ID has already been taken.']
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'user_id' => Yii::t('app', 'User ID'),
'contact_id' => Yii::t('app', 'Contact ID'),
'created_on' => Yii::t('app', 'Created On'),
'modified_on' => Yii::t('app', 'Modified On')
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getContact()
{
return $this->hasOne(User::className(), ['id' => 'contact_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
/**
* #inheritdoc
* #return ContactsSearch the active query used by this AR class.
*/
public static function find()
{
return new ContactsSearch(get_called_class());
}
}
Search model
namespace backend\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use backend\models\Contacts;
/**
* ContactsSearch represents the model behind the search form about `backend\models\Contacts`.
*/
class ContactsSearch extends Contacts
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['id', 'user_id', 'contact_id'], 'integer'],
[['created_on', 'modified_on'], 'safe']
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = Contacts::find();
$dataProvider = new ActiveDataProvider([
'query' => $query
]);
$this->load($params);
if(!$this->validate())
{
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'user_id' => $this->user_id,
'contact_id' => $this->contact_id,
'created_on' => $this->created_on,
'modified_on' => $this->modified_on
]);
return $dataProvider;
}
}
View(index.php)
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'user_id',
'contact_id',
'created_on',
'modified_on',
['class' => 'yii\grid\ActionColumn']
]
]);
Error
PHP Warning – yii\base\ErrorException
Invalid argument supplied for foreach()
1. in F:\Files\Web\PHP\wamp\www\Php\sites\expenses\vendor\yiisoft\yii2\BaseYii.php at line 517
public static function configure($object, $properties)
{
foreach ($properties as $name => $value) {
$object->$name = $value;
}
return $object;
}
2. in F:\Files\Web\PHP\wamp\www\Php\sites\expenses\backend\models\Contacts.php at line 76 – yii\base\Object::__construct()
public static function find()
{
return new ContactsSearch(get_called_class());
}
3. in F:\Files\Web\PHP\wamp\www\Php\sites\expenses\backend\models\ContactsSearch.php at line 43 – backend\models\Contacts::find()
public function search($params)
{
$query = Contacts::find();
$dataProvider = new ActiveDataProvider([
'query' => $query
]);
$this->load($params);
...