Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post form data to Controller's action with Ajax

I have a page in MVC3, with a link (Ajax.ActionLink). When user clicks it, it calls controller's action, and the result is inserted into a div, with replace.

Code is shown below:

@Ajax.ImageActionLink("/Images/btn_share.png", "Share pool", "SharePool", new { poolKey = Model.Id, poolName = Model.Name },
    new AjaxOptions { 
        UpdateTargetId="popup", 
        HttpMethod="GET", 
        InsertionMode = InsertionMode.Replace,
        LoadingElementId="loading_dialog",
        OnSuccess = "ShowPopup('#popup_share', true, true)"
    } 

ImageLinkAction is custom extension method to use image as link, and ShowPopup is a javascript function that shows the updated div (to make it look as a popup)

Now the markup code inserted into the div which creates the popup contains a form as below

<div>
@using (Html.BeginForm()) {

    @Html.HiddenFor(model => model.ID)

    <div class="editor-label">
        @Html.LabelFor(model => model.EmailAddress)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.EmailAddress)
        @Html.ValidationMessageFor(model => model.EmailAddress)
    </div>

    // ... other fields

    @Html.ValidationSummary(true)
    <p>
        <button type ="submit">Share</button>       
    </p>
}
</div>

The issue is with the form's submit: the Submit button calls the proper action but with a postback, which cause my page to refresh. What I need is to post data with ajax, receive the response, which is another partial view that gets inserted into the

I was trying to replace the Submit button with Ajax.ActionLink as below

    @Ajax.ActionLink("Share", "Share",
        new Models.MyModel 
            {
                ID = Model.ID,
                EmailAddress = Model.EmailAddress
            },
        new AjaxOptions
            {
                UpdateTargetId="popup", 
                HttpMethod="POST", 
                InsertionMode = InsertionMode.Replace,
                LoadingElementId="loading_dialog",
                OnSuccess = "ShowPopup('#popup_share', true, true)"
            }

The controller's code looks like this:

[HttpPost]
public ActionResult SharePool(MyModel model)
{
    // ...
    return PartialView("_MyPartialView", model)
}

The problem is, in the moment the Ajax ActionLink is rendered (when form is loaded) there is no value in Model.EmailAddress, so my POST action in controller receives only ID parameter.

How can I handle this? Ideally, I think I should add

OnBegin = "PreparePostData()"

But since I know javascript only basically, I have no idea how can I implement this. I think this PreparePostData() should collect form fields and prepare the object routeValues parameter, to be set before the ajax call is invoked.

Anyone can give me some indications on how to implement this?

Or is any other, better approach on this problem?

Thank you

like image 737
bzamfir Avatar asked Apr 25 '12 13:04

bzamfir


People also ask

Is Ajax a post request?

data : A plain object or string that is sent to the server with the request. success : A callback function that is executed if the request succeeds.it takes as an argument the returned data. It is also passed the text status of the response.

How do I call Actionresult from Ajax?

1st you need to return a partial view. You need to be aware of ajax parameters contentType and dataType. From the documentation: contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8'). This specifies what type of data you're sending to the server.


1 Answers

I'd recommend just writing your own AJAX calls with jQuery. It's more flexible than MVC's helpers anyway

@Html.ActionLink("Share", "Share", new { }, new { id = "share" })

And then a function

$("#share").click(function (e) {
   e.preventDefault();
   //Show loading display here
   var form= $("#shareForm");
   $.ajax({
       url : '@Url.Action("Share")',
       data: form.serialize(),
       type: 'POST',
       success: function(data){
          //Show popup
          $("#popup").html(data);
       }
   });
});
like image 149
DMulligan Avatar answered Oct 17 '22 23:10

DMulligan