I'm working with .NET Framework / MVC 4 / C#. I have a View that contains a Partial View which I update/refresh depending on user actions which include clicking a SAVE or CANCEL button. An Ajax request calls a Controller method which returns a Partial View with a blank model to refresh the View. THE PROBLEM is that when returning to the Ajax call from the Controller method, the HTML that the Ajax call presents is the OLD HTML from the Partial View that I am trying to replace??? The model returned by the Controller method is definitely blank, but the Ajax request is not getting it for some strange reason.
After the user clicks either button:
- A javascript function is triggered.
- The Form inside the Partial View is serialized (hidden inputs, text boxes, and dropdowns).
- The serialized Form data is passed into an Ajax request which calls a Controller method and passes in the data.
//Submit a New Payment
$('#paymentpartial').on("click", ".savepayment", function () {
event.preventDefault();
var $form = $('form');
if ($form.valid()) {
var form = $form.serialize();
//Save
$.ajax({
url: '/Payments/SavePayment',
datatype: "json",
traditional: true,
data: form,
cache: false,
success: function (html) {
$("#paymentpartial").html(html);
oTable.fnDraw();
},
//AJAX call failed
error: function (data, status, errorThrown) { alert(status + ", " + errorThrown); }
});
}
return false;
});
Controller method does stuff and returns a Partial View with a blank model.
public ActionResult SavePayment(PaymentSummaryVM model) { try { //Save Stuff Here //Build a brand new model for the Partial View PaymentSummaryVM newModel = new PaymentSummaryVM(); newModel.ParticipantId = model.ParticipantId; List<PaymentType> pTypes = db.PaymentTypes.Where(pt => pt.Active == true).OrderBy(pt => pt.ord).ToList(); newModel.PaymentTypeList = new SelectList(pTypes, "PaymentTypeId", "Name"); return PartialView("_AddEditPayment", newModel); } catch (Exception ex) { TempData["Error"] = "There were errors while saving your changes. " + ex.Message; return RedirectToAction("Index", new { id = model.ParticipantId }); } return RedirectToAction("Index", new { id = model.ParticipantId }); }
- On success, Ajax returns the HTML of the Partial View and injects it in a DIV using the jQuery .html() function.
$.ajax({
url: '/Payments/SavePayment',
datatype: "json",
traditional: true,
data: form,
cache: false,
success: function (html) {
$("#paymentpartial").html(html);
}
- THE PROBLEM is that the HTML returned by the Controller method, as seen in the Ajax call, is the OLD HTML from the previous Partial View that I'm trying to replace. I'm so confused. Here's the Partial View HTML:
@using BeyondThemes.BeyondAdmin.Models
@model PaymentSummaryVM
@if (Model.PaymentId == 0)
{
<div class="widget-header bordered-bottom bordered-blue">
<span class="widget-caption">New Payment</span>
</div>
}
else
{
<div class="widget-header bordered-bottom bordered-blue">
<span class="widget-caption">Edit Payment</span>
</div>
}
<div class="widget-body" style="margin-bottom:20px">
@Html.HiddenFor(m => m.ParticipantId)
@Html.HiddenFor(m => m.PaymentId)
<div class="row">
@Html.Bootstrap().LabelFor(m => m.PaymentDate).LabelText("Date:").HtmlAttributes(new { @class = "col-md-1 control-label" })
<div class="form-group col-md-3">
@Html.Bootstrap().TextBoxFor(m => m.PaymentDate).Placeholder("Payment Date").HtmlAttributes(new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.PaymentDate)
</div>
@Html.Bootstrap().LabelFor(m => m.PaymentTypeId).LabelText("Type:").HtmlAttributes(new { @class = "col-md-1 control-label" })
<div class="form-group col-md-3">
@Html.Bootstrap().DropDownListFor(m => m.PaymentTypeId, Model.PaymentTypeList).OptionLabel("Select a Payment Type").HtmlAttributes(new { @class = "form-control", @id = "creditcard" })
@Html.ValidationMessageFor(m => m.PaymentTypeId)
</div>
@Html.Bootstrap().LabelFor(m => m.Notes).LabelText("Notes:").HtmlAttributes(new { @class = "col-md-1 control-label", @maxlength = "250" })
<div class="form-group col-md-3">
@Html.Bootstrap().TextAreaFor(m => m.Notes).HtmlAttributes(new { @class = "form-control", @maxlength = "250" })
@Html.ValidationMessageFor(m => m.Notes)
</div>
</div>
<div class="form-group col-md-offset-1">
<div class="row">
<div class="col-md-1">
</div>
<div class="col-md-1">
<button type="button" class="btn btn-success savepayment" style="width:100%">Save</button>
</div>
<div class="col-md-1">
<button type="button" class="btn btn-default cancelpayment" style="width:100%">Cancel</button>
</div>
<div class="col-md-9">
</div>
</div>
</div>
</div>
And it's being injected from the main View like this:
@using (var form = Html.Bootstrap().Begin(new Form().Type(FormType.Horizontal).HtmlAttributes(new { @id = "paymentpartial" })))
{
Html.RenderPartial("_AddEditPayment", Model);
}
UPDATE: I just got it to do what I wanted. I had to make the following change, that is, NOT SERIALIZING the form. Just passed in the specific value..Really no clue why this worked but hey..
var pid = $("#ParticipantId").val();
$.ajax({
url: '/Payments/GetAddPaymentPartial',
datatype: "json",
//traditional: true,
data: { participantid: pid },