Returning a dataProvider in an ajax request

I have a method returning a DataProvider to a Javascript function, I need to return the dataProvider for a given

. How do I do? I’ve tried using pAjax, but to no avail.

Controller:

public function actionFilterProtocolo($text = null){
    $protocolo = Protocolo::find();
    if (!empty($id)) {
        $protocolo->where(['fk_contribuinte' => $id]);
    }
    $protocolo->filterWhere(['like', 'numero', $text]);

    $dataProvider = new ActiveDataProvider([
        'query' => $protocolo,
        'pagination' => [
            'pageSize' => 10,
        ],
        'sort' => [
            'defaultOrder' => [
                'data_abertura' => SORT_DESC
            ]
        ],
    ]);

    return Json::encode([
        'status' => 200,
        'dataProvider'=> $dataProvider,
    ]);
}

JS

function buscarProtocolo(){
var result = $('#pesquisar').val();
if(result != null){
    var ajaxUrl = $('#formProtocolo').data().url;
    $.ajax({
        method: 'GET',
        url: ajaxUrl + '?text=' + result,
        beforeSend: function () {
            $(".preloader").fadeIn();
        },
        processData: false,
    }).then(function (response) {
            var retorno = JSON.parse(response);
            if (retorno.status === 200) {
                console.log(retorno);
                $('#list-protocolos').html(retorno.content);
                $.pjax.reload({container: '#list-protocolos-pjax'});
            } else {
                $('#list-protocolos').html(retorno.content);
            }
            $(".preloader").fadeOut();
        });
  }
}

view: (div that will receive the dataProvider)

<div class="protocolo-index" id="protocolos">
    <div class="row">
        <div class="col-md-12">
            <?php Pjax::begin([
                'id' => 'list-protocolos-pjax'
            ]) ?>
            <?= GridView::widget([
                'dataProvider' => $dataProvider,
                'options' => [
                    'data-url' => \yii\helpers\Url::to(['/protocolo/view-ajax']),
                    'id' => 'list-protocolos',
                    'vAlign' => 'middle',
                ],

Hi @vinimatos,

You can’t return an ActiveDataProvider itself as a response. It works only in server side, and no javascript in client side can use it directly.

Thank you, @softark . I was trying to customize a search where the return would be a json with a dataProvider. This query would be via ajax

A DataProvider is not a set of data, but a PHP object that provides a set of data. It is usually used by some data widget like GridView and ListView to create a grid or list in HTML format. All of this happens in server side.
If you want to update a grid by ajax, you have to return the updated html data of the grid as a response.

BTW, I would like to recommend you revisit Gii’s CRUD generator before you try to do it by yourself. You just have to check Enable Pjax.

1 Like

I have my code generated by gii. How do I enable pjax? I’m already loading it into index.php, as it may have posted right up.

This is CRUD Generator. You’ll see “Enable Pjax” checkbox.

I say enable without having to run gii. Already have the whole view structure ready. I do not want to have to run gii, not to overwrite other forms

You can run Gii without modifying your current code. Just preview it.

The change will occur in “index.php” view script.
You’ll see Pjax::begin() and Pjax::end(). That’s it.

<?php
...
$this->title = 'Slips';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="slip-index">

    <h1><?= Html::encode($this->title) ?></h1>
    <?php Pjax::begin(); ?>
    <?php // echo $this->render('_search', ['model' => $searchModel]); ?>

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

    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],

            'id',
            'date',
            'in_out',
            'item_id',
            'type_id',
            //'abstract',
            //'amount',
            //'created_at',
            //'updated_at',

            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>
    <?php Pjax::end(); ?>
</div>

I also recommend you uncomment the following line:

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

This will add a search form on top of the grid. You could use it to filter your Protocolo model by some text.

actionIndex() remains the same even when you have enabled Pjax. It will return the same content as a response for Pjax request. The javascript provided by Yii will use only the content enveloped in Pjax widget to update the DOM in the client browser … yes, you don’t need to write a javascript for Pjax by yourself. Pjax widget will automatically do it.

And if you want to optimize your code a little, you can modify your actionIndex like the following.

    public function actionIndex()
    {
        $searchModel = new SlipSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

       if (Yii::$app->request->isPjax) {
           return $this->renderPartial('index', [
               'searchModel' => $searchModel,
               'dataProvider' => $dataProvider,
           ]);
       } else {
           return $this->render('index', [
               'searchModel' => $searchModel,
               'dataProvider' => $dataProvider,
           ]);
       }
    }

Now we are returning the output HTML without the wrapping layout using renderPartial for Pjax request.

1 Like

Thank you, @softark . :+1::sorriso:

1 Like