Alena
Alena

Reputation: 3

How to display search results in Yii2

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>

Upvotes: 0

Views: 1209

Answers (1)

tarleb
tarleb

Reputation: 22659

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.

Upvotes: 2

Related Questions