7

I'm just playing around with jQuery and MVC3 at the moment, and am wondering how I can submit a form, which has been dynamically loaded into a jQueryUI dialog?

My code so far consists of...

Javascript/jQuery

$(document).ready(function () {

    $('.trigger').live('click', function (event) {

       var id = $(this).attr('rel');

       var dialogBox = $("<div>");

       $(dialogBox).dialog({
           autoOpen: false,
           resizable: false,
           title: 'Edit',
           modal: true,
           show: "blind",
           hide: "blind",
           open: function (event, ui) {
               $(this).load("PartialEdit/" + id.toString());
           }
        }
    });

    $(dialogBox).dialog('open');

})    });

cshtml

<h2>Detail</h2><a href="#" class="trigger" rel="1">Open</a>

Controller

public ActionResult PartialEdit(int id)
    {
        return PartialView(new EditViewModel() { Name = id.ToString() });
    }

    [HttpPost]
    public ActionResult PartialEdit(int id, FormCollection collection)
    {
        // What to put here???            
    }

The Partial View

....@using (Html.BeginForm()){....Html.EditorFor(model => model.Name).....}....

As you can see the load() in jQuery calls a PartialView named PartialEdit.

The form is loading up just fine, but I'm stuck working out how I actually submit the form?

Questions

How do I get the UI to submit the form, and close the dialog? What should the [HttpPost]PartialEdit return?

At the moment I have the submit button within the partial view. When clicked, the form is submitted, and the browser does whatever the [HttpPost]PartialEdit returns (currently resulting in a blank page being displayed).

However, after a submit I would like instead to trigger an event on the client side (Maybe a full page refresh, or a partial page refresh depending on the context it is used). I'm not sure where to start?

Also, should I be placing a submit button within the PartialView, or should I use the buttons on the jQuery-UI dialog?

Any suggestions/pointers appreciated.

Mathieu
  • 4,449
  • 7
  • 41
  • 60
ETFairfax
  • 3,794
  • 8
  • 40
  • 58

5 Answers5

6

Try something among the lines:

open: function (event, ui) {
    $(this).load("PartialEdit/" + id.toString(), function(html) {
        $('form', html).submit(function() {
            $.ajax({
                url: this.action,
                type: this.method,
                data: $(this).serialize(),
                success: function(res) {
                    if (res.success) {
                        $(dialogBox).dialog('close');
                    }
                }
            });
            return false;
        });
    });
}

and the controller action could return JSON:

[HttpPost]
public ActionResult PartialEdit(int id, FormCollection collection)
{ 
    // do some processing ...

    // obviously you could also return false and some error message
    // so that on the client side you could act accordingly
    return Json(new { success = true });
}

The final part for improvement is this:

"PartialEdit/" + id.toString()

Never do such url hardcoding in an ASP.NET MVC application. Always use url helpers when dealing with urls. So make your anchor a little more dynamic and instead of:

<a href="#" class="trigger" rel="1">Open</a>

use:

@Html.ActionLink(
    "Open", 
    "PartialEdit", 
    new {
        id = "1" // you probably don't need a rel attribute
    }, 
    new { 
        @class = "trigger"
    }
)

and then:

$(this).load(this.href, function(html) {
    ...
    return false; // now that the anchor has a href don't forget this
});
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Many thanks for your suggestion. Problem at the moment is that $('form', html).submit(function() {...}); isn't working. Does my partial view need to be anything special? So far its just.. @using (Html.BeginForm()) { @Html.ValidationSummary(true)
    @Html.LabelFor(model => model.Name)
    @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name)

    }
    – ETFairfax Jun 23 '11 at 09:56
  • @ETFairfax, could you please define `isn't working`? Does the `$('form', html)` selector returns the form element when you log this in FireBug console? Is the `submit` callback executed? – Darin Dimitrov Jun 23 '11 at 11:34
  • Sorry for being vague! The submit call back isn't being executed. $('form', html) is returning length: 0. – ETFairfax Jun 23 '11 at 12:26
  • @ETFairfax, OK, try giving the form an unique id and use it in the selector: `$('#myForm').submit(...);`. – Darin Dimitrov Jun 23 '11 at 12:29
  • No joy-Still the same results as before! I'll keep playing round and let you know if I solve the mystery!! – ETFairfax Jun 23 '11 at 12:57
1

Thanks for all your input, the solution that is working for me at the moment is having this function attached to the "Submit" button on the dialog....

"Submit": function () {
    var $this = this;
    var form = $('form', $this);
    if (!$(form).valid()) {
       return false;
    }

    $.post(form.attr("action"), JSON.stringify($(form).serializeObject()), function () {
        $($this).dialog("close").dialog("distroy").remove();
    });
}

...which is a bit of a combination of the answers above.

Thanks again.

ETFairfax
  • 3,794
  • 8
  • 40
  • 58
0

I faced a similar problem today, where I had to submit a form which was in a partial view - and the partial view was in a dialog, which was created from another form!

The crux was to get the handler of the form in the partial view and serialize it.

Here is how I defined my dialog in the first form:

var udialog = $('#userdialog').dialog({
            open: function(event, ui) {                    
                $(this).load('xx');
            },
            buttons: {
                "Submit" : function(){                         
                    $.ajax(
                         {
                             url: 'xx',
                             type: "POST",
                             async: true,
                             data: $('form', $(this)).serialize()
                    });
                }
             }                 
        });
gunnerz
  • 1,898
  • 5
  • 24
  • 39
0

The button is ok under the partial view, but it sounds like you want to submit the form via AJAX so there's no page refresh. You can do that like this:

$('#theIdOfYourForm').live('submit', function(event){
    event.preventDefault();
    var form = $(this);
    $.post(form.attr('action'), form.serialize(), function(data){
        if (data.IsError) { alert(data.Error); }
        else { alert(data.Message); }
    });
});

And return a JSON object from your HttpPost PartialEdit action that defines IsError, Error, or Message as necessary. You can get fancier with this, but then this answer would be too long :)

Milimetric
  • 13,411
  • 4
  • 44
  • 56
0

Well, jQuery submit does nothing, you need to have a form inside the partial view, then what happen is when the jQuery dialog submit execute, you call your form submit which have the action defined already.

See my code below which is non ajax submit

      }); 
    $dialog
        .dialog("option", "buttons", {
            "Submit":function(){
                var dlg = $(this);
                var $frm = $(frm);
                if(onFormSubmitting != null)
                    onFormSubmitting();
                $frm.submit();
        },
        "Cancel": function() { 
            $(this).dialog("close");
            $(this).empty();
        }    

    });

And regarding ur question inside post action, you should perform your business logic then call "Return RedirectToAction("viewname",new {id=xxx})"

Vincent
  • 482
  • 8
  • 21