Reputation: 933
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.
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
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
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