skip to Main Content

I have a controller in Yii2 app with the following actions:

private function actionPagination($query)
    {
        $count = $query->count();

        $pagination = new Pagination([
            'defaultPageSize' => 10,
            'totalCount' => $count,
        ]);

        $books = $query
            ->orderBy('id')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return [$books, $pagination];
    }


    public function actionIndex()
    {
        $query = Books::find();

        list($books, $pagination) = $this->actionPagination($query);

        return $this->render('index', [
            'books' => $books,
            'pagination' => $pagination,
            'totalPages' => max(1, ceil($pagination->totalCount / $pagination->pageSize)),
        ]);
    }


    public function actionFilter()
    {

        $query = Books::find();
        $genres = Genres::find()->select(['genre_name', 'id'])->orderBy('genre_name')->indexBy('id')->column();
        $authors = Authors::find()->select(['concat(first_name, " ", last_name)', 'id'])->orderBy('id')->column();
        $authors = array_combine(range(1, count($authors)), $authors);

        $searchModel = new Books();
        $requestParams = Yii::$app->request->queryParams;

        if ($searchModel->load($requestParams)) {
            if ($searchModel->year_filter) {
                $query->andWhere(['year' => $searchModel->year_filter]);
            }
            if ($searchModel->genre_filter) {
                $query->andWhere(['genre_id' => $searchModel->genre_filter]);
            }

            if ($searchModel->author_filter) {
                $query->joinWith('links')
                    ->andWhere(['links.author_id' => $searchModel->author_filter]);
            }
        }

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

And I have a form:

  <?php $form = ActiveForm::begin([
    'action' => ['filter'],
    'method' => 'get',
    'options' => ['id' => 'filter-form']
  ]); 
  ?>

  <?= $form->field($searchModel, 'year_filter')->textInput(['id' => 'year-filter-input']) ?>

  <?= $form->field($searchModel, 'genre_filter')->dropDownList(
    $genres,
    [
      'prompt' => 'All genres',
      'id' => 'genre-filter-select'
    ]
  ) ?>

<?= $form->field($searchModel, 'author_filter')->dropDownList(
    $authors,
    [
        'prompt' => 'All authors',
        'id' => 'author-filter-select'
    ]

) ?>

  <div class="form-group">
    <?= Html::submitButton('Filtering', ['class' => 'btn btn-primary']) ?>
    <?= Html::button('Reset filter', [
      'class' => 'btn btn-outline-secondary reset-filter',
      'type' => 'button'
    ]) ?>
  </div>

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

When I try to load the page I’m getting the following error:

Undefined variable $searchModel

I want to create $searchModel only after im pressing ‘Filtering’.

Or should I use another method?

i tried the code that i listed.

2

Answers


  1. Add $searchModel at actionIndex()

    public function actionIndex()
    {
        $query = Books::find();
    
        list($books, $pagination) = $this->actionPagination($query);
        $searchModel = new Books();
    
        return $this->render('index', [
            'books' => $books,
            'pagination' => $pagination,
            'totalPages' => max(1, ceil($pagination->totalCount / $pagination->pageSize)),
            'searchModel' => $searchModel,
        ]);
    }
    
    Login or Signup to reply.
  2. Your Form need the $searchModel from somewhere.
    in order to render the form so you have to pass it to your view like your filter does

    public function actionIndex()
        {
            $query = Books::find();
    
            list($books, $pagination) = $this->actionPagination($query);
    
            $searchModel = new Books();
    
            return $this->render('index', [
                'books' => $books,
                'pagination' => $pagination,
                'totalPages' => max(1, ceil($pagination->totalCount / $pagination->pageSize)),
                'searchModel' => $searchModel
            ]);
        }
    

    I want to create $searchModel only after im pressing ‘Filtering’.

    again you need the model to render the form so you either create it or you only render the form if the model exists.

    // in your index.php
    
    if ($searchModel) {
     /** 
     * your form here or $this->render('_form');
     **/
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search