mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 06:15:19 +08:00
145 lines
3.7 KiB
PHP
145 lines
3.7 KiB
PHP
<?php
|
|
/**
|
|
* @link http://www.yiiframework.com/
|
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
|
* @license http://www.yiiframework.com/license/
|
|
*/
|
|
|
|
namespace yii\widgets;
|
|
|
|
use Yii;
|
|
use yii\base\Widget;
|
|
use yii\helpers\Html;
|
|
use yii\helpers\Json;
|
|
use yii\web\Response;
|
|
|
|
/**
|
|
* Pjax is a widget integrating the [pjax](https://github.com/defunkt/jquery-pjax) jQuery plugin.
|
|
*
|
|
* Pjax captures the link clicks in the content enclosed between its [[begin()]] and [[end()]] calls,
|
|
* turns them into AJAX requests, and replaces the enclosed content with the corresponding AJAX response.
|
|
*
|
|
* The following example makes the [[\yii\gridview\GridView]] widget support updating via AJAX:
|
|
*
|
|
* ```php
|
|
* use yii\widgets\Pjax;
|
|
*
|
|
* Pjax::begin();
|
|
* echo GridView::widget([...]);
|
|
* Pjax::end();
|
|
* ```
|
|
*
|
|
* Clicking the sorting and pagination links in the grid will trigger AJAX-based updating of the grid content.
|
|
* Moreover, if the grid view has turned on filtering, the filtering will also be performed via AJAX.
|
|
*
|
|
* By default, Pjax enables [[enablePushState|push state]], which means the browser's current URL will
|
|
* be updated when an AJAX request is made by Pjax.
|
|
*
|
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
|
* @since 2.0
|
|
*/
|
|
class Pjax extends Widget
|
|
{
|
|
/**
|
|
* @var array the HTML attributes for the widget container tag.
|
|
*/
|
|
public $options = [];
|
|
/**
|
|
* @var string the jQuery selector of the links that should trigger pjax requests.
|
|
* If not set, all links within the enclosed content of Pjax will trigger pjax requests.
|
|
* Note that the pjax response to a link is a full page, a normal request will be sent again.
|
|
*/
|
|
public $linkSelector;
|
|
/**
|
|
* @var boolean whether to enable push state.
|
|
*/
|
|
public $enablePushState = true;
|
|
/**
|
|
* @var boolean whether to enable replace state.
|
|
*/
|
|
public $enableReplaceState = false;
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function init()
|
|
{
|
|
if (!isset($this->options['id'])) {
|
|
$this->options['id'] = $this->getId();
|
|
}
|
|
|
|
ob_start();
|
|
ob_implicit_flush(false);
|
|
|
|
if ($this->requiresPjax()) {
|
|
$view = $this->getView();
|
|
$view->clear();
|
|
$view->beginPage();
|
|
$view->head();
|
|
$view->beginBody();
|
|
}
|
|
echo Html::beginTag('div', $this->options);
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function run()
|
|
{
|
|
echo Html::endTag('div');
|
|
if ($requiresPjax = $this->requiresPjax()) {
|
|
$view = $this->getView();
|
|
$view->endBody();
|
|
$view->endPage(true);
|
|
}
|
|
|
|
$content = ob_get_clean();
|
|
|
|
if ($requiresPjax) {
|
|
// only need the content enclosed within this widget
|
|
$response = Yii::$app->getResponse();
|
|
$level = ob_get_level();
|
|
$response->clearOutputBuffers();
|
|
$response->setStatusCode(200);
|
|
$response->format = Response::FORMAT_HTML;
|
|
$response->content = $content;
|
|
$response->send();
|
|
|
|
// re-enable output buffer to capture content after this widget
|
|
for (; $level > 0; --$level) {
|
|
ob_start();
|
|
ob_implicit_flush(false);
|
|
}
|
|
} else {
|
|
$this->registerClientScript();
|
|
echo $content;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return boolean whether the current request requires pjax response from this widget
|
|
*/
|
|
protected function requiresPjax()
|
|
{
|
|
$headers = Yii::$app->getRequest()->getHeaders();
|
|
return $headers->get('X-Pjax') && ($selector = $headers->get('X-Pjax-Container')) === '#' . $this->getId();
|
|
}
|
|
|
|
/**
|
|
* Registers the needed JavaScript.
|
|
*/
|
|
public function registerClientScript()
|
|
{
|
|
$id = $this->options['id'];
|
|
$options = Json::encode([
|
|
'push' => $this->enablePushState,
|
|
'replace' => $this->enableReplaceState,
|
|
]);
|
|
$linkSelector = Json::encode($this->linkSelector !== null ? $this->linkSelector : '#' . $id . ' a');
|
|
$view = $this->getView();
|
|
PjaxAsset::register($view);
|
|
$js = "jQuery(document).pjax($linkSelector, \"#$id\", $options);";
|
|
$view->registerJs($js);
|
|
}
|
|
}
|