Ragheb AlKilany
Ragheb AlKilany

Reputation: 933

Ajax Filtering with GridView in Yii

I want to use PJax in Yii Grid View, not with the associative filter that comes inside the Grid View, but with the Search Filter that's outside it, so it can filter the results inside.enter image description here

Here is the source of the index file:

<div class="cars-index">

<h1><?= Html::encode($this->title) ?></h1>


<?php  echo $this->render('_search', ['model' => $searchModel]); ?>

<p>
    <?= Html::a('Create Cars', ['create'], ['class' => 'btn btn-success']) ?>
</p>


<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        'id',
        'name',
        ['attribute' => 'code',
        'label' => 'Colour',
        'format' => 'raw',
        'value' => 'colour',
        'contentOptions' => function ($model, $key, $index, $column){
            return ['style' => ' text-align: center; width: 100px;color:white;background-color:#'. $model -> code];
        },
        'headerOptions' => ['style' => 'text-align: center;'],
        ],
        'price',
        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>

Am I supposed to create an active form just for the part I want to filter? Or is there another way?

Upvotes: 2

Views: 5671

Answers (2)

LihO
LihO

Reputation: 42083

In your filter view:

<div id="myFilter">
    <?php $form = ActiveForm::begin([
        'id' => 'myFilterForm',
        'method' => 'post',
        'action' => [...],
    ]); ?>
    ...
</div>

And make sure you render filter between Pjax::begin and Pjax::end

Yet here comes the trick. If your server does not respond within default timeout, Pjax gets ignored and page reloaded, so make sure the timeout is big enough:

<?php Pjax::begin([
    'id'=>'myGrid',
    'timeout' => 10000,                    // <------------ THIS !!!!!!!
    'formSelector' => '#myFilterForm'
]); ?>

<?= $this->render('myFilter', ['model' => $searchModel]); ?>

<?= GridView::widget([
    ...
]); ?>
<?php Pjax::end(); ?>

Also in your controller, you might want to "reset" the search model, so only data from the request used are attributes actually used by search:

public function actionSearch()
{
    $searchModel = new MySearch();

    if ($searchModel->load(Yii::$app->request->post())) {
        $searchModel = new MySearch(); // "reset"
        $dataProvider = $searchModel->search(Yii::$app->request->post());
    } else {
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
    }

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

Hope this helps. Cheers!

Upvotes: 0

ScaisEdge
ScaisEdge

Reputation: 133360

If You can't simply add the filter to you table like this

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,

I suggest you use a proper action and a proper search function called by submit based on a specified active form

for action form eg:

<?php $form = ActiveForm::begin([
   'id' => 'search-form',
   'method' => 'post',
   'action' => ['controller/yourAction']
]); ?>

in the controller

 $model = new yourActiveForm();

    if ($model->load(Yii::$app->request->post()) ) {

      $dataProvider = $searchModel->search( [ 'yuorSearchModel'=> ['your_att1' => $model->yourValue1]]);
   }

then your render

Conforming to yii2 doc

Pjax only deals with the content enclosed between its begin() and end() calls, called the body content of the widget. By default, any link click or form submission (for those forms with data-pjax attribute) within the body content will trigger an AJAX request. In responding to the AJAX request, Pjax will send the updated body content (based on the AJAX request) to the client which will replace the old content with the new one. The browser's URL will then be updated using pushState. The whole process requires no reloading of the layout or resources (js, css).

You may configure $linkSelector to specify which links should trigger pjax, and configure $formSelector to specify which form submission may trigger pjax.

You must add the

<?php Pjax::begin(); ?> 
 .... your active form

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

and configure the proper $linkSelect and $formSelector

Upvotes: 2

Related Questions