Yii2 Pjax is not working, reloads the entire page

8.8k views Asked by At

When a file_get_contents($url) is used inside a action and when that action is loaded using Pjax, the entire page reloads.

In controllers/SiteController.php

public function actionAbout()
{
    $url = 'http://api.dar.fm/topsongs.php?q=Music&page_size=20';
    $xml = file_get_contents($url);

    Yii::$app->view->params['xmldata'] = $xml;
    return $this->render('about');
}

In layouts/main.php

<?php Pjax::begin(); ?>
   <a href="/yiidev/web/index.php?r=site/home">Home</a> 
   <a href="/yiidev/web/index.php?r=site/about">About</a>
   <a href="/yiidev/web/index.php?r=site/contact">Contact us</a>  
<?php Pjax::end(); ?>

For Home and Contact link, only the area between pjax begin() and end() is updated but for About link the entire page reloads.

If i remove the file_get_contents() call from from actionAbout() the page reload is not happening. I believe the problem is something related to getting contents from external url using file_get_contents()

3

There are 3 answers

0
Vivek Palanisamy On

The issue was due to ajax timeout. file_get_contents() took more time to execute, as it was reading a external url and timeout happens. The issue was resolved by increasing timeout vaue as below.

Pjax::begin(['timeout' => 5000 ]);

Refer https://github.com/yiisoft/yii2/issues/8819

0
Ankit Singh On

Use <?php Pjax::begin(['id' => 'grid', 'timeout' => 0]) ?> to set infinite timeout or use <?php Pjax::begin(['id' => 'grid', 'timeout' => 5000]) ?>. Here time is in milliseconds. If the query takes more time than defined in timeout, page reload is triggered. Default timeout is 1000 milliseconds. you can verify it in Pjax Class file.

0
IStranger On

Additionally to previous answer I propose my variant to solve problem with timeout - overrided version of Pjax class (I use it in all my projects). This may help to prevent cases when you forget add timeout in Pjax constructor.

/**
 * Custom Pjax with incremented timeout.
 * JS for Pjax updating:
 *  <code>
 *      $.pjax.defaults.timeout = false;             // For JS use case yor should manual override default timeout.
 *      $.pjax.reload({container: '#pjaxId'});
 *
 *      // OR
 *      $.pjax.reload('#pjaxId', {timeout : false});
 *
 *      // OR for gridview with search filters
 *      $('.grid-view').yiiGridView('applyFilter'); // Thats true only if you have search Filters
 *  </code>
 *
 * Note: In more cases ID of widget should be static, because widgetId is autoincremented and browser version of page may be not up-to-date.
 */
class Pjax extends \yii\widgets\Pjax
{
    /**
     * @var int Timeout {@link \yii\widgets\Pjax::$timeout}.
     *          For JS use case yor should manual override defaults (  $.pjax.defaults.timeout = false;  ).
     */
    public $timeout = 30000;
}

See more details here: yii2 how to use pjax when hyperlink is not in pjax