* @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); } }