5

I have the following form in a partial view

@model PartDetail
@using (Ajax.BeginForm("Create", "Part", null, new AjaxOptions { UpdateTargetId =       "update_panel"}))
{
    <h3>New @Model.PartType</h3>
    <p> Serial Number: 
        <strong>
            @Html.EditorFor(model => model.SerialNumber)
            @Html.ValidationMessageFor(model => model.SerialNumber)
        </strong>
    </p>
    <p> Name: 
        <strong>
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </strong>
    </p>
    ...... more relatively boiler plate code here......
    <p>
        <input type="submit" class="btn primary" value="Save Part"/>
    </p>
}

With a model of

public class PartDetail
{
    public string DateCreated { get; set; }
    [StringLength(255, MinimumLength = 3)]
    public string Description { get; set; }
    public Guid ID { get; set; }
    public string IsActive { get; set; }
    public string Manufacturer { get; set; }
    public IEnumerable<SelectListItem> Manufacturers { get; set; }
    [StringLength(100, MinimumLength = 3)]
    public string Name { get; set; }
    public string PartType { get; set; }
    [Required]
    [StringLength(100, MinimumLength = 3)]
    public string SerialNumber { get; set; }
}

And I reference (in parent views of my partial view)

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

And nothing gets validated. If I type nothing into the Serial Number text box and press submit it saves it to the database with no problems.

PlTaylor
  • 7,345
  • 11
  • 52
  • 94

4 Answers4

18

Try adding an OnBegin callback to the AjaxOptions and this should work.

function validateForm() { 
   return $('form').validate().form(); 
} 

@using (Ajax.BeginForm("Create", "Part", null, new AjaxOptions { UpdateTargetId = "update_panel", OnBegin = "validateForm" }))
...

If this doesn't work for you, an alternative solution may be to submit the form using jQuery. This would be my preferred solution.

<div id="result"></div> 

@using (Html.BeginForm()) 
{ 
<h3>New @Model.PartType</h3>
<p>Serial Number: 
    <strong>
        @Html.EditorFor(model => model.SerialNumber)
        @Html.ValidationMessageFor(model => model.SerialNumber)
        </strong>
    </p>
    <p> Name: 
        <strong>
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </strong>
    </p>
    ...... more relatively boiler plate code here......
    <p>
        <input type="submit" class="btn primary" value="Save Part"/>
    </p>

    }

jQuery/JS function to submit the form

    $(function () { 
        $('form').submit(function () { 

        $.validator.unobtrusive.parse($('form'));  //added

            if ($(this).valid()) { 
                $.ajax({ 
                    url: this.action, 
                    type: this.method, 
                    data: $(this).serialize(), 
                    success: function (result) { 
                        $('#result').html(result); 
                    } 
                }); 
            } 
            return false; 
        }); 
    });
Nick
  • 5,844
  • 11
  • 52
  • 98
  • The top of my partial view now looks like this and it is still not validating.... @using (Ajax.BeginForm("Create", "Part", null, new AjaxOptions { UpdateTargetId = "update_panel", OnBegin = "validateForm" })) { – PlTaylor Jan 17 '12 at 14:20
  • Stick an alert('test'); in validateForm() to see whether it is hit at all. – Nick Jan 17 '12 at 14:23
  • I updated my answer with a jQuery style solution. Although it doesn't address the problem you're experiencing, I prefer to use jQuery over Ajax and thought I'd give you the option here. – Nick Jan 17 '12 at 14:35
  • Let me implement that and give it a try. My main goal is for it to function reliably. Whatever technology it takes to do that is a secondary concern. – PlTaylor Jan 17 '12 at 14:42
  • You'll need to specify the post URL - just noticed I hadn't specified it in my example (e.g. /Part/Create) – Nick Jan 17 '12 at 14:45
  • I implemented that verbatim (except I change '#result' to #update_panel) and it submits the form and acts as before with no validation. I'm obviously missing something fundamental here. – PlTaylor Jan 17 '12 at 14:52
  • 1
    Try running $.validator.unobtrusive.parse($('form')); after submitting – Nick Jan 17 '12 at 15:31
  • Updated my answer above with this in place. – Nick Jan 17 '12 at 15:38
  • That did it!! ($.validator.unobtrusive.parse($('form'));) Thanks for your persistence. – PlTaylor Jan 17 '12 at 16:49
3

In this case order of javascript file including process is important. Your order of including these file should be

jquery.js
jquery.validate.js
jquery.validate.unobtrusive.js

When I tried with re-ordering it works fine for me. Try it.

Sandip
  • 112
  • 8
1

Check your root Web.config of the solution/project. Does it contain the following lines?

  <appSettings>
    <add key="ClientValidationEnabled" value="true"/> 
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/> 
  </appSettings>

It not, add them.

Anders Arpi
  • 8,277
  • 3
  • 33
  • 49
0

you need to modified your controller action little bit to work validation in Ajax request you catch RenderHtml of partial view and apply your validation on it for e.g

    //In Controller 



     public string Create(PartDetail model)
        {
            string RenderHtml = RenderPartialViewToString("PartailViewName", model);
            return RenderHtml;
        }



protected string RenderPartialViewToString(string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString("action");

            ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);
                return sw.GetStringBuilder().ToString();
            }
        }

you must be pass ViewName and Model to RenderPartialViewToString method. it will return you view with validation which are you applied in model.

Shivkumar
  • 1,903
  • 5
  • 21
  • 32