В фреймворке Yii 2.0 встроена поддержка jquery плагина pjax, объединяющего pushState и ajax технологии. Подробнее на гитхабе разработчика.
Для примера сделаем возможность добавления новой Заметки в списке заметок без перезагрузки страницы.
Контроллер
    public function actionIndex()
    {
        $model = new Notes();
        if ($model->load(Yii::$app->request->post()) && $model->save())
        {
            $model = new Notes();
        }
        $searchModel = new NotesSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
            'model' => $model,
        ]);
    }
Шаблоны
index.php
<?php
use yii\helpers\Html;
use yii\widgets\Pjax;
use yii\grid\GridView;
/* @var $this yii\web\View */
/* @var $searchModel app\modules\notes\models\NotesSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('app', 'Notes');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="notes-index">
    <h1><?= Html::encode($this->title) ?></h1>
    <?= $this->render('_form',[
        'model' => $model,
    ]) ?>
<?php Pjax::begin(['id' => 'notes']) ?>
    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
            'id',
            'note:ntext',
            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>
<?php Pjax::end() ?>
</div>
_form.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $model app\modules\notes\models\Notes */
/* @var $form yii\widgets\ActiveForm */
?>
<?php
    $this->registerJs(
        '$("document").ready(function(){
            $("#new_note").on("pjax:end", function() {
            $.pjax.reload({container:"#notes"});  //Reload GridView
        });
    });'
    );
?>
<div class="notes-form">
<?php yii\widgets\Pjax::begin(['id' => 'new_note']) ?>
    <?php $form = ActiveForm::begin(['options' => ['data-pjax' => true]]); ?>
    <?= $form->field($model, 'note')->textarea(['rows' => 6]) ?>
    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
    </div>
    <?php ActiveForm::end(); ?>
    <?php Pjax::end(); ?>
</div>
Результат
Что мы сделали
1. В действии actionIndex добавили сохранение данных новой Заметки, если они пришли в запросе post:
if ($model->load(Yii::$app->request->post()) && $model->save())
        {
            $model = new Notes();
        }
2. Обернули виджеты GridView и ActionForm в пиджак:
<?php Pjax::begin(['id' => 'notes']) ?> <?php yii\widgets\Pjax::end(); ?>
3. Добавили небольшой скрипт, обновляющий GridView после добавления новой записи:
<?php
    $this->registerJs(
        '$("document").ready(function(){
            $("#new_note").on("pjax:end", function() {
            $.pjax.reload({container:"#notes"});  //Reload GridView
        });
    });'
    );
?>
							

а использование JS в виде — это вообще нормально?
А где нормально? В контроллере или модели?
нормально — в js-файлах
Я имею ввиду, что $this->registerJs() — это ужасно
Почему?
потому что файлы представления итак сложно содержать в нормальном виде:
php-код, встроенные виджеты Yii2, остаётся только ещё стили подобавлять до кучи и JS
а когда JS-кода станет много, что-то разобрать в коде станет просто нереально
В статье демонстрируется пример, ничего не мешает вам поместить js в отдельный файл
Спасибо! Здорово. $this->registerJs() — нормальная практика, для того и создан))
Спасибо, пост в тему. Использования registerJs тоже избегаю, не люблю мешать логику разных модулей и языков
Добрый день, не работает фильтрация. Указал $query->andFilterWhere([
‘id’ => $this->id,
‘post_id’ => $this->post_id,
но так и отображаются абсолютно все записи из таблицы. Если указываю ‘post_id’ => ‘1’, то фильтр работает нормально. Пожалуйста подскажите в чем проблема.
Смотрите, что приходит в $this->post_id. Без кода представления и searchModel сложно что-то еще посоветовать)
Хотя, вот статья про фильтрацию: http://nix-tips.ru/yii2-sortirovka-i-filtr-gridview-po-svyazannym-i-vychislyaemym-polyam.html
Можно сделать проще, просто форму и грид запихнуть в один pjax и все, а контроллер будет выглядеть так:
public function actionIndex()
{
$modelProfit = new Profit();
if ($modelProfit->load(Yii::$app->request->post()) && $modelProfit->save()) {
$modelProfit = new Profit();
$modelProfit->user_id = Yii::$app->user->id;
$searchModel = new ProfitSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render(‘index’, [
‘searchModel’ => $searchModel,
‘dataProvider’ => $dataProvider,
‘modelProfit’ => $modelProfit,
]);
}else {
$modelProfit = new Profit();
$modelProfit->user_id = Yii::$app->user->id;
$searchModel = new ProfitSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render(‘index’, [
‘searchModel’ => $searchModel,
‘dataProvider’ => $dataProvider,
‘modelProfit’ => $modelProfit,
]);
}
}
Тут есть лишний код, но думаю суть ясна.
Ситуация:
есть сообщения и есть форма,.. навешал pjax на форму,.. после pjax:end делаю reload контейнера с сообщениями,..
НО есть 1 проблемка… после всего этого при втором уже заполнении форму форма не уходил через как прежде… а происходит обычная перезагрузка страницы.