Optional GridView Pagination


(DBCreator) #1

Is there a way to allow the user to select whether or not pagination should be used. By default I’d like to paginate it (this I have working perfectly), but there are instances, when they perform a filter on the data and it would be better to display all the records rather than breaking it across pages. Is there a way to gain this type of control?


(Pawel) #2

Pagination is not defined in the GridView - it’s a property of DataProvider.

Take a look at Guide section for GridView - there is ActiveDataProvider instantiated with pagination property set.

$dataProvider = new ActiveDataProvider([
    'query' => Post::find(),
    'pagination' => [
        'pageSize' => 20,
    ],
]);
echo GridView::widget([
    'dataProvider' => $dataProvider,
]);

In this example Pagination object is instantiated with pageSize property set to 20 which means that for this data each page will contain maximum 20 results. The $dataProvider object is then passed to the GridView widget.

By setting pagination to false like:

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

you can switch pagination off for the DataProvider that can be then used in GridView.


(DBCreator) #3

You are entirely correct. I’m sorry for not having paid more attention to how everything is setup.

Now, I did a very brief test and using

'pagination' => false,

works beautifully. I thought I could add something like Pagination to the search params to control it, but I’m obviously doing it wrong. Could you provide more guidance on how to implement it. I was think a simple check box to enable/disable pagination.

And thank you for your help, it is greatly appreciated!

Update
I’ve managed to get the model search to accept an extra parameters and use it to activate, or not, the pagination. The last piece of the puzzle is how to integrate a checkbox on the index page that will be submitted with the filter parameters. If you could help me with this aspect I’d be very grateful. I was thinking a row above the existing Filter row which would have the Paginate checkbox. Please tell me if this is the right concept or if I’ve taken a wrong turn and there’s a better approach. This is all very new to me.


(Softark) #4

If you have used Gii’s CRUD generator to implement your index page and you are using the search form, then you can add an additional field in the search form.

I would do it using in this way - using a dropDownList instead of a checkbox:

  1. search model
public function search($params, $pageSize = 10)
{
    ...
    'pagination' => [
        'pageSize' => $pageSize,  // no pagination if it is 0
    ],
    ...
  1. controller
public function actionIndex($pageSize = 10)
{
    $searchModel = new SomeSearch();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams, $pageSize);
    return $this->renderPartial('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
        'pageSize' => $pageSize,
    ]);
}
  1. index.view
    <h1><?= Html::encode($this->title) ?></h1>
    <?php echo $this->render('_search', ['model' => $searchModel, 'pageSize' => $pageSize]); ?>

  1. _search.php
    <?php $form = ActiveForm::begin([
        'action' => ['index'],
        'method' => 'get',
    ]); ?>

    <?= $form->field($model, 'xxxx') ?>
    ...
    <div class="form-group">
        <?= Html::label('Page Size', ['class' => 'control-label']) ?>
        <?= Html::dropDownList('pageSize', $pageSize, 
            [0 => 'ALL', 10 => '10', 20 => '20', 50 => '50'],
            ['class' => 'form-control']) ?>
    </div>
    <div class="form-group">
        <?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
        <?= Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
    </div>

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

(DBCreator) #5

Ok, I’ve got it somewhat working, but this make a separate filter from the Gridview Filter and then seem independent of one another.

Is there a way to tie them together?

Also, the Gridview filter automatically filters after any change, can that be true of the pagination dropdown rather than needing to use the Search button?


(Softark) #6

As to the 2nd question, I usually add these lines to _search.php in order to improve the user experience.

$this->registerJs("
$('#xxxx-search-form').on('change', 'select', function(event){
    $('#xxxx-search-form').submit();
    event.preventDefault();
});
$('#xxxx-search-form').on('click', '#clear-btn', function(event){
    $('#xxxx-search-form input').val('');
    $('#xxxx-search-form select').val('');
    $('#xxxx-search-form').submit();
    event.preventDefault();
});
");

where xxxx-search-form stands for the ID of the search form.

And as to the 1st question, I couldn’t come up with a satisfactory solution so far.

I tried to add a form that has a dropDownList (or a checkbox) before the “summary” text (i.e., ‘Showing 1-10 of 999.’ or something like that), or in the header cell of the action column. It worked somehow, but it was far from complete. Among other things, I couldn’t make it to work like other filters in the Gridview, preserving other filter values.
But it should be possible, anyway.


(DBCreator) #7

Thank you for all of your help.

I am surprised that this isn’t a default option in the Gridview.

If ever you come up with any improvements, ideas, I would love to hear.


(Softark) #8

Although I don’t have experience with it, but I think you may consider using Kartikv’s enhanced GridView.

Krajee : GridView > Toggle Grid Data

Kartikv’s Yii2 extensions in general are proved to be useful by many people.