Can you help me out with implementing filters to GridView in Yii2? Right now, my rendered table does not respond to my actions (search GET params are not added, nothing changes if I enter a query to a filter input). Here's my code:
Controller:
$searchModel = new UserSearch();
$dataprovider = $searchModel->search(\Yii::$app->request->get());
return $this->render('index', [
'dataProvider' => $dataprovider,
'searchModel' => $searchModel
]);
Model (UserSearch.php):
public $fullname;
public function rules()
{
return [
[['fullname'], 'safe'],
];
}
public function search($params) {
$query = StUsers::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if(!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->andFilterWhere(['LIKE', 'fullname', $this->fullname]);
return $dataProvider;
}
View:
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
'id',
'fullname'
],
]);
I have the same problem when filtering in DataView. Perhaps the problem is in the client side.
Check again if your jquery called twice on your page ( browser/source code ).
May be your problem related with this also :
jQuery(...).yiiGridView is not a function
There should be no need for a solution since 4 years have passed. But, problem is in next statement:
if(!($this->load($params) && $this->validate())) {
return $dataProvider;
}
Change it to:
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
possibly issue is jquery.min.js
You should referencing not more than once
Try to see if you have repeated.
Related
I have a query in Model Autos getSpecialItems() it is used multiple times in project, but i need add in controller to filter $dataProvider.
How make this whitout write same query again in controller?
Autos.php
public function getSpecialItems()
{
return self::find()->where(['id_category' => 18])->all();
}
controller.php
public function actionIndex()
{
$searchModel = new AutosSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
//need add query here
//$dataProvider->query->$searchModel->getSpecialItems();
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
You have to add filter in to your AutosSearch() model after validate():
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 you need
$query->andFilterWhere([
'id_category' => 18,
]);
I've this code
public function actionIndex() {
$model = new Out();
$searchModel = new VatoutFakturOutSearch();
if (Yii::$app->request->post('hasEditable')) {
$userId = Yii::$app->user->id;
$searchModel->user_id = $userId;
$searchModel->parent_id = $userId;
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->pagination->pageSize = 100;
return $this->render('index', [
'searchModel' => $searchModel,
'model' => $model,
'dataProvider' => $dataProvider,
]);
}
for actionIndex, for showing my index page.
with code above it will show data which has user_id==$userId AND parent_id==$userId.
But that's not what I need, what I need is the page show data which has user_id==$userId OR parent_id==$userId.
How do I can do that?
How do I can set OR condition in queryParams?
Thanks
In your search() method just simply add andWhere() condition:
$query->andWhere(['or',
['user_id' => $this->user_id],
['parent_id' => $this->user_id],
]);
Or in controller:
$dataProvider->query->andWhere(['or',
['user_id' => $userId],
['parent_id' => $userId],
]);
You can use where with or operator
$dataProvider->query->andWhere(['or',
['user_id'=>$user_id],
['parent_id'=>$user_id]
]);
The question is confusing, but I'll explain.
I have this search query from AsistenciaSearch.php
public function search($params)
{
$query = Asistencia::find();
// 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;
}
$query->joinWith('rutAlumno0');
$query->joinWith('idPlanificacion0');
// grid filtering conditions
$query->andFilterWhere([
'idAsistencia' => $this->idAsistencia,
//'idPlanificacion' => $this->idPlanificacion,
]);
$query->andFilterWhere(['like', 'asistencia', $this->asistencia])
->andFilterWhere(['like', 'rutAlumno', $this->rutAlumno])
//->andFilterWhere(['like', 'idPlanificacion', $this->idPlanificacion])
->andFilterWhere(['like', 'alumno.nombreAlumno', $this->nombreAlumno])
->andFilterWhere(['like', 'alumno.apellidoAlumno', $this->apellidoAlumno])
->andFilterWhere(['like', 'alumno.cursoAlumno', $this->cursoAlumno])
->andFilterWhere(['like', 'alumno.establecimientoAlumno', Yii::$app->user->identity->escuelaProfesor]);
return $dataProvider;
}
And this a controller function using the search query in PlanificacionController.php:
public function actionVerasistencia($id)
{
$searchModel = new AsistenciaSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('verasistencia', [
'model' => $this->findModel($id), //findModel from Planificacion
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Both Asistencia and Planificacion are related by using a primary key in Planificacion named idPlanificacion and a foreign key from that model in Asistencia using the same name.
The question is, I need to make merge with another filter, where the $id from findModel($id) is like the $idPlanificacion from the search query, like this:
public function actionVerasistencia($id)
{
$searchModel = new AsistenciaSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('verasistencia', [
'model' => $this->findModel($id),
'searchModel' => $searchModel,
'dataProvider' => $dataProvider->andFilterWhere('like',$id,$this->idPlanificacion),
]);
}
But I got this error:
Getting unknown property: frontend\controllers\PlanificacionController::idPlanificacion
Any solution, please?
$this inside the controller is related to the controller itself
but your are referring to idPlanificacion alias you are referring to a model attribute
could be you want retrive the value by the model eg:
$model = $this->findModel($id)
so could be
public function actionVerasistencia($id)
{
$searchModel = new AsistenciaSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$model = $this->findModel($id);
return $this->render('verasistencia', [
'model' =>$model,
'searchModel' => $searchModel,
'dataProvider' => $dataProvider->andFilterWhere('like',$id,$model->idPlanificacion),
]);
}
I'm trying display and filter data which I got via SQL SUM operator.
I have 2 table employee and department. Table employee contains department_id filed and salary filed. I need display all department and total SUM salary for every department.
I followed this guide, but GridView does not display any data.
Here is action:
public function actionIndex()
{
$searchModel = new DepartmentFrontendSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index',
[
'dataProvider' => $dataProvider,
'searchModel' => $searchModel,
]
);
}
Model:
class DepartmentFrontendSearch extends DepartmentFrontend
public $employee_count;
public $salary;
public function rules() {
return [
[['employee_count','salary','name'], 'safe']
];
}
public function search($params) {
$query = DepartmentFrontend::find();
$subQuery = Employee::find()
->select('department_id, SUM(salary) as salary_amount')
->groupBy('department_id');
$query->leftJoin(['salarySum' => $subQuery], 'salarySum.department_id = id');
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->setSort([
'attributes' => [
'name',
'salary'
]
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
$query->andFilterWhere(['like', 'name', $this->name]);
$query->andWhere(['salarySum.salary_amount' => $this->salary]);
return $dataProvider;
}
GRID:
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'salary_amount',
'employee_count',
'name',
],
]);
So, can anybody tell me what I did wrong?
If You need a filter for the alias salary_amount you should add a specific var for this (do the fact salary_amount is an alias for sum(salary) the var $salary is not useful)
public $employee_count;
public $salary;
public $salary_amount;
otherwise use salary as alias too
the in your filter you are using
$query->andWhere(['salarySum.salary_amount' => $this->salary]);
But salary_amount is the result of an aggregation so you should use having(SUM(salary) = $this->salary_amount)
$query->having('SUM(salary) = ' . $this->salary_amount);
I want to implement a search form. I'm getting search results but when the request is not in the form, Listview displays all data from the table.
How to set conditions so that when the search form is empty an empty Listview is returned?
Models:
public function search($params)
{
$query = Product::find();
$dataProvider = new ActiveDataProvider(['query' => $query]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->andFilterWhere(['title' => $this->title]);
return $dataProvider;
}
Controllers:
public function actionSearch()
{
$searchModel = new SearchForm();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('search', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
form:
<div class="site-search">
<?php
$form = ActiveForm::begin([
'action' => ['search'],
'method' => 'get',])
?>
<?=$form->field($model, 'title')?>
<div class="form-group">
<?=Html::submitButton('Submit', ['class' => 'btn btn-primary'])?>
</div>
<?phpActiveForm::end();?>
</div>
view:
<?php
echo $this->render('_form', ['model' => $searchModel]);?>
<div class="listView">
<?php
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => '_product',]);
?>
</div>
Your problem probably lies with the search model (it's difficult to tell conclusively, as the validation rules of the model are missing). The search function only sets a query condition if the model can be populated from $params. Adding a condition which always fails to the query would fix this.
public function search($params)
{
if (!($this->load($params) && $this->validate())) {
$query = Product::find()->where('1 <> 1');
} else {
$query = Product::find()->where(['title' => $this->title]);
}
return new ActiveDataProvider(['query' => $query]);
}
Alternatively, one could also return a different type of DataProvider:
public function search($params)
{
if (!($this->load($params) && $this->validate())) {
return new yii\data\ArrayDataProvider(['allModels' => []]);
}
$query = Product::find()->where(['title' => $this->title]);
return new ActiveDataProvider(['query' => $query]);
}
However, tt strikes me as strange that one would still want to return a data provider if validation fails. Throwing and catching an error and presenting an error message on validation failure seems like a decent option and might be better than showing only an empty results list.