Обновление родительского окна с сохранением flash

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Закрыто
Аватара пользователя
vityachis
Сообщения: 3
Зарегистрирован: 2016.02.01, 11:11
Контактная информация:

Обновление родительского окна с сохранением flash

Сообщение vityachis »

В общем дело такое: Есть страница, на ней есть кнопка которая в свою очередь открывает модальное окно (с iframe внутри) и подгружает в него другой екшен (actionCreateNewPost), в котором есть форма, после того как форму заполняешь и нажимаешь submit, данные отправляются в actionCreateNewPost и все естественно сохраняется, модальное окно скрывается (display:none;), а iframe становится пустым, после чего вверху страницы появляется flash сообщение.
В чем состоит задача и что не так: После сохранения данных, нужно обновить страницу (родительское окно), но при этом после того как будет понятно что запись была создана. Если просто с помощью js обновить страницу, то flash пропадает и человек не поймет произошло изменение на странице или нет и сохранились ли введенные данные.
Решение должно быть применимо ко всем страницам, а не только к данной.
Из вариантов были такие:
  • Сохранять сообщение в сессию и потом выводить их непосредственно из сессии, но такой вариант требует много манипуляций и возможно будет тяжело применим для других страниц сайта
  • Сохранить сообщение открытое, но после загрузки страницы его скрывать средствами js, в этом возникает проблема, а точнее в том что при загрузке или медленном интернете сообщение может быть видно и это плохо.
  • еще один вариант, что при отображении сообщения нужен какой-то параметр передать (как вариант в get), но тогда нужно придумать что бы при ручном обновлении страницы, сообщение это не оставалось
И собственно код:
Controller

Код: Выделить всё

// Главный action
public function actionUpdate($id)
{
    $model = $this->loadModel($id);
    $this->pageHeading = 'Update Client #' . $model->id . ' "' . $model->username . '"';

    if (isset($_POST['Client'])) {
        $model->attributes = $_POST['Client'];
        if ($model->save()) {
            flash('success', 'Client Updated Successfully');
            $this->redirect(array('update', 'id' => $id));
        } else
            flash('error', 'Error Updating Client');
    }

    $this->render('update', array(
        'model'     => $model,
    ));
}

// Action модального окна
public function actionCreateNewPost($id)
{
    $model = new Post();

    if (isset($_POST['Post'])) {
        $model->attributes = $_POST['Post'];
        if ($model->save()) {
            flash('success', 'Created Successfully');
            $this->redirect(array('update', 'id' => $id));
        } else {
            flash('error', 'Error Creating');
        }
    }

    $this->render('_form_create_new_post', array(
        'model' => $model,
    ));
}
View:

Код: Выделить всё

<?php

/** - View: _form  - **/
// Кнопка для вывода модального окна
$createUrl = Yii::app()->createUrl('client/createNewPost', array("asDialog" => 1, "id" => $model->id));
$label     = 'Create New';
echo $this->widget('bootstrap.widgets.TbButton', array(
    'label'       => $label,
    'type'        => 'primary',
    'url'         => 'javascript:void(0)',
    'size'        => 'mini',
    'htmlOptions' => array(
        'onclick' => "$('#popup-frame').attr('src', '$createUrl'); $('#popup-dialog').dialog('option', 'title', '$label'); $('#popup-dialog').dialog('open');",
        'style'   => 'position: absolute; right: 10px;',
    ),
), true);

/** - View: _form_create_new_post - **/
<?php $form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array(
    'id'                   => 'client-new-post',
    'enableAjaxValidation' => false,
)); ?>

<p class="help-block">Fields with <span class="required">*</span> are required.</p>

<?php echo $form->errorSummary($model); ?>

<?php echo $form->textFieldRow($model, 'email'); ?>

<?php echo $form->textFieldRow($model, 'text'); ?>

<div class="form-actions">
    <?php $this->widget('bootstrap.widgets.TbButton', array(
        'buttonType' => 'submit',
        'type'       => 'primary',
        'label'      => $model->isNewRecord ? 'Create' : 'Save',
    )); ?>
</div>

<?php $this->endWidget(); ?>
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Обновление родительского окна с сохранением flash

Сообщение SiZE »

Эм.. а чем Yii::$app->session->setFlash('success', "Your message to display"); не устроило?
Аватара пользователя
vityachis
Сообщения: 3
Зарегистрирован: 2016.02.01, 11:11
Контактная информация:

Re: Обновление родительского окна с сохранением flash

Сообщение vityachis »

SiZE писал(а): 2017.11.02, 19:42 Эм.. а чем Yii::$app->session->setFlash('success', "Your message to display"); не устроило?
Проект на Yii1. Флэш сообщение возвращается и отображается на странице, но нужно перезагрузить страницу родительскую и потом получить это самое сообщение. Нужно возможно сделать так, что бы просто в родительский елемент не выводило флэш сообщение и тогда при перезагрузке все было бы как требуется.
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Обновление родительского окна с сохранением flash

Сообщение SiZE »

vityachis писал(а): 2017.11.03, 12:32 Проект на Yii1. Флэш сообщение возвращается и отображается на странице, но нужно перезагрузить страницу родительскую и потом получить это самое сообщение. Нужно возможно сделать так, что бы просто в родительский елемент не выводило флэш сообщение и тогда при перезагрузке все было бы как требуется.
Ты пишешь

Код: Выделить всё

Сохранять сообщение в сессию и потом выводить их непосредственно из сессии, но такой вариант требует много манипуляций и возможно будет тяжело применим для других страниц сайта
Так Yii::app()->user->setFlash() и Yii::app()->user->getFlash() именно это и делает. Что не устроило то?
Аватара пользователя
vityachis
Сообщения: 3
Зарегистрирован: 2016.02.01, 11:11
Контактная информация:

Re: Обновление родительского окна с сохранением flash

Сообщение vityachis »

SiZE писал(а): 2017.11.03, 12:52
vityachis писал(а): 2017.11.03, 12:32 Проект на Yii1. Флэш сообщение возвращается и отображается на странице, но нужно перезагрузить страницу родительскую и потом получить это самое сообщение. Нужно возможно сделать так, что бы просто в родительский елемент не выводило флэш сообщение и тогда при перезагрузке все было бы как требуется.
Ты пишешь

Код: Выделить всё

Сохранять сообщение в сессию и потом выводить их непосредственно из сессии, но такой вариант требует много манипуляций и возможно будет тяжело применим для других страниц сайта
Так Yii::app()->user->setFlash() и Yii::app()->user->getFlash() именно это и делает. Что не устроило то?
Проблема в том, что в таком случае flash сообщение выводиться либо в iframe, если не использовать redirect, либо просто вверху страницы, при этом на странице нет нужных (только что добавленных) данных. А нужно что бы вверху было показано flash сообщение и все данных на странице было обновлены (ну лучше всего страница обновлена полностью).

Решение было найдено вот такое:

Код: Выделить всё

// Action модального окна
public function actionCreateNewPost($id)
{
    $model = new Post();

    if (isset($_POST['Post'])) {
        $model->attributes = $_POST['Post'];
        if ($model->save()) {
            flash('success', 'Created Successfully');
            echo "<script>(function(){window.parent.document.location.reload();})()</script>";
            Yii::app()->end();
        } else {
            flash('error', 'Error Creating');
        }
    }

    $this->render('_form_create_new_post', array(
        'model' => $model,
    ));
}
  • Заменен этот кусок (из шапки темы):

Код: Выделить всё

$this->redirect(array('update', 'id' => $id));
  • На этот:

Код: Выделить всё

echo "<script>(function(){window.parent.document.location.reload();})()</script>";
Yii::app()->end();
Таким образом мы отдаем JS код который сразу же выполняется и перезагружает родителя. А "Yii::app()->end();" завершает выполнение метода дальше, в итоге flash сообщение не отдается пользователю на отображение и после перезагрузки уже отображается на странице, чего и нужно было добиться.
Закрыто