How to implement single search form in yii2

14,177

I had the same problem and my solution is:

Model

Extend your UserSearch Model with a search parameter

class UserSearch extends User
{
    public $searchstring;
    ...

Enable passing the variable

    public function rules()
    {
        return [
            ...
            [['searchstring'], 'safe'],
        ];
    }

Change your search-Method (beware: the searchfields are combined with orFilterWhere, depends on your needs).

     $query->orFilterWhere(['like', 'fname', $this->searchstring])
        ->orFilterWhere(['like', 'lname', $this->searchstring])
        ->orFilterWhere(['like', 'email', $this->searchstring])
        ->orFilterWhere(['like', 'username', $this->searchstring])
        ->orFilterWhere(['like', 'user_type', $this->searchstring]);

View (could be also layout)

Extend your form with a search-input. You can style the input-field by yourself, this is just an example:

<?php
/* @var $searchModel app\models\UserSearch */
echo $form->field($searchModel, 'searchstring', [
        'template' => '<div class="input-group">{input}<span class="input-group-btn">' .
        Html::submitButton('GO', ['class' => 'btn btn-default']) .
        '</span></div>',
    ])->textInput(['placeholder' => 'Search']);
?>

Controller

Also check for the value of $searchstring after posting the form.

public function actionIndex()
{
    ...
    $searchModel = new UserSearch();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
    ...
    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);
}

That's it.

Share:
14,177
Ethelene Laverne
Author by

Ethelene Laverne

Updated on June 17, 2022

Comments

  • Ethelene Laverne
    Ethelene Laverne almost 2 years

    Yii2 has a searchModel to search each field in the GridView. Is it possible to just create a single search field outside the GridView where the user can input keywords and by the time Search button is hit, the results will display in the GridView based on the keywords entered.

    CONTROLLER

    public function actionIndex()
    {
        $session = Yii::$app->session;
        //$searchModel = new PayslipTemplateSearch();
    
        $PayslipEmailConfig = PayslipEmailConfig::find()->where(['company_id'=> new \MongoId($session['company_id'])])->one();
    
        $payslipTemplateA = PayslipTemplate::find()->where(['company_id' => new \MongoId($session['company_id'])])->andwhere(['template_name' => 'A'])->one();
        $payslipTemplateB = PayslipTemplate::find()->where(['company_id' => new \MongoId($session['company_id'])])->andwhere(['template_name' => 'B'])->one();
    
        $pTemplateModel = PayslipTemplate::find()->where(['company_id' => new \MongoId($session['company_id'])])->all();
        $user = User::find()->where(['_id' => new \MongoId($session['user_id'])])->one();
        $module_access = explode(',', $user->module_access);
    
        //$dataProvider = User::find()->where(['user_type' => 'BizStaff'])->andwhere(['parent' => new \MongoId($session['company_owner'])])->all();
        $searchModel = new UserSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
    
        return $this->render('index', [
            'PayslipEmailConfig' => $PayslipEmailConfig,
            'dataProvider' => $dataProvider,
            'payslipTemplateA' => $payslipTemplateA,
            'payslipTemplateB' => $payslipTemplateB,
            'searchModel' => $searchModel,
        ]);
    }
    public function actionSearchresults($keyword)
    {
        $session = Yii::$app->session;
        if ( $keyword == '') {
            return $this->redirect(\Yii::$app->request->getReferrer());
        } else {
            $user = User::find()->where( [ '_id' => new \MongoId($id) ] )->one(); 
            $searchModel = new PayslipTemplateSearch();
    
            $payslipTemplateA = PayslipTemplate::find()->where(['company_id' => new \MongoId($session['company_id'])])->andwhere(['template_name' => 'A'])->one();
            $payslipTemplateB = PayslipTemplate::find()->where(['company_id' => new \MongoId($session['company_id'])])->andwhere(['template_name' => 'B'])->one();
    
            return $this->render('searchresults', [
                'searchModel' => $searchModel,
                'user' => $user,
                'payslipTemplateA' => $payslipTemplateA,
                'payslipTemplateB' => $payslipTemplateB,
            ]);
        }    
    }
    

    I asked a question connected to this problem here: Main Search Form in Yii2

    It didn't due to some complications in Kartik's Select2 search dropdown widget. Now I switched temporarily to a simple Yii2 search field.

    VIEW

    echo $form->field($model, '_id')->textInput(array('placeholder' => 'search'))->label(false);
    

    MODEL

    <?php
    
    namespace app\models;
    
    use Yii;
    use yii\base\Model;
    use yii\data\ActiveDataProvider;
    use app\models\User;
    
    /**
     * UserSearch represents the model behind the search form about `app\models\User`.
     */
    class UserSearch extends User
    {
        /**
         * @inheritdoc
         */
        public function rules()
        {
            return [
                [[/*'_id',*/ 'creator_id'], 'integer'],
                [['fname', 'lname', 'email', 'username', 'user_type'], '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)
        {
            $session = Yii::$app->session;
    
            $query = User::find();
            $query->where(['user_type' => 'BizStaff'])->andwhere(['parent' => new \MongoId($session['company_owner'])]);
    
            $dataProvider = new ActiveDataProvider([
                'query' => $query,
            ]);
    
            $this->load($params);
    
            if (!$this->validate()) {
                // uncomment the following line if you do not want to any records when validation fails
                // $query->where('0=1');
                return $dataProvider;
            }
    
            $query->andFilterWhere([
                '_id' => $this->_id,
                'creator_id' => $this->creator_id,
            ]);
    
            $query->andFilterWhere(['like', 'fname', $this->fname])
                ->andFilterWhere(['like', 'lname', $this->lname])
                ->andFilterWhere(['like', 'email', $this->email])
                ->andFilterWhere(['like', 'username', $this->username])
                ->andFilterWhere(['like', 'user_type', $this->user_type]);
    
            return $dataProvider;
        }
    }
    

    Do you have any idea on how to I implement a single search? It's kind of a smarter search since it can search everything in the database table based on keywords inputted.

    EDIT

    When I search a keyword, say for example 'hello', it then gives me this url and error after hitting enter key:

    URL:

    http://localhost/iaoy-dev/web/index.php?r=payslip-template%2Fsearchresults&PayslipTemplateSearch%5B_id%5D=hello

    Error message:

    Bad Request (#400) Missing required parameters: id

    Help.