JQuery Modal dialogue and issues I found


Very recently I was trying to explore jQuery (yes I know, this is very late unfortunately) and as expected I came around very basic problems which took hours to solve with help from posts from Internet.

As the problems were very basic but to find the solutions I had to spent a lot of hours. So the following post is for those who wants basic solution for the journey to jQuery along with ASP.NET

First I was trying with JQuery Modal dialog. My project was to open an external page with some values in query string when evern user clicks the edit link on a Grid view. This external page is updating the record. So, the modal dialogue have to stay open until the update is done in the server and then if the update is successful you have to close the modal dialogue.

Here is how I did it:

Include jQuery scripts:

<script src=”Scripts/jquery-1.9.1.js” type=”text/javascript”></script>
<script src=”Scripts/jquery-migrate-1.1.0.js” type=”text/javascript”></script>
<script src=”Scripts/jquery-ui-1.10.0.custom.js” type=”text/javascript”></script>

First try using a simple Modal dialogue -> Add a div like this in your page after <body> section:

<div id=”dialog-modal” title=”Basic modal dialog”>
<p>
Loading…</p>
</div>

Now, you might have a need to open the dialogue when a link is clicked, so add such a link:

<a href=’#’ onlclick=’javascript:openDialog()’ title=’Open dialogue test’>Click Here</a>

After this you can add a script tag in the head section of the page and add the following function:

<script type=”text/javascript”>

var dialogid = null;

function openDialog() {
dialogid = $(“#dialog-modal”).dialog({ modal: true, width: 450, height: 500 });
}

</script>

Now, test your page. Hope you’ll be able to open the Modal dialog when the link is clicked.

Now: I wanted to load another page (from same domain) in the modal dialogue:

Here are the solution that worked for me:

function openDialog() {
dialogid = $(“#dialog-modal”).load(“myexternalpage.aspx” ).dialog({ modal: true, width: 450, height: 500 });
}

If you want to pass some value to the URL then just modify the same method like below:

function openDialog(id) {
dialogid = $(“#dialog-modal”).load(“myexternalpage.aspx?id=” + id).dialog({ modal: true, width: 450, height: 500 });
}

Both the solution should work for you. There is one problem though.

Suppose you have opened a page with a form inside using the above technique and you want to submit data from that form. Then the whole page will be post back!

To solve this issue I went to the IFRAME technique.

First, add an IFRAME in your HTML Page just after body tag like below:

<div style=”display: none”>
<div id=”dlgConfirm” title=”Modal Test” style=”padding: 0px;”>
<i frame style=”margin: 0px; padding: 0px” marginheight=”0″ marginwidth=”0″ src=””
width=”100%” height=”100%” frameborder=”0″ scrolling=”auto”></i frame>
</div>
</div>

Note the additional space in the iframe tag in the above code. I had to do this since WordPress was deleting the tag automatically 😦

Now, change the dialogue open method:

var loadedByFunction = false;

$(function () {
dialogid = $(“#dlgConfirm”).dialog({
autoOpen: false,
resizable: false,
modal: true,
width: 450,
height: 500,
open: function (event, ui) { $(‘body’).css(‘overflow’, ‘hidden’); $(‘.ui-widget-overlay’).css(‘width’, ‘100%’); },
close: function (event, ui) { $(‘body’).css(‘overflow’, ‘auto’); }
})
});

function fConfirm(id) {
// alert(id);
loadedByFunction = true;
$(‘#dlgConfirm’).children().attr(‘src’, ‘myexternalpage.aspx?id=’ + id)
.load(function () {
if (loadedByFunction) {
loadedByFunction = false;
$(“#dlgConfirm”).dialog(‘open’);
}
});
return false;
}

We are almost there. Hope everything is working fine till this point 🙂

Another problem I have faced is with scroll bar. The modal dialog was also showing a scroll bar along with the iframe. Which was very annoying. I had to change the div (dlgConfirm) definition to add a overflow: hidden style, which fixed the issue.

<div id=”dlgConfirm” title=”Edit User” style=”padding: 0px; overflow: hidden”>
<i frame style=”margin: 0px; padding: 0px” marginheight=”0″ marginwidth=”0″ src=””
width=”100%” height=”100%” frameborder=”0″ scrolling=”auto”></i frame>
</div>

Now, another important issue I found is to close the Modal popup when a particular action is performed in the opened page. To do that I have defined the following javascript method in the main page:

function test() {
if (null != dialogid) dialogid.dialog(“close”);

}

You might have seen that when declaring the dialogue I have used another variable called  “dialogid” which came useful now to decide whether the dialogue is in open state or not.

Now, you can call the above method from your iframe page like below:

 <input id=”Button1″ type=”button” value=”Close Modal” onclick=”javascript:parent.test()” />

This way you can do a lot of things. Like if the submit is successful then you can call “parent.test()” to close the modal dialogue.

Now, 1 problem remains.

I am using a jQuery datatable which is loading data from a C# webservice  which is loading student data. There is an edit link in the last cell of each row to allow users to edit the corresponding data. If user clicks that link then the edit page will open inside the model dialogue using the technique just shown above. Also, one of the additional requirement is to update the datatable if the user is edited successfully inside the iframe page. This is where I am currently stuck and still searching for a suitable solution.

And finally I got the solution 🙂

Here is how I did it.

First initiated a data table inside my script:

var oTable =null;

$(document).ready(function () {
oTable = $(‘#example’).dataTable({
“bProcessing”: true,
“bDestroy”: true,
“sPaginationType”: “full_numbers”,
“bSort”: true,
“iDisplayLength”: 10,
“bLengthChange”: false,
“aaData”: new Array(), //If server response is null then create an empty array
});
});

Now, created a method to refresh its data through AJAX call:

function refreshTable() {
$.ajax({
type: “POST”,
url: “MyWebService.asmx/GetDataMethod”,
data: “{}”,
contentType: “application/json; charset=utf-8”,
dataType: “json”,
success: function (json) {
if (null != oTable) {
oTable.fnClearTable();
oTable.fnAddData(json.d.aaData);
}
},
complete: function () {
if (null != oTable) {
oTable.fnDraw();
}
}
});
};

So, when body load is done I am just calling this function refreshTable once to load data initially.

Now, as indicated in my above example, I have to refresh this table based on a edit in the modal page which was opened by clicking the link in this data table. I am writing the following script when my update is done successfully inside the modal page:

Response.Write(“<script type=’text/javascript’>parent.test();</script>”);

When the test method from parent is called, I am just using the following way to load data again:

function test() {
alert(“Hi”);
if (null != dialogid) dialogid.dialog(“close”);
refreshTable();
}

In this way the modal dialogue is getting closed and the datatable is able to load new data as soon as the update from the modal page is finished successfully.

To make a catchy look I am now planning to create another Modal dialogue which will be opened when the update from the inner page is done. So, when the test() method is called I will first show the new modal dialogue which will inform user that the update is successful and when they click ‘OK’ the data table will get refreshed. Solution yet to find 🙂

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s