jqModal Tips – ajax dynamic dialogs

I’ve been using jqModal to handle all my dialog ‘window’ forms on a current application.  I’m not going to get into all the details here, but rather expand on a few complex operations.

First, one powerful aspect of jqModal is the ability to assign a dialog based on a href trigger link.

Here is an example of what this means:

$(‘.dialogs’).jqm({ajax:’@href’,modal:true, trigger: ‘a.triggerLink’});

ajax

If passed, dialog contents will be loaded remotely via ajax. You can pass the URL (e.g. $.jqm({ajax:’remote/dialog.html’}) or extract it from an attribute of the triggering element. For instance, $(.jqm({ajax:’@href’}) would grab contents from bar.html if the triggering element was <a href=”foo/bar.html”>Open Dialog</a>. If a more complicated loading routine is desired, the onShow() callback should be leveraged.

So, let’s say you have the above as described where you want to open a dialog for a list of items : the above dialog contains the very important trigger reference that is saying ‘any a href with class ‘triggerLink’ will fire an event to open the dialog.

Then, the added functionality is ‘when this happens, it’s going to call to the href of that trigger to determine the ajax form to load.

Let’s say I have a html form that I want in the dialog.  The href will need to point to that html…. ie.  myform.html.   I could just do the following:

$('.dialogs').jqm({ajax:'myform.html',modal:true, trigger: 'a.triggerLink'});

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

When the trigger link is clicked ie. a href=”#” class=”triggerLink”  (brackets removed) it will open a dialog with the myform.html as it’s content.

This works particularly well with something like asp.net mvc.  ie. my system is to use a ascx (a snippet of html basically) that is loaded by calling a controller action.   Let’s say I have a html form that I want in the dialog.  The href will need to point to that html…. ie. mycontroller/myaction/1

so if you had a list of links you have one jqm assigned:

$('.dialogs').jqm({ajax:'@href',modal:true, trigger: 'a.triggerLink'});

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

With the corresponding html links:

<a href=”mycontroller/myaction/1” class=”triggerLink”>Item 1</a>
<a href=”mycontroller/myaction/2” class=”triggerLink”>Item 2</a>
<a href=”mycontroller/myaction/3” class=”triggerLink”>Item 3</a>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

the controller action, based on the parameter passed with know, for instance, that you are selecting a particular item based on id to edit inside the dialog.

So, my last ‘issue/problem’ was – ‘what if I want to have this fire based on a select’ ?

Tricky but very doable:

take the above href – assign an id to it:

<a id=”editProviderLink” href=”#” class=”triggerLink”>Edit</a>

I also have a select with id ‘employeeProviderList’.  So, you select a provider name in a dropdown, and click the ‘edit’ href link

then, in the script (document.ready):

$("#editProviderLink").click(function(event) { 
        $(this).attr("href", "/MyController/MyAction/" + $('#employeeProviderList').val()); 
    });

 

this code will do the following:

when you click on the link, it will create the href attribute of the link, injecting in the url to call via ajax – this will occur before the jqmodal will fire (thankfully) – and open up the dialog with the corresponding html returned from the controller action.   This also can be done through the ‘onShow’

onShow (callback)

Called when a dialog is to be shown. Be sure to show (set visible) the dialog.

// onShow : show+make the window translucent
var myOpen=function(hash){ hash.w.css(‘opacity’,0.88).show(); };
$(‘#dialog’).jqm({onShow:myOpen});

Be sure to check out all the callback options!

There is a way as well to fire off a callback that will occur when the dialog is closed – which I sometimes do to update the underlying page via another ajax call  🙂

Hope this helps – its a bit complex, but once you dig into jqModal, it can very powerful – and especially with a MVC setup (like asp.net mvc).

An example that I will cover later is to create a html helper that encapsulates the logic to build a window.  ie.

<%= Html.jqmAjaxWindow<ClaimsController>("addDependentCareWindow","a.addDependentCareTrigger", 
    "Add Provider",true, c => c.LoadNewProviderView(ViewData.Model.Employee.Employeeid.ToString()), 
        new Hash(onHide=> "myClose"))%>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

This dialog can be triggered with:

<a href="#" class="addDependentCareTrigger">Add</a>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

To get an idea of this helper code:

 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

public static string jqmAjaxWindow<TController>(this HtmlHelper helper, string dialogWindowName, string dialogTriggerName, 
           string dialogTitleText, bool isModel, Expression<Action<TController>> theAction, IDictionary options) 
           where TController : Controller 
        { 
            var sb = new StringBuilder(); 
            BuildChrome(sb, dialogWindowName, dialogTitleText); 
            sb.Append("<div class="jqmTarget clear"><p>...Loading Content...</p></div>"); 
            sb.Append("</div>"); 
            sb.Append("<script type='text/javascript'>"); 
            sb.Append("$(function() {"); 
            sb.AppendFormat("$('#{0}').jqm(", dialogWindowName); 
            sb.Append("{ajax: "); 
            sb.AppendFormat("'{0}', ", LinkBuilder.BuildUrlFromExpression<TController>(helper.ViewContext.RequestContext, 
                helper.RouteCollection, theAction)); 
            if (isModel) 
            { 
                sb.Append("modal: true, "); 
            } 
            foreach (DictionaryEntry option in options) 
            { 
                sb.AppendFormat("{0}:{1},", option.Key, option.Value); 
            } 
            sb.Append("target:'div.jqmTarget', "); 
            sb.AppendFormat("trigger:'{0}'", dialogTriggerName); 
            sb.Append("});"); //end of jqm 
            var browser = HttpContext.Current.Request.Browser; 
            if (browser.Browser != "AppleMAC-Safari") 
            { //problem with drag and chrome... 
                sb.AppendFormat("$('#{0}').draggable();", dialogWindowName); 
            } 
            sb.Append("});</script>"); //end of function() 
            return sb.ToString(); 
        }
 
private static void BuildChrome(StringBuilder sb, string dialogWindowName, string dialogTitleText)
        {
            string imagePath = VirtualPathUtility.ToAbsolute("~/Content/Images/Close.jpg");
            sb.AppendFormat("<div id="{0}" class="jqmWindow">", dialogWindowName); //outer window
            sb.Append("<div class="jqmTitleContainer jqDrag">");

            sb.AppendFormat("<div class="jqmTitle">{0}</div>", dialogTitleText); //title
            sb.Append("<div class="jqmCloseContainer">"); //start close container
            sb.AppendFormat("<a href="#" class="jqmClose"><img class="jqmCloseImage" src="{0}" 
               alt="Close"/></a>", imagePath);
            sb.Append("</div>"); //end close container
            sb.Append("</div>"); //end jqmTitleContainer
        }
Advertisements

5 thoughts on “jqModal Tips – ajax dynamic dialogs

  1. Hi Steve,
    Thanks for the article.. i need to know how do i open a modal window.. and on a form action redirect to another html page in the same modal window…

  2. Interesting article..
    I was looking at using a jqModal popup to enter some search criteria, grabbing the result through an ajax call to a controller which would then render a partial view back to be rendered in a div section of the same popup. All seems to work as far as getting the partial view returned – but the jquery function called to add the view content to the popup ( although invoked ) doesnt seem to do the replace. Is there something in the way the popup works that prevents you from doing this Any ideas?

    Thanks

  3. It should work as described. Are you properly populating the div correctly in your ajax onsuccess result ?

    ie.

    $.ajax({
    type: “POST”,
    url: BuildUrl(“controller.mvc/action/” + $(“#somevalue”).val()),
    data: “{}”,
    dataType: “html”,
    beforeSend: function() {
    $.blockUI({ message: “Updating View…” });
    },
    success: function(txt) {
    $(“#yourDivOnPopup”).html(txt).show();
    $.unblockUI();
    }
    });

  4. Thanks for the reply.
    Yeah – found the issue was the document ready function for the page being rendered in the jqModal dialog wasn’t being executed, so the functions set up there weren’t being called.
    Coded it another way in the end.
    Not sure if that is because the initial dialog page is rendered through a controller call via ajax on the dialog creation. Would you expect that a page rendered into the dialog that was would have document ready invoked still?

Leave a Reply

Fill in your details below or click an icon to log in:

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