jQuery, MVC3: Submitting a partial view form within a modal dialog
Asked Answered
S

5

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.

Symbol answered 22/6, 2011 at 16:30 Comment(0)
S
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.

Symbol answered 27/9, 2011 at 7:44 Comment(0)
W
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
});
Wanting answered 22/6, 2011 at 16:39 Comment(5)
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) <div class="editor-label"> @Html.LabelFor(model => model.Name) </div> <div class="editor-field"> @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name) </div> <p> <input type="submit" value="Save" /> </p> }Symbol
@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?Wanting
Sorry for being vague! The submit call back isn't being executed. $('form', html) is returning length: 0.Symbol
@ETFairfax, OK, try giving the form an unique id and use it in the selector: $('#myForm').submit(...);.Wanting
No joy-Still the same results as before! I'll keep playing round and let you know if I solve the mystery!!Symbol
S
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.

Symbol answered 27/9, 2011 at 7:44 Comment(0)
E
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 :)

Endue answered 22/6, 2011 at 16:38 Comment(0)
J
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})"

Jordan answered 24/6, 2011 at 4:45 Comment(0)
E
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()
                    });
                }
             }                 
        });
Emeraldemerge answered 4/2, 2014 at 17:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.