Calling a modal popup from another modal popup then falling back into original modal popup

Hello again,

I was trying to call a modal popup from another modal popup but when i close the second modal i can’t seem to fallback into the original modal window.

Here is the scenario:

I have a simple gridview index page which has an add button which allows to add a new model (which is displayed in the gridview). This add btn calls a bootstrap modal window with the fields required to add a new modal. However this modal has one attribute which is a entered via a dropdown select input field. This dropdown is populated from the database. Here is where the second modal window comes in; I want to be able to add another option to the database which would be reflected in the dropdown. I managed to call a second modal from the first modal but when I submit I’m not sure how to redirect back to the first modal (preferably with the fields that have already been filled as they were).

My workflow is as follows:

In my index.php I have the following btn




<?=

            Html::button(Yii::t('app','test'),[

                'value' => Yii::$app->urlManager->createUrl('/users/test'),

                'class' => 'btn btn-success',

                'id' => 'test-modal-btn'

            ]);

            ?>



Here is the code for the Modal widget




<?php

    Modal::begin([

        'header' => "<h4>Modal in a modal</h4>",

        'id' => 'test-modal',

        'size' => 'modal-lg'

    ]);


    echo "<div id='test-modal-content'></div>";


    Modal::end();

?>



to capture the click action and show the modal window i have the following js code added from an external js file using the $this->registerJsFile(…) function




$(function () {

    $('#test-modal-btn').click(function () {

        $('#test-modal')

            .modal('show')

            .find('#test-modal-content')

            .load($(this).attr('value'));

    });

});



so far all good, in my UsersController I have the following action




public function actionTest(){

        $model = new TcUser();


        if($model->load(Yii::$app->request->post()) && $model->save()){

            return $this->redirect('index');

        }

        return $this->renderAjax('test',[

            'model' => $model

        ]);

    }



with this my first modal window works just fine.

Following these same steps in my test.php view file I added a btn and modal widget with




    <?=

    Html::button('add',[

        'value' => Yii::$app->urlManager->createUrl('/gender/test'),

        'class' => 'btn btn-primary',

        'id' => 'second-modal-btn'

    ]);

    ?>


    <?php

    Modal::begin([

        'header' => "<h4>Second Modal</h4>",

        'id' => "second-modal",

        'size' => 'modal-lg'

    ]);


    echo "<div id='second-modal-content'></div>";


    Modal::end();

    ?>



the dropdown field is generated with




<?=

    $form->field($model, 'gender_id')

        ->dropDownList(

            ArrayHelper::map(Gender::find()->all(),'id','name'),

            [

                'prompt' => Yii::t('app','Select gender')

            ]

        )

        ->label(Yii::t('app','Gender'))

    ?>



similarly a js file to handle the click action on the btn




$(function () {

    $('#second-modal-btn').click(function () {

        $('#second-modal')

            .modal('show')

            .find('#second-modal-content')

            .load($(this).attr('value'));

    });

});



And an action in the GenderController to handle the request




public function actionTest(){

        $model = new Gender();


        if ($model->load(Yii::$app->request->post()) && $model->save()) {

            return $this->redirect(['/users/add-user']); //<-----What should i do here???

        } else {

            return $this->renderAjax('create', [

                'model' => $model,

            ]);

        }

    }



here is where i’m stuck… Once i have completed the $model->save() how can i fallback into the original modal popup? Is it possible to retain the fields fields which were already inserted before the modal was called and have the new option in the dropdown field?

Hope I explained myself correctly and thanks for your time and input in advance

I have done exactly what you’re trying to do two different ways. Both are not straight forward with Yii. I wish I could just say here is an example but what i have done in the past became heavily integrated into my applications.

My goal was to be able to add anything in the application from anywhere. It doesn’t matter if it’s in a modal in a modal that’s in a modal or just some random page. It wasn’t easy but it is worth the initial headache and make the application very user friendly as a user never has to leave a form to input related data they can just add it in the original form. What i can offer, is help you avoid a lot of issues that took me a lot of time to figure out.

Things to watch out for with your IDs

Each form must have it’s own unique ID. Yii will assign the same ID to all of your forms since they all think they are the only one on the page. This will mess up ajax validation and other widgets. On all of my forms I would do something like set the id equal to time like


'some-form-'.time()

Each form widget must have it’s own unique ID. for example if modal 1 has a date picker and modal 2 has a date picker you they must have different unique ids. If the date picker on both forms has an id of “date-picker” the js will get confused and you will have errors. I normally set a form id then append it to the id of all of the widgets. This will happen if you have a form with a parent child relation and uses the same form. You would essentially be loading the same form twice via ajax.

Try and answer to some of your questions

Your actions must return json so you can read the response (errors, success etc) it in your forms via javascript. I have a custom base controller and all of my controllers extend that one. One of my actions is isAjax() since this whole process has to be ajax to work. Here is an example of one of my create actions.





protected function isAjax() {

        $request = Yii::$app->request;

        if (!$request->isAjax) {

            throw new BadRequestHttpException('Bad Request Type!', '400');

        }

        return $request;

    }

    public function actionCreate() {

        $request = $this->isAjax();

        $model = new Equipment();

        if ($model->load($request->post())) {

            \Yii::$app->response->format = Response::FORMAT_JSON;

            if ($model->save()) {

                return ['message' => "Successfully added new {$model->name}.", 'id' => $model->id];

            }

            return ['errors' => ActiveForm::validate($model)];

        } else {

            return $this->renderAjax('_form', ['model' => $model]);

        }

    }



Since your controller must send back json you need to submit all of your forms via ajax. In the success or fail function of the ajax call you will close the modal.

Here is a screen capture i just made of my asset management application with what i think you’re trying to do. You can add and edit anything from anywhere. Unlimited nested modals. If this is similar to what you want then the above is necessary.

[video]https://drive.google.com/file/d/0B9xKaex6VhgbdWtodF9fUUxzY2M/view?usp=sharing[/video]