Guwanch Guwanch - 1 month ago 55
PHP Question

How to use custom filter for yii2 ListView widget?

In my controller I rendered $dataProvider

$searchModel = new StudentSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);

return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);


Here is search function of StudentSearch

public function search($params)
{
$query = Student::find();

$query->andFilterWhere([
'student_id' => $this->student_id,
'age' => $this->age,

]);

$query->andFilterWhere(['like', 'firstname', $this->firstname]);

$dataProvider = new ActiveDataProvider([
'query' => $query,
]);


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

return $dataProvider;
}


in view I used $dataprivider in ListView widget like below

<div class="listView">

<?php
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => '_student_list',
]);
?>

</div>


In '_student_list.php' I listed students

my filters

<div class="listFilter">
<input type="text" name="firstname"/>
<input type="text" name="age"/>
</div>


Now I want filter Students by firstname or age. How can I do this? If you have any solution to this problem please help. Thank you.

Answer

1) Add filter form to your view:

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $form yii\widgets\ActiveForm */
?>

<div class="student-form">
    <?php $form = ActiveForm::begin(['method' => 'get']); ?>

    <?= $form->field($searchModel, 'firstname') ?>

    <?= $form->field($searchModel, 'age') ?>

    <div class="form-group">
        <?= Html::submitButton('Apply', ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>
</div>

2) Prepare StundentSearch model to return dataProvider depending on received GET parameters.

These attributes must be specified in rules in order to massively assign them.

public function rules()
{
    return [
        ['firstname', 'string'],
        ['age', 'integer'],
    ];
}

public function scenarios()
{
    // bypass scenarios() implementation in the parent class
    return Model::scenarios();
}

public function search($params)
{
    $query = Student::find();

    $dataProvider = new ActiveDataProvider(['query' => $query]);

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

    $query->andFilterWhere(['age' => $this->age])
        ->andFilterWhere(['like', 'firstname', $this->firstname]);

    return $dataProvider;
}