D
D
Dmitry2016-12-04 02:11:56
Yii
Dmitry, 2016-12-04 02:11:56

Search form output in yii2 template?

Goodnight.
We need to organize a search on the site. The form should be located on all pages of the site.
I made a separate file with the form, which I include in layouts/main.
I can't figure out how to correctly pass the search model to the form.
Form file (shortened form code)

<?php $form = ActiveForm::begin([
            'method' => 'get',
            'action' => ['/search-flights'],
        ]) ?>
        <div class="secondRow clearfix">

            <?= $form->field($model, 'city_from')->widget(Select2::className())->label(false) ?>
            <?= $form->field($model, 'date_from')->widget(DatePicker::className())->label(false) ?>
            <?= Html::input('submit',null,'Найти билеты', ['class' => 'peopleSubmit']) ?>

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

For search, I made a separate controller with one action.
class SearchController extends Controller
{
    public function actionSearchFlights()
    {
            $searchModel = new FlightsSearch();
            $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

            return $this->render('search-flight', [
                'dataProvider' => $dataProvider,
            ]);
    }
}

search model.
<?php

namespace app\modules\main\models\search;

use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\modules\airlines\models\Flights;

class FlightsSearch extends Model
{
    public $city_from;
    public $date_from;

    public static function tableName()
    {
        return '{{%flights}}';
    }

    public function rules()
    {
        return [
            ['date_from','city_from'], 'required'],
            ['city_from', 'integer'],
            ['date_from', 'date', 'format' => 'php:d.m.Y' ],
        ];
    }

    public function attributeLabels()
    {
        return [
            'city_from' => Yii::t('module', 'SEARCH_CITY_START'),
            'date_from' => Yii::t('module', 'SEARCH_DATE_START'),
        ];
    }

    public function search($params)
    {

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

        $this->load($params);
        if(!$this->validate()){
            /*$query->where('0=1');*/
            return $dataProvider;
        }

        $query->andFilterWhere(['>=', 'date_start', $this->date_from ? strtotime($this->date_from . ' 00:00:00') : null])
              ->andFilterWhere(['=', 'city_start_id', $this->city_from])
        return $dataProvider;

    }
}

I connect the form in the template (I understand that this is not the way to transfer the model)
<?= $this->render('includes/_header', ['model' => new FlightsSearch()]); ?>

Layout main is used, in addition to SearchController, in three more controllers.
I thought about making a widget where to connect the form and search the database. But, as I understand it, after searching for information on the forums, it is not recommended to directly access the database in the widget, you can only transfer the result of the query to the database to the widget.
The documentation says:
When creating widgets, you should adhere to the basic principles of the MVC concept. In general, the main logic should be located in the widget class, while separating the code responsible for the markup into views.

So how do you do it right? So that the search model is passed to the widget and the form is not cleared after the search is completed (the entered data remains in the fields)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Maxim Timofeev, 2016-12-04
@slo_nik

It makes sense to make a widget if the form needs to be parameterized, while the model can also be transferred to it.
But in your case, it is more logical to get the model directly in the view with the form

<?php 
$model = new FlightsSearch();
$form = ActiveForm::begin([
            'method' => 'get',
            'action' => ['/search-flights'],
        ]) ?>
        <div class="secondRow clearfix">

            <?= $form->field($model, 'city_from')->widget(Select2::className())->label(false) ?>
            <?= $form->field($model, 'date_from')->widget(DatePicker::className())->label(false) ?>
            <?= Html::input('submit',null,'Найти билеты', ['class' => 'peopleSubmit']) ?>

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

Moreover, yii\base\DynamicModel is probably more appropriate here, there is an example in the docs, just for implementing the search:
www.yiiframework.com/doc-2.0/yii-base-dynamicmodel.html

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question