0

I need to do client-side validation for ASP.NET MVC5 application. What I want to achieve is; when user fill each field in form, its validated same time and change field color or border color to red as he/she going along with data entry in form.

I have added all require details but for some reason it is not happening;

bundleConfig

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));

        bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
          "~/Scripts/jquery-ui-{version}.js"));

        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.validate*",
                    "~/Scripts/jquery.validate.unobtrusive.js"));

Main page Layout

I have added jquery in html header as;

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>@ViewBag.Title</title>
              @Styles.Render("~/Content/css")
              @Styles.Render("~/Content/themes/base/ThemeCSS")
              @Scripts.Render("~/bundles/modernizr")
              @Scripts.Render("~/bundles/jquery")
  </head>
  <body>
      //my other code....
      //at bottom

  @Scripts.Render("~/bundles/bootstrap")
  @Scripts.Render("~/bundles/jqueryui")
  @Scripts.Render("~/bundles/jqueryval")
  @Scripts.Render("~/bundles/DefaultThemeScripts")
  @RenderSection("scripts", required: false)
 </body>
</html>

Student Model class

this is form model class

public class Student
{
    public Student(){}

    [Key]
    [Display(Name="Student ID")]
    public int StudentID { get; set; }

    [Display(Name = "Student UWL ID")]
    [Required(ErrorMessage="Require Your Student UWL ID")]
    [Range(0, Int32.MaxValue, ErrorMessage = "Only Number Allowed")]
    public int StudentNumber_UWLID { get; set; }

    [StringLength(50)]
    [Required(ErrorMessage = "Required Title")]
    [Display(Name = "Title")]
    public string Title { get; set; }

    [StringLength(50)]
    [Display(Name = "Other Title")]
    public string OtherTitle { get; set; }

    [StringLength(50)]
    [Required(ErrorMessage = "Required Gender")]
    [Display(Name = "Gender")]
    public string Gender { get; set; }

    [StringLength(250)]
    [Required(ErrorMessage = "Required First Name")]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [StringLength(250)]
    [Display(Name = "Middle Name")]
    public string MiddleName { get; set; }

    [StringLength(250)]
    [Required(ErrorMessage = "Required Last Name")]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }

    [StringLength(250)]
    [Required(ErrorMessage = "Required Nationality")]
    [Display(Name = "Nationality")]
    public string Nationality { get; set; }

    [StringLength(250)]
    [Required(ErrorMessage = "Required Your Date Of Birth")]
    [Display(Name = "Date Of Birth")]
    public System.DateTime DateOfBirth { get; set; }
 }

Razor form

@model App.DAL.Model.Student

<script type="text/javascript">

$('#CreateStudentProfileForm').submit(function (e) {

    e.preventDefault();

    var formURL = $(this).attr("action");
    $ajax({.....
   )};
 </script>


@using (Html.BeginForm("CreateStudentProfile", "StudentProfile", FormMethod.Post, new { id = "CreateStudentProfileForm" }))

{
   @Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>Student</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.StudentNumber_UWLID, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.StudentNumber_UWLID, new { htmlAttributes = new { id = "StudentNumber_UWLID", @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.StudentNumber_UWLID, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.OtherTitle, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.OtherTitle, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.OtherTitle, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Gender, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Gender, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Gender, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.MiddleName, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.MiddleName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.MiddleName, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Nationality, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Nationality, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Nationality, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.DateOfBirth, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.DateOfBirth, new { htmlAttributes = new { @class = "form-control datepicker" } })
            @Html.ValidationMessageFor(model => model.DateOfBirth, "", new  { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}

<div>
     @Html.ActionLink("Back to My Profile Home Page", "MyProfile")
</div>

Web.config

 <appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

Controller class

  [HttpGet]
    public ActionResult CreateStudentProfile()
    {
        return PartialView("CreateStudentProfile_Partial");
    }

    [HttpPost]
    public ActionResult CreateStudentProfile(Student _studentModel)
    {
        try
        {
            if(ModelState.IsValid)
            {
               int _entityID =  _studentProfileServices.CreateNewStudentProfile(_studentModel);

               if (_entityID != 0) 
               {
                   return Json(new { Response = "Success" });
               }
               else
               {
                   return Json(new { Response = "Error" });
               }
            }
            else
            {
                return Json(new { Response = "Invalid Entry" });
            }
        }
        catch (DataException ex)
        {
            ModelState.AddModelError("", "Unable To Create New Student Profile" + ex);
        }

        return PartialView("CreateStudentProfile_Partial", _studentModel);
    }
K.Z
  • 5,201
  • 25
  • 104
  • 240
  • Remove `@Scripts.Render("~/bundles/jqueryval")` from the view - your are loading it twice (its already in the layout). Also the bindle you just have `"~/Scripts/jquery.validate*"` - the `*` (wildcard) means that `jquery.validate.unobtrusive.js` is also included –  Jun 30 '15 at 11:40
  • thank you for that, I have removed it but still not working! – K.Z Jun 30 '15 at 11:42
  • Comment out the script and see of the error messages are displayed –  Jun 30 '15 at 11:43
  • I am not getting any error message is just not happening – K.Z Jun 30 '15 at 11:48
  • may be I am doing something wrong in my controller class.... I have update my question with my ActionResult methods – K.Z Jun 30 '15 at 11:49
  • Have you commented out the script (it wont even work). If you enter something in the (say) `Title` textbox, tab out then tab in again and clear its contents the as soon as you tab out you should see an error message –  Jun 30 '15 at 11:56
  • no it doesn't ... I have tried that ... – K.Z Jun 30 '15 at 13:19
  • You code looks OK with the previous suggestions (except the script but we can fix the script issue later). Have you checked you browser tools to see if the scripts are loading correctly (sources tab) –  Jun 30 '15 at 13:23
  • I have found solution, refer to my answer ... many thats for help. much appreciated – K.Z Jun 30 '15 at 13:49

3 Answers3

1

As My pages where I am creating form are partial view so it has to handle differently then the standard view.. I have found solution in do my research on google as following;

http://code.davidferguson.me.uk/post/47540738095/mvc-client-validation-after-partialview-loaded-via

//this code goes in your partialview
$(function(){ 
   //allow the validation framework to re-prase the DOM
   jQuery.validator.unobtrusive.parse(); 

   jQuery.validator.unobtrusive.parse("#formId");
 });

//...

$(function(){
$("#SubmitButton").click(function(){ 
  if (!$("#Form1").valid()){ 
    return false; 
   } 
 });
});
K.Z
  • 5,201
  • 25
  • 104
  • 240
  • Then you should have mentioned that you were dynamically loading the content! –  Jun 30 '15 at 21:54
0

I found a solution perfect solved my problem. Before you call $.validator.unobtrusive.parse, remove the original validator and unobtrusive validation from the form like so: below is the code:

var form = $("#main_div").closest("form");
form.removeData('validator');
form.removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse(form);
The details you should reference here
Community
  • 1
  • 1
Paul Cong
  • 21
  • 3
-1

There are two ways.

Either place your JqueryVal bundle above just after Jquery scripts bundle. like

 @Styles.Render("~/Content/css")
 @Styles.Render("~/Content/themes/base/ThemeCSS")
 @Scripts.Render("~/bundles/modernizr")
 @Scripts.Render("~/bundles/jquery")
 @Scripts.Render("~/bundles/jqueryval")

or write your scripts in script section

@section scripts
{
    // write scripts here
}

Reason is, your jquery validations files renders after your scripts tag. So when your script access validation function it will give error.

Ankush Jain
  • 5,654
  • 4
  • 32
  • 57