How to display modal before save model

Hello :slight_smile:
I have 2 models:

  1. Model “Post” (id, title, content, status)
  2. Model “Annotations” (id, post_id, content) which is storing annotations for posts.

When the value in the “status” field was changed (in “Post” model in update action),I want to display a modal, where user have to write reasons for changing the status (which belong to “Annotations” model). After that i want to save both models. How to do it?

Thanks :slight_smile:
Greetings
Tom

First of all decide if you want the modal to appear “interactively” such that the page isn’t reloaded, in which case you’d do it with some JavaScript, or if you want to do it server-side by rendering the modal when the user submits the form, as a second step before accepting the change.

Thanks for reply:)

“interactively” - it would be ideally. But second method would be ok too. I know how to save model, i know how to display modal but i don’t know how to "glue it ". I found tutorials how to create and add second model in dialog window, but my problem is, that i want to display modal only if - for example - “status” field = 2 - in update action of course.

Thanks for helping

Do you know/understand how you would do this, on the client side, with just HTML+JavaScript+CSS? That’s often a really good start in cases like this.

I understand how i would do this on client side:

  1. When user click “save” in update view i need to check in controller action (before modelA->save) - if $modelA->status == 2 (and i know how to do it). If $modelA->status != 2 i should save data and reload page (and i know how to do it)
  2. But i don’t know how to display modal - if - for example - $modelA->status == 2

Thanks for helping

Doing what you just describe seems like doing it on the server side - your page will reload, unless of course you are sending an AJAX request to the server which the controller then receives and returns a reply, but that seems unnecessary.

If you are fine with requiring JavaScript, you can just write a little code that triggers on the user hitting the submit button, inspects the value of that status input in the form, and if it is equal to 2, displays a modal instead of letting the submit pass.

The modal would be e.g. a <div> that contains the form elements for the Annotation model, and you’d show it by making the JS code simply unhide it by removing some CSS class on it.

Once the user clicks OK in the modal, the modal closes and they can hit the submit button of the form again. The same JS code as before runs, but this time it detects that there’s already data in the Annocation input, and lets the submit pass so it’s all sent to the server.

On the server side, you’d process both the data for the Post model and the Annotations model.

The above is a very simplified summary of how you can do it. Please note that it’s missing support for clients with JS disabled.

All this said, perhaps there’s something in Yii to help you do this more easily - I’m just used to doing it “manually”.

I was looking for tutorials on this topic but I did not find one. Can you provide any tutorials on this topic?
Thanks
Tom

I cannot, maybe someone else can. I’m more into trying to help people understand how they do it themselves.

Updated my thread:
My models:
ModelPost (id,title,content,status)
ModelPostAnnotation(id,annotation,post_id)

My code:

Controller:
class PostController extends RController
{
  public function actionChangestatus($id, $newstatus)
      {
        $modelPost=$this->loadModel($id);
        $modelPost->status=$newstatus;

        if($newstatus == 2){

          $modelPostAnnotation=new PostAnnotation;

          if(isset($_POST['PostAnnotation']))
          {
              $modelPostAnnotation->attributes=$_POST['PostAnnotation'];
              if($modelPostAnnotation->save() && $modelPost->save())
              {
                 echo CJSON::encode(array(
                      'status'=>'success',
                      'flash'=>"Annotation added and status changed",
                      ));
                 exit;
              }
          }

          echo CJSON::encode(array(
               'status'=>'failure',
               'div'=>$this->renderPartial('_form_annotations', array('modelPostAnnotations'=>$modelPostAnnotation), true)
               ));
          exit;
        }

        else {
          if($modelPost->save())
          {
             echo CJSON::encode(array(
                  'status'=>'success',
                  'flash'=>"Status changed",
                  ));
             exit;
          }
        }
      }
View file

<?php
echo CHtml::ajaxLink(
        'Change status to cancelled',
        array('post/changestatus/', 'id'=>$model->id, 'newstatus'=>2),
        array(
            'type'=>'POST',
            'data'=> "js:$(this).serialize()",
            'dataType'=>'json',
            'success'=>"function(data)
            {
                if (data.status == 'failure')
                {
		    $('#dialog').dialog('open');
                    $('#dialog div.divForDialog').html(data.div);
                }
                else
                {
		    $('#dialog').dialog('open');
                    $('#dialog div.divForDialog').html(data.flash);
                    setTimeout(\"$('#dialog').dialog('close') \",1500);
                }
            } ",
        )
        );
?>

<?php $this->beginWidget('zii.widgets.jui.CJuiDialog',
    array(
    'id'=>'dialog',
    'options'=>array(
            'title'=>'Annotations',
            'autoOpen'=>false,
            'modal'=>true,
            'width'=>550,
            'height'=>190,
          )
    ));
?>
    <div class="divForDialog"></div>
<?php $this->endWidget();?>
View (form_annotations.php)

<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm', array(
    'id'=>'annotations-form',
    'type'=>'horizontal',
)); ?>
     <?php echo $form->textFieldRow($modelPostAnnotation,'annotation'); ?>
     		<?php $this->widget('bootstrap.widgets.TbButton', array(
			'buttonType'=>'submit',
			'type'=>'primary',
			'label'=>'Save',
		)); ?>
<?php $this->endWidget(); ?>

When i change post status to for example 5 - everything is ok - status is changed and response is displayed in dialog. But when i want to change post status to 2 - response is not displayed in dialog, but as raw text:

This same, when i try change post status to 2 - i can save changed status and annotations, but response is not displayed in dialog - but as raw text:
Bez%C2%A0tytu%C5%82u2

What am i doing wrong?

Thank you for your time and helping :slight_smile:

Greetings
Tom