ASP.NET MVC: Ajax Dialog Form Using jQuery UI


In one of my recent projects I needed to display some information, allow the user to edit it utilizing a dialog window, post the updated information and reload it for the user using Ajax. I needed to perform the named operations for multiple models so I set out to create some generic code that could be reused over and over. Below is a picture of what I am trying to accomplish.

The project used for the post below can be downloaded here.

First, the model. For this example, we will use a simple model that contains some profile information for a user.

public class Profile
{
    [Required]
    public string Name { get; set; }

    [Required]
    [StringLength(10, MinimumLength=3)]
    [Display(Name="Nick name")]
    public string NickName { get; set; }

    [Required]        
    public string Email { get; set; }

    [Required]
    public int Age { get; set; }
}

Second, we need to create three action methods. One will be used to display the profile information, another to display the form for editing the profile, and lastly another that will be used to save the edited profile object. The first two should always return a PartialView as each of these action methods will be called using Ajax and their result will be loaded into div elements; the first into a div used to display the saved profile and the second into the edit dialog. The third action method will return a PartialView if the ModelState is invalid so that the errors can be displayed to the user and a Json result indicating the save was successful if all went well. (Note that in this example I am just storing the profile information in Session but obviously this would be stored in a database or some other data store.)

public ActionResult Profile()
{
    Profile profile = new Profile();

    // Retrieve the perviously saved Profile
    if (Session["Profile"] != null)
        profile = Session["Profile"] as Profile;

    return PartialView(profile);
}

public ActionResult EditProfile()
{
    Profile profile = new Profile();

    // Retrieve the perviously saved Profile
    if (Session["Profile"] != null)
        profile = Session["Profile"] as Profile;

    return PartialView(profile);
}

[HttpPost]
public ActionResult EditProfile(Profile profile)
{
    // If the ModelState is invalid then return
    // a PartialView passing in the Profile object
    // with the ModelState errors
    if (!ModelState.IsValid)
        return PartialView("EditProfile", profile);

    // Store the Profile object and return
    // a Json result indicating the Profile 
    // has been saved
    Session["Profile"] = profile;
    return Json(new { success = true });            
}

Next we need to create the two partial views that correspond to the first two action methods we created above. In this example, the partial view for the EditProfile action is pretty much just the stock view created by the MVC frameowork except I have removed the input element to submit the form as we will use the buttons on the jQuery UI dialog to submit it.

The second partial view, the one that displays the saved Profile object again in this example is the stock view with a few added elements.

@using DialogFormExample.MvcHelpers

@model DialogFormExample.Models.Profile

<fieldset>
    <legend>Contact Info</legend>
    
    <div class="display-field">
        Name: @Html.DisplayFor(model => model.Name)
    </div>

    <div class="display-field">
        Nick name: @Html.DisplayFor(model => model.NickName)
    </div>
    
    <div class="display-field">
        Email: @Html.DisplayFor(model => model.Email)
    </div>
    
    <div class="display-field">
        Age: @Html.DisplayFor(model => model.Age)
    </div>

    <div class="right">
        @Html.DialogFormLink("Edit", Url.Action("EditProfile"), "Edit Profile", "ProfileContainer", Url.Action("Profile"))
    </div>
</fieldset>

The first portion of the partial view just displays the form elements required for editing the model. This is just the stock Edit view modified only slightly. The new code starts at line 25. Here I created an extension method for HtmlHelper named DialogFormLink that will create an anchor tag loaded with all the needed information to make the dialog form work. Here is the code for the extension method. You can read the comments to get an understanding of the parameters it requires.

/// <summary>
/// Creates a link that will open a jQuery UI dialog form.
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="linkText">The inner text of the anchor element</param>
/// <param name="dialogContentUrl">The url that will return the content to be loaded into the dialog window</param>
/// <param name="dialogTitle">The title to be displayed in the dialog window</param>
/// <param name="updateTargetId">The id of the div that should be updated after the form submission</param>
/// <param name="updateUrl">The url that will return the content to be loaded into the traget div</param>
/// <returns></returns>
public static MvcHtmlString DialogFormLink(this HtmlHelper htmlHelper, string linkText, string dialogContentUrl,
    string dialogId, string dialogTitle, string updateTargetId, string updateUrl)
{
    TagBuilder builder = new TagBuilder("a");
    builder.SetInnerText(linkText);
    builder.Attributes.Add("href", dialogContentUrl);            
    builder.Attributes.Add("data-dialog-title", dialogTitle);
    builder.Attributes.Add("data-update-target-id", updateTargetId);
    builder.Attributes.Add("data-update-url", updateUrl);

    // Add a css class named dialogLink that will be
    // used to identify the anchor tag and to wire up
    // the jQuery functions
    builder.AddCssClass("dialogLink");

    return new MvcHtmlString(builder.ToString());
}   

The above extension method that builds our anchor tag utilizes the HTML5 data attributes to store information such as the title of the dialog window, the url that will return the content of the dialog window, the id of the div to update after the form is submitted, and the url that will update the target div.

Now we need to add the container div to hold the Profile information in the Index view.

@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>

<div id="ProfileContainer">
    @{ Html.RenderAction("Profile"); }
</div>

Lastly, I have listed the scripts and css files that need to be linked below in the _Layout page for everything to work correctly.

<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/themes/base/jquery.ui.all.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>   
    <script src="@Url.Content("~/Scripts/DialogForm.js")" type="text/javascript"></script>    
</head>

The last script reference above is to a script I wrote called DialogForm.js. This script (shown below) will make everything work.


$(function () {

    // Don't allow browser caching of forms
    $.ajaxSetup({ cache: false });

    // Wire up the click event of any current or future dialog links
    $('.dialogLink').live('click', function () {
        var element = $(this);

        // Retrieve values from the HTML5 data attributes of the link        
        var dialogTitle = element.attr('data-dialog-title');
        var updateTargetId = '#' + element.attr('data-update-target-id');
        var updateUrl = element.attr('data-update-url');

        // Generate a unique id for the dialog div
        var dialogId = 'uniqueName-' + Math.floor(Math.random() * 1000)
        var dialogDiv = "<div id='" + dialogId + "'></div>";

        // Load the form into the dialog div
        $(dialogDiv).load(this.href, function () {
            $(this).dialog({
                modal: true,
                resizable: false,
                title: dialogTitle,
                buttons: {
                    "Save": function () {
                        // Manually submit the form                        
                        var form = $('form', this);
                        $(form).submit();
                    },
                    "Cancel": function () { $(this).dialog('close'); }
                }
            });

            // Enable client side validation
            $.validator.unobtrusive.parse(this);

            // Setup the ajax submit logic
            wireUpForm(this, updateTargetId, updateUrl);
        });
        return false;
    });
});

function wireUpForm(dialog, updateTargetId, updateUrl) {
    $('form', dialog).submit(function () {

        // Do not submit if the form
        // does not pass client side validation
        if (!$(this).valid())
            return false;

        // Client side validation passed, submit the form
        // using the jQuery.ajax form
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {
                // Check whether the post was successful
                if (result.success) {                    
                    // Close the dialog 
                    $(dialog).dialog('close');

                    // Reload the updated data in the target div
                    $(updateTargetId).load(updateUrl);
                } else {
                    // Reload the dialog to show model errors                    
                    $(dialog).html(result);

                    // Enable client side validation
                    $.validator.unobtrusive.parse(dialog);

                    // Setup the ajax submit logic
                    wireUpForm(dialog, updateTargetId, updateUrl);
                }
            }
        });
        return false;
    });
}

Conclusion

I know that was a lot to take in but after you do the setup once, all you need to do is make one call to Html.DialogFormLink and everything will be taken care of for you. Hope this helps!

71 Responses to “ASP.NET MVC: Ajax Dialog Form Using jQuery UI”

  1. ASP.NET MVC: Client Side Validation with an Ajax Loaded Form « Nick Olsen's Programming Tips Says:

    […] Client Side Validation with an Ajax Loaded Form August 13, 2011 — Nick Olsen In my last post I discussed how to perform some CRUD operations using Ajax and the jQuery UI dialog window. In that […]

  2. ASP.NET MVC: Displaying Client and Server Side Validation Using qTip Tooltips « Nick Olsen's Programming Tips Says:

    […] will be building off of the example from my last post that showed how to use jQuery UI to build Ajax […]

  3. ASP.NET MVC: Displaying Client and Server Side Validation Using Error Icons « Nick Olsen's Programming Tips Says:

    […] done previously I will be using the same example project from this post where we created a dialog form which was submitted via […]

  4. Alpesh Says:

    Very useful article, and thanks for posting the code download link too. Have one question. I want to generalize the DialogForm.js for all the dialog box based forms in my application. And all of my forms are going to have jquery based validations over and above server side validations. I see that you are manually submitting the form by saying $(form).submit();. I am going to have Validate jquery method on all my partials renderend in dialog boxes. Is there any way i can generalize these Validate() jquery methods to be called before the form is submitted?

    • Nick Olsen Says:

      I don’t know if I understand exactly what you are saying but from what I understand you want to make sure the jQuery validation rules are run before the form is submitted to the server correct? This is already being done. In line 46 of DialogForm.js we are checking $(this).valid() which runs all jQuery validation and returns false if anything isn’t valid. In this case we cancel the form submit.

      Is that what you meant?

  5. Rich Says:

    Hi, great post!

    I was just wondering, how do you change the width of the dialog?
    I’ve tried to set the width of ui-dialogue in my theme css, but it seems to be written as an inline stle at some point

    Thanks!

    • Nick Olsen Says:

      You have to set the width in the jquery ui dialog method like so:

      $( “.selector” ).dialog({
      width: 460
      });

      By default I believe the width gets set to 300px if you don’t specify a width.

  6. Gilbert Blanco Says:

    Thank you for share your post with the community.

  7. Dave Says:

    Excellent post, It’s helped me loads already.
    Have you any tips on how to make the behavior of a successful submit dynamic?
    So instead off just….

    // Reload the updated data in the target div
    $(updateTargetId).load(updateUrl);

    …it could somehow be…..

    $(updateTargetId).load(updateUrl, function(){
    SomePageSpecificAction();
    });

    Reason I ask is that I am trying to integrate this with a page that is using a tablesorter (http://tablesorter.com/docs/), which requires a call to (“#table”).trigger(“update”); it would be a beautiful thing if it was possible to make this function call!!!!

    Any ideas appreciated, and again, many thanks for the post.

    • Nick Olsen Says:

      You should be able to do just that! Take a look at the documentation: http://api.jquery.com/load/ One of the parameters to the load method is a function that will be called after the load. Let me know if it isn’t working.

      • Dave Says:

        Hi Nick, thanks for the reply.

        I’ve had a go at converting your code to a jquery widget. Let me know what you think….

        /* SomePage.js */
        $(‘.dialogForm’).dialogForm({ postSuccesCallBack: function () { alert(“Hello”); } });

        /* DialogForm.js */
        var dialogForm = {

        _init: function () {

        var $this = this;

        $this.element.click(function (e) {

        e.preventDefault();

        // Retrieve values from the HTML5 data attributes of the link
        var dialogTitle = $this.element.text(); //element.attr(‘data-dialog-title’);
        var updateTargetId = ‘#’ + $this.element.attr(‘data-update-target-id’);
        var updateUrl = $this.element.attr(‘data-update-url’);

        // Generate a unique id for the dialog div
        var dialogId = ‘uniqueName-‘ + Math.floor(Math.random() * 1000)
        var dialogDiv = “”;

        // Load the form into the dialog div
        $(dialogDiv).load(this.href, function () {
        $(this).dialog({
        modal: true,
        show: ‘blind’,
        position: ‘top’,
        width: 680,
        resizable: false,
        title: dialogTitle,
        buttons: {
        “Save”: function () {
        // Manually submit the form
        var form = $(‘form’, this);
        $(form).submit();
        },
        “Cancel”: function () { $(this).dialog(‘close’).dialog(“distroy”).remove(); }
        }
        });

        // Enable client side validation
        $.validator.unobtrusive.parse(this);

        // Setup the ajax submit logic
        $this._wireUpForm(this, updateTargetId, updateUrl, $this.options.postSuccesCallBack);
        });
        return false;
        });
        },

        options: {
        postSuccesCallBack: null
        },

        /* private */
        _currentSortDirection: true, // true = ascending, false descending

        _debug: function (message) {
        if (window.console && window.console.log)
        window.console.log(message);
        },

        _wireUpForm: function (dialog, updateTargetId, updateUrl, succesCallBack) {
        $(‘form’, dialog).submit(function () {

        // Do not submit if the form
        // does not pass client side validation
        if (!$(this).valid())
        return false;

        // Client side validation passed, submit the form
        // using the jQuery.ajax form
        $.ajax({
        url: this.action,
        type: this.method,
        data: $(this).serialize(),
        success: function (result) {
        // Check whether the post was successful
        if (result.success) {
        // Close the dialog
        $(dialog).dialog(‘close’).dialog(“distroy”).remove();

        // Reload the updated data in the target div
        $(updateTargetId).load(updateUrl, function () {
        succesCallBack();
        });
        } else {
        // Reload the dialog to show model errors
        $(dialog).html(result);

        // Enable client side validation
        $.validator.unobtrusive.parse(dialog);

        // Setup the ajax submit logic
        wireUpForm(dialog, updateTargetId, updateUrl);
        }
        }
        });
        return false;
        });
        }
        };
        $.widget(“ui.dialogForm”, dialogForm);

  8. jovnas Says:

    Great post!

    I’ve implemented a customized version of your code.
    Since our site currently is not using unobtrusive validation I replaced the line $.validator.unobtrusive.parse(dialog); with Sys.Mvc.FormContext._Application_Load();
    However, the client validation did not fire if the user opened the dialog, pressed cancel, then opened it again. The solution to this problem was to add .dialog(‘destroy’).remove(); on line 31 and 63. (I guess just remove() would work.)

    Thought I should share this, if anyone faces the same problem.

  9. adamtuliper Says:

    You may want to include a filter for .filter(‘div) to avoid reloading scripts plus I _think_ (it may be fixed) jquery creates a dialog for scripts and for the content if both are returned. Note the bug here: http://forum.jquery.com/topic/problem-with-ui-dialog-component-and-jquery-1-4-1

  10. adamtuliper Says:

    also note the spelling error above for $(dialog).dialog(‘close’).dialog(“distroy”).remove(); (should be ‘destroy’)

  11. czetsuya Says:

    I’m currently working on a project that requires multiple locale settings, so is it possible to change the button labels at runtime?

    • Nick Olsen Says:

      This is an example of one way to set the button text based on the current locale setting. You would have to store your button text in a global strings object or array.

      var buttons = {};
      buttons[strings.ok] = function () {
      // Do something here
      $(this).dialog(‘close’);
      };
      buttons[strings.cancel] = function () {
      $(this).dialog(‘close’);
      }

      div.dialog({
      modal: true,
      width: 400,
      height: 450,
      resizable: false,
      title: strings.title,
      buttons: buttons,
      close: function () {
      $(this).remove();
      }
      });

  12. czetsuya Says:

    Hi, sorry for the 2 successive questions but I just want to know why the dialog fail when seting the properties autoOpen: false and show: “blind”.

    Thanks,
    czetsuya

  13. Ben Says:

    Nick, great solution. I’m using it in my own little web app. But I’ve noticed that within one of my dialogs opened for editing some data any of my jquery calls are not being executed. For example: I open a dialogbox which has two checkboxes. I have some jquery code that forces only one of the checkboxes to be selected similar to the radio button logic. the code executes nicely in a regular page but not at all from within the dialog. Any ideas?

    • Nick Olsen Says:

      Is the script included on the page that is loaded into the dialog? If so, this is a jQuery issue. For security reasons jQuery will strip out any scripts that are included on a page that are loaded via ajax. Somewhat obnoxious but not the end of the world. I have found two solutions to this. After the page is loaded into the dialog, use the jQuery $.getScript() method to remotely retrieve the script or have a function defined on the parent page of the dialog form and after the load of the dialog form, call that function which runs your script on the dialog content.

      Hope that helps.

  14. czetsuya Says:

    Hi,

    I would like to ask if you’ve encountered this issue:

    I am required to do some business server side validations and when it failed I return the view. When I click the save/submit button again it doesn’t work.

    For example I have 2 date fields: date1 and date2 and date1 should be greater than date2, When that rule is satisfied it successfully post to the server. But when not it shows an error in the page (correct), then when the error is corrected and the submit button is pressed again, it won’t submit. Any idea or possible solution to this?

    Really appreciate this plugin,
    czetsuya

  15. David Compton Says:

    I’m not sure if this is already covered in the comments above, however in the hope that it might save someone else a few hours of debugging heartache…. note that in order to allow the dialog to work when called multiple times, in DialogForm.js I had to add in a call to $this).empty() after the call to $(this).Dialog(‘Close’) – and a call to $(dialog).empty() after the call to $(dialog).dialog(‘close’). Without this I had major problems if the dialog was called twice without the calling page being refreshed.

    • Julio IE Says:

      I had the same problem but wasnt working while closing dialog by ESC.
      You could add it to your dialog attributes, so it will work when you closed by ESC or clicking on the X:

      $(this).dialog({
      modal: true,
      resizable: false,
      title: dialogTitle,
      close: function() { $(this).empty(); } ,
      buttons: { …….

    • Kevin Says:

      Thanks for the post, David. You did save me hours of debugging. Plus-1 for you.

  16. czetsuya Says:

    I’m wondering why an input of type file doesn’t work using this popup? The same form works properly if not loaded to the popup, I can successfully upload the file and get it to the post action. But it’s always null when I put the form inside the popup.

    Any guess why?

    Thanks,
    czetsuya

  17. John Says:

    Fantastic post.

    However I cant get a datepicker to work inside your dialog.
    Its fine inside a normal JQueryUI Dialog – Just not after using the exampe above?
    i
    .e. If I add to editprofile.cshtml

    $(function () {
    $(“#datepicker”).datepicker();
    });

    Outside of one of your dialogs the datepicker works fine. Inside and it doesnt. Any idea why? Any suggestions would be appreciated.

    Thanks though.. excellent example.

    • Nick Olsen Says:

      The problem is that any JavaScript you put on the edit view will be stripped out by the Ajax call. It is a security issue to try and prevent malicious acts. So what you need to do is place a function named something like styleElements(context) on the Home/Index page that
      takes care of all your styling needs for a given div or element on the page. Then after the dialog is loaded via Ajax, call that method passing in the dialog div as the context.

      The other option is to load a separate Edit.js file via Ajax as well after you load the HTML.

      Hope that helps!

  18. Bil@l Says:

    Hi Nick,
    I’m trying your code in an app I am working on. What happens when I hit “Save” on the dialog, is that I see the URL posting to in the browser address bar and json response is displayed on page, instead of being placed inside the dialog as the code instructs.

    Have you faced such an issue before?
    Thanks

  19. Jeremiah Says:

    My way of doing this is pretty close to yours, however I was wondering how to call multiple actions inside a the jquery dialog without using an Iframe as I need to retrieve values from the popup. Have you ran into this?

  20. Andres Londoño Says:

    Hi! I’m using this dialog to create a subscribe page, and it works, but for something in the development i found and error when i was trying to create a new data, so, i need to show the error to the user (the error is controlled by a try-catch in the server) but in the part when the ajax try to show the result, it doesn’t not refresh the data in this part:
    // Reload the dialog to show model errors
    $(dialog).html(result);
    $.validator.unobtrusive.parse(dialog);
    wireUpForm(dialog, updateTargetId, updateUrl);

    in the controller I has:

    if (ModelState.IsValid)
    {

    try
    {
    repository.save(subscriber);
    }
    catch(Exception ex)
    {
    subscriber.name = subscriber.name.ToUpper(); //this is to view change in the data
    subscriber.error = ex.Message;
    }
    return PartialView(“SubscribePartial”, subscriber);
    }

    How can I refresh the dialog form with this response? and in case that everything was done, how can I show a confirmation message with a ok button?

    Thanks

  21. K Says:

    Is it possible to pop up the modal from within a modal? I tried this and the popup happens, but the second modal does not have any of its css, jquery and does not post although I see the FORM within firebug that has the right action to POST to. What am I missing to make the modal within a modal work? Thanks

  22. lapella Says:

    Hello Nick,

    after I have submitted data and I return Json(new { success = true }); in my Action how can retrieve in javascript wether the action was successful or failed to execute a javascript function where I have to do manually a delete on cascade…

    • Nick Olsen Says:

      Take a look at line 59 of the last script. It checks the result object for the value of the success property. If you need to see if an exception was thrown and you aren’t handling it on your own you can handle the error event of the ajax call.

  23. lapella Says:

    Your dialog forces me to use it in a general way / update data in a general way: $(updateTargetId).load(updateUrl);
    my updateTargetId is e.g. #TreeViewDiv when I load a url into it nothing happens ?

  24. lapella Says:

    Hello Nick, sorry for my rush statement which was non-explaining I realized after I had to leave my computer… I guess I tried now 5 or more ajax form asp.net mvc samples and all are not working or are limited. Maybe there is also a lack of knowledge on my side, but I try to learn. Jquery UI is really bad to learn. Everyone is doing it differently…
    OK come to the point …I asked on SO: http://stackoverflow.com/questions/10677801/validation-errors-are-not-shown-with-ajax-form-in-asp-net-mvc This has nothing to do with your dialog which I left because I did not know/understand HOW I can update a DataRecordListDiv with a new submitted data record by the dialog. You offer a updateTargetId in your DialogForm but well my Form could be a delete list-form, a update/create item form etc… Thus I need to define always a different “callback” to update my datagrid/treeview/etc… I see there no possibility with your DialogForm . Has this a reason that your DialogForm does not define a dataType like Json/Html ? Is this because you return in one Action a JsonResult(valid data) or a PartialView(invalid data) ? Well I just saw you are on SO too, maybe you want answer? 🙂

  25. JD Says:

    Hi Nick,

    Wrapping the JQuery UI dialog is an excellent idea, thanks!

    I just tried incorporating this into my ASP.NET MVC web site and I see the popup show up (with title, close, save and cancel), but no body (no fields in the dialog). The partial view does have a bunch of divs with class =”editor-field”. I am not sure what I’m doing wrong, the only difference I can think of is that I am not using Razor syntax in my website, I am using the classic syntax instead.

    Secondly, cancel closes the dialog, but Save does not call the controller action so something is not right in the wiring (I have checked the name of the action and name of the controller in the Url.Action are correct).

    Any idea on how I should go about debugging this?

    Thanks,
    JD

    • JD Says:

      A second question – what do I need to do so that the 2 EditProfile controller methods in your example above can have 2 different signatures (need to take a different set of parameters). Since the Helper only takes a single parameter for the controller action I am unable to provide independent parameters on the 2 calls to EditProfile.

      Thanks,
      JD

  26. avidgoffer Says:

    Nick, I think your example here is great! I have everything working except the submit. For whatever reason the event tied to the form fires so I get no validation or return trip to the server. Do you have any ideas?

  27. DK Says:

    How would I do without the MVCHelper (DialogFormLink) ?
    Thanks

  28. Sebastien Cabanel Says:

    Hi,
    I try to use your code but I can’t find the way to make it work in my case,
    I need to replace “Edit” by an icon in:
    @Html.DialogFormLink(“Edit”, Url.Action(“EditProfile”), “Edit Profile”, “ProfileContainer”, Url.Action(“Profile”))

    Thanks for your help

    • Nick Olsen Says:

      You would simply need to create a new DialogFormLink extension method that generated a button tag with an embedded image, a link with a background image set via css, or something like that. Then instead of passing in the string “Edit”, you can pass in an image file name or file path.

  29. Rodel Says:

    Hi Nick,

    Excellent article!
    I made simple modifications so that I can set the dimensions of the dialog. I thought it might help someone, or if you could suggest improvement.

    In the helper extension:
    public static MvcHtmlString DialogFormLink(this HtmlHelper htmlHelper, string linkText, string dialogContentUrl,
    string dialogTitle, string updateTargetId, string updateUrl, int? dialogWidth = 0, int? dialogHeight = 0)
    {
    :
    builder.Attributes.Add(“data-dialog-width”, dialogWidth.ToString());
    builder.Attributes.Add(“data-dialog-height”, dialogHeight.ToString());
    }

    In the js file:
    var width = parseInt(element.attr(‘data-dialog-width’));
    if (width == 0)
    width = ‘auto’;

    var height = parseInt(element.attr(‘data-dialog-height’));
    if (height == 0)
    height = ‘auto’;

    $(dialogDiv).load(this.href, function () {
    $(this).dialog({
    modal: true,
    resizable: true,
    title: dialogTitle,
    width: width,
    height: height,

    Thanks,
    Rodel

  30. Kevin Says:

    Very cool, Nick…..copy, paste…works! Thanks for the post!

  31. Paul D Says:

    Great Article!
    I need to use this to Add or Edit with a key field for the edit. How would I add route values to the htmlhelper?

    Thanks!

  32. loiswaisbrooker Says:

    This is a very nice article on “CRUD Operations Using Entity Framework in ASP.NET MVC”. I have find out some other articles link from which I have learnt “CURD operations using Ajax Model Dialog in ASP.NET MVC!”. I think this is very helpful for developers like me.

    http://www.mindstick.com/Articles/279bc324-5be3-4156-a9e9-dd91c971d462/?CRUD%20operation%20using%20Modal%20d

    http://www.dotnet-tricks.com/Tutorial/mvc/42R0171112-CRUD-Operations-using-jQuery-dialog-and-Entity-Framework—MVC-Razor.html

  33. Stefan Baychev (@Stefan___) Says:

    Thank you for the article helped me a lot by working on and using your scripts, css and overall idea of how to do a validation, a really elegant way of making it!

  34. Taipan Says:

    Thank you for such a brilliant article. But I have one problem. When I click on the link no dialog appears, it just redirects me to the action page. Could you help me?

  35. Dick Nagtegaal Says:

    Great post! Especially the helper method and the unobtrusive syntax.

    One thing I haven’t been able to solve is that the user has to press the Save button with the mouse. I’d like pressing Enter have the same effect as clicking Save. So it should still perform the validation of the form and only close it if the controller action returns true.

    • Nick Olsen Says:

      The only way I have see this work is to handle the key down event on all inputs in the form and validate and submit the form manually. Something like this:

      $('form').on('keydown', function(e) {
      // check for enter key using e.which and then call $(this).valid() and submit.
      });

  36. john hayes Says:

    thanks for posting – that is a really cool solution!

  37. Itumeleng Says:

    Hi, there…how do i pass routeValues and htmlAttributes to the custom HtmlHelper (DialogFormLink)?

  38. Ben Says:

    Nick, have you looked into porting this logic to using bootstrap and bootbox.js instead of jquery-ui? -Ben

  39. Nicolas R Says:

    Hi Nick,

    Thanks for your demo, it’s a very good start for me. I still have a small problem in the implementation: I’m using it with a grid of items, not only one item, and I’m refreshing the grid zone if the Save button has been clicked and the return is a success like you are doing. But when I then try to Edit a line (after refresh, same line or not), the edit windows is not in a modal view!

  40. hankhepler Says:

    Hi Nick,
    Just ran across this tutorial and came in very handy. Was wanting to download and link is gone (yes I know it has been a while since you posted this 😉 but was wanting to see the entire flow. I am wondering if it may be somewhere else available for download?

    Thanks!!

  41. Kumar Says:

    Hello nick, I used your code it works fine, but problem with me is when I’am trying to show jquery-ui tabs inside the modal popup div , it fails to show the tabs . Please help me! Thanks

  42. Rohit Kesharwani Says:

    nice article. I also done a article i.e. based on crud and jquery dialog(s).

    http://rohit-developer.blogspot.in/2014/08/crud-multiple-jquery-dialogs-in-aspnet.html

    I think this will also help user(s) to some extent.
    Thanks, keep writing and inspiring us.

  43. Борис Илларионов Says:

    Hello! I used your code it works fine, but I have 2 problems:
    1. When I click on the link twice without refreshing the page no dialog appears (by the second time), it just redirects me to the action page.
    2. There is no icon “close”. Just empty square.
    Could you help me? Thanks.


Leave a reply to Paul D Cancel reply