An Active Form In Iframe Inside A Popup

We negotiated with my boss the following workflow:

The backoffice of our site is about pupils (children).

Now we at the page for entering contract data for a specific pupil. This page displays (among other) a <select> with a list of people which may be kins of a child.

When we click "Add" button, an iframe inside of jQuery UI modal dialog appears. In the iframe there is an active form to enter a new kin for the pupil. Or we can select an existing kin from the list of kins and press "Edit" button, this also opens an active form inside the iframe inside a modal dialog. When a kin is added or edited the above mentioned <select> should be updated.

Now the hard part: If inside the popup in iframe the button "Save" is clicked and the saving performs successfully then the popup should close and the <select> with the list of kins on the page should be updated. But if the button "Save" is clicked and there are errors, the popup should not close and the errors should be displayed inside the iframe.

So it should behave differently on successful submit and failed submit.

How to implement it? I guess something related with AJAX, but don’t know the exact way to do this.

The workflow is not set in stone, you may advice me how to change the user experience with our site.

I do exactly the same.




        $.post(saveUrl, params, function(data, textStatus, jqXHR){

            if (jqXHR.getResponseHeader('Content-Type') == 'text/html') {

                // a form must have failed validation, redraw it

                dialog.html(data);

                dialog.scrollTop(0);

            } else {

                // we expect JSON

                if (typeof afterSave == 'function') {

                    afterSave(data);

                }

                if (bootstrap) {

                    dialog.parents('.modal:first').modal('hide').remove();

                } else {

                    dialog.dialog('destroy').remove();

                }

            }

        });



If saving fails, html is returned with same form filled with posted data an marked errors.

If it succeds, a JSON message is returned containing new or updated record id. Using this we can do post-saving actions like selecting it in a dropdown (afterSave callback above).

That condition for bootstrap variable is to support modal dialog from bootstrap or jQuery UI.

I’m afraid, this won’t work because I want to use an iframe inside the dialog.

Or should I do it without iframe at all?

Hi

If I understood well you want to send an event from iframe to the parent page (the popup)

check this

I use iframes only where I have to, that is for ajax file uploading and when the contents require really invasive CSS or JS that won’t go well with my site.

So I would advise not to use iframes in this scenario :slight_smile:

What is this afterSave()?

It’s a function (callback). I copied code from my js lib. Define it as you see fit, maybe selecting a value from a dropdown as you wrote earlier.

Hi

I think you have this:

main page > dialog > iframe > view.

The update button on the main page will probably open the dialog and set the source of the iframe - which will send the request to the controller, and update the iframe with the original view.

The main page and view must have their own js functions. They cannot share functions, because the iframe is like a “shield” between the dialog and the view. If your functions are in a single js file, then both main page and view (or main page’s layout and view’s layout) must load the js file separately.

So you can access the view from the view’s js. But you cannot access the dialog from the view. You have to access the dialog from the main page.

If you submit the view and there are errors, then your controller will render/renderPartial the view - which contains the model with errors - and this view will be displayed in iframe. No problem.

If there were no errors, do this in the controller:

  1. Update the main page.

Maybe it is a gridview:


echo CHtml::script("

	window.parent.$.fn.yiiGridView.update('{$_GET['gridId']}');

");

Maybe it is a tree view:


echo CHtml::script("

	parent.updateTree(); /* function to call a controller action to render the tree */

");

  1. Close the dialog:

echo CHtml::script("

	parent.closeDialog1();

");

Notes:

The controller echo to the view, but the view cannot access the dialog on the main page.

So the view passes instructions to the main page by calling it’s ‘parent’.

Thus, both updateTree() and closeDialog1() are functions in the main page js - not the view’s js.

The function in the main page that close the dialog can be something like this:


function closeDialog1()

{

	$('#iframe1').attr('src','about:blank');

	$('#dialog1').dialog('close'); 

}

Ps. I like using an iframe in the dialog, because you don’t have to worry about widgets in the view overriding the js of widgets in the main page.

Hope this helps.

You probably have seen this wiki. Just making sure.