1

I am using VS2012 / C# / MVC 4.

I am trying to Post a "Contact Us" form without refreshing the whole page. All is fine, the validation kicks in the first time if I miss any required fields and OnSuccess is not fired. After I successfully post the form (not missing any required fields) each additional postings will cause OnSuccess to fire even though the validation failed (required fields are missing). The red exclamation point is displayed correctly and the controller "knows" it failed but the ajax OnSuccess doesn't seem to know about the new failure.

ContactUsForm.cshtml (partialView):

@model contactdemo.Models.ContactUsDetails

  <div id="formContainer">
    @using (Ajax.BeginForm("ContactUsForm", new AjaxOptions { UpdateTargetId = "formContainer", OnSuccess = "displaySuccess" }))
    {    
    <strong>Send To: </strong>
    <div>
        @Html.DevExpress().ComboBoxFor(model => model.ContactID,
            settings =>
            {
                settings.ShowModelErrors = true;
                settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
                settings.Name = "ContactID";
                settings.Properties.ValueField = "ContactID";
                settings.Properties.ValueType = typeof(int);
                settings.Properties.TextField = "ContactName";
                settings.ControlStyle.CssClass = "contactUsCombo";
        }).BindList(Session["Names"]).GetHtml()
    </div>
    <div>
        @Html.DevExpress().LabelFor(m => m.Subject).GetHtml()
        @Html.DevExpress().TextBoxFor(m => m.Subject, 
            settings =>
            {
                settings.ShowModelErrors = true;
                settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
                settings.ControlStyle.CssClass = "subjectText";
            }).GetHtml()
    </div>
    <div>
        @Html.DevExpress().LabelFor(m => m.Message).GetHtml()
        @Html.DevExpress().MemoFor(m => m.Message, 
            settings =>
            {
                settings.ShowModelErrors = true;
                settings.Height = 50;
                settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
                settings.ControlStyle.CssClass = "memoText";
            }).GetHtml()
    </div>
    <div>
        @Html.DevExpress().Button(
            settings =>
            {
                settings.Name = "btnSubmit";
                settings.Text = "Send Message";
                settings.UseSubmitBehavior = true;
                settings.ControlStyle.CssClass = "contactUsCombo";
            }).GetHtml()
    </div>       
}

HomeController.cs:

namespace contactdemo.Controllers
{
[OutputCacheAttribute(VaryByParam = "*", Duration = 1, NoStore = true)]
public class HomeController : Controller
{
    <snip...>

    [HttpGet]
    [OutputCache(Duration = 60, VaryByParam = "*")]
    public ActionResult ContactUsForm()
    {
        return PartialView(new ContactUsDetails());
    }

    [HttpPost]
    public ActionResult ContactUsForm(ContactUsDetails data)
    {
        if (ModelState.IsValid)
        {
            return PartialView(new ContactUsDetails());
        }
        else
        {
            return PartialView(data);
        }
    }   
}

Index.cshtml:

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

<script type="text/javascript">
function displaySuccess(result) {
    alert("Sent Successfully");
}
</script>
Nick
  • 1,417
  • 1
  • 14
  • 21
Gina Marano
  • 1,773
  • 4
  • 22
  • 42

1 Answers1

2

Make sure that inside your displaySuccess callback you reattach the unobtrusive validation handler to the newly added contents to the DOM:

function displaySuccess(result) {
    $('#formContainer form').removeData('validator');
    $('#formContainer form').removeData('unobtrusiveValidation');
    $.validator.unobtrusive.parse('#formContainer form');

    alert('Sent Successfully');
}

The reason you need to do this is because you are refreshing the contents of your DOM with the new partial after an AJAX callback and the unobtrusive validation framework has no way of knowing those new elements unless you tell it to. You might also take a look at a similar answer.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Apparently when I am bundled it does not work: Microsoft JScript runtime error: Unable to get value of the property 'unobtrusive': object is null or undefined – Gina Marano Feb 07 '13 at 18:36