Issues with jQuery Dialog Widget


I have been working with this jQuery Dialog widget for few days and just this morning got stuck into some weird issues. It look very long time to solve and thus I thought I can share those experience with you guys:

My problem was, I wanted to have a jQuery modal dialog form in my aspx page which will help me add some data. So, I took the first step by going to jQuery site and grabbing the source for jQuery modal form with css and javascript given in their site.

http://jqueryui.com/dialog/#modal-form

Now, first thing you’ll notice that their code has a form tag inside the dialog div, which surely you don’t want since you already have a form tag. So, I have removed it.

When I tried the code first the dialog opened after click of a button but no… the page posted back suddenly!

so, when you click the button to open your jquery modal dialog form, the page posted back right after opening the form. It’s because they have used a button inside their code!

<button id=”create-user”>Create new user</button>

//JavaScript

$(“#create-user”)
.button()
.click(function () {
$(“#mydialog”).dialog(“open”);
});

They have failed to notice that if this is used in ASPX page then the page will post back. There is few solution, one of which is to add a ‘return false;’ in the above function, like:

$(“#create-user”)
.button()
.click(function () {
$(“#mydialog”).dialog(“open”);
return false;
});

Or, you can change the button to a input type button, i.e. simple HTML button.

First problem solved.

Next one came right after: I wanted to submit the modal form but it was not working. No matter what I do my jquery modal form is not getting submitted. I have added a ASPX button which is also not getting posted back. I have added a HTML input type submit which has cause similar output.

So, I have tried to post the form back in the following way:

//Try 1

$(“#myForm”).submit();

//try 2

document.getElementById(“myForm”).submit();

//try 3

$(“form:first”).submit();

//try 4

$(“form[name=’myForm’]”).submit();

Aha! Now the form is getting submitted but … not the values! In my modal jquery form I have few ASPX fields like textbox, check box, hidden element all of whose values are showing as blank string in the PostBack.

This was really a nightmare to me. I had no clue why this is not getting posted back. After googling a lot I came around a solution which  told me the cause: “When you use jQuery UI’s Dialog plugin to bring up a div as a dialog, it usually pulls the div out of the form to do this and then ASP.Net elements don’t work” says Ken (http://www.keysolutions.com/blogs/kenyee.nsf/d6plinks/KKYE-7XPVS6)

Then I have tried the solution he gave, i.e. to append the dialog to the form through JavaScript.

//Either you need to call this

$(“#mydialog”).parent().appendTo($(“#myForm”));

//Or you can have it in the dialog.open method

$(“#mydialog”).dialog({
bgiframe: true,
autoOpen: false,
height: 400,
width: 350,
modal: true,

open: function (type, data) {
$(this).parent().appendTo($(“#myForm”));
},
close: function () {
allFields.val(“”).removeClass(“ui-state-error”);
}
});

Note: Watch out for the following function:

close: function () {
allFields.val(“”).removeClass(“ui-state-error”);
}

If you call the close function before submit then you’ll not see any values in the post back because they will get wiped up when allFields.val(“”) is called. So, you need be wise when calling this close method.

when I have tried this my jquery modal form was showing up properly and I was also able to submit it with values. But unfortunately I came to another bummer!

Strangely my jquery dialog form was opening up but it was getting show under the overlay. Yes, you read it correct. The dialog was opening beneath the masked overlay. So, there was no way to control it with normal jQuery dialog. You just have to use tab to navigate through elements and submit. TAB, ESC keys were working but not the mouse controller!

I clearly understood that the issue is with the CSS z-index property. Somehow, my jquery modal form’s z-index was lower than the masked overlay and I have to increase the z-index to bring it to front.

So I have added  a inline CSS to my DIV containing the dialog like below:

<div id=”mydialog” title=”My Dialog” style=”z-index: 99999″>

But, this didn’t work. I have used IE developer tools and found that the parent of this dialog is still not having a greater z-index. So I have used the following and it did work. I had to change the open function for the dialog:

$(“#mydialog”).dialog({

bgiframe: true,

autoOpen: false,

height: 400,

width: 350,

modal: true,

open: function (type, data) {

$(this).parent().appendTo($(“#myForm”));

$(this).parent().css(‘z-index’, ‘999999’); //Increase the z-index here

},

close: function () {

allFields.val(“”).removeClass(“ui-state-error”);

}

});

Hopefully this post will help someone in need and save some time 🙂

<div id=”mydialog” title=”Create a new Role” style=”z-index: 99999″>

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 🙂