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

How to Store and Retrieve an Object from Cookie in ASP.NET C#


Hi,

The name of the article suggests a typical problem which the developers come around whenever they are designing a login Form or want to store some useful object in the Cookie.

Unfortunately, cookies are unsecured and they can store string value only. So, to come out of this problem one need to understand that all data can not be / must not be saved in the Cookie. Some basic information like Login Name, user name, email can be saved but not password. Also, the developer need to make sure that no one can read the information except the website for which it is designed.

Solution?

1. First you need to prepare the object: How? – This can be done by serializing the object as a string. XML, JSON, base-64 of arbitrary binary etc.

2. Now, once your object is prepared, you need to add some security. In other word you need to encrypt the string such a way that the content can be readable by you only.

3. Last step: very easy, store the encrypted content as a string in the Cookie.

How to retrieve?

Just do the opposite.

1. Get the content of the cookie as a string

2. Decrypt the string

3. Deserialize it

4. Use the object as you like.

Now, lets see an example code.

here is the class whose object I want to store in my Cookie:

public class clsAdmin
{
private string _name;

public string Name
{
get { return _name; }

set { _name = value; }
}

private int _id;

public int AdminId
{
get { return _id; }
set { _id = value; }
}
}

Now, to serialize the object we can use the following code:

clsAdmin admin = new clsAdmin();

admin.Name = “UBK”;

admin.AdminId = 1;

//  Serialize it

String _serAdmin = SerializeAnObject(admin);

So, you have your serialized string. Now, you need to encrypt it. For this you can refer to this article or use your own code.

String _encVal = EncDec.Encrypt(_serAdmin, “YOUR PASSWORD”);

This time your data is ready to be saved in a cookie.

try
{
HttpCookie myCookie = new HttpCookie(“admin_cookie”);
DateTime now = DateTime.Now;

// Set the cookie value.
myCookie.Value = _encVal;

// Set the cookie expiration date.
myCookie.Expires = now.AddDays(14);

// Add the cookie.
Response.Cookies.Add(myCookie);
}
catch (Exception _e)
{
//Failed to add Cookie
throw _e;
}

Once your Cookie is added, this is time to use it in our code.

try
{
HttpCookie myCookie = new HttpCookie(“admin_cookie”);
myCookie = Request.Cookies[“admin_cookie”];

// Read the cookie information and display it.
if (myCookie != null)
{
string _admStr = EncDec.Decrypt(myCookie.Value, “YOUR PASSWORD”);
clsAdmin _adm = DeSerializeAnObject(_admStr, typeof(clsAdmin)) as clsAdmin;

if (null != _adm && _adm.Login.Length > 0)
{
//DO Whatever you want with the object
}
}
else
Response.Write(“not found”);
}
catch (Exception _e)
{
//Failed to read cookie?
throw _e;
}

For XML Serializer I have used the wonderful code from http://weblogs.asp.net/stevewellens/archive/2009/07/02/serializing-and-deserializing-objects-to-and-from-xml.aspx

/// ---- SerializeAnObject -----------------------------
/// <summary>
/// Serializes an object to an XML string
/// </summary>
///AnObject">The Object to serialize
/// <returns>XML string</returns>

public static string SerializeAnObject(object AnObject)
{
    XmlSerializer Xml_Serializer = new XmlSerializer(AnObject.GetType());
    StringWriter Writer = new StringWriter();      

    Xml_Serializer.Serialize(Writer, AnObject);
    return Writer.ToString();
}
 

/// ---- DeSerializeAnObject ------------------------------
/// <summary>
/// DeSerialize an object
/// </summary>
///XmlOfAnObject">The XML string
///ObjectType">The type of object
/// A deserialized object...must be cast to correct type

public static Object DeSerializeAnObject(string XmlOfAnObject, Type ObjectType)
{       
    StringReader StrReader = new StringReader(XmlOfAnObject);
    XmlSerializer Xml_Serializer = new XmlSerializer(ObjectType);
    XmlTextReader XmlReader = new XmlTextReader(StrReader);
    try
    {
        Object AnObject = Xml_Serializer.Deserialize(XmlReader);
        return AnObject;
    }
    finally
    {
        XmlReader.Close();
        StrReader.Close();
    }
}

Hope this will help someones quest :)