iamhx
iamhx

Reputation: 472

ASP.NET MVC jQuery Unobtrusive Validation to compare between two dates

I'm trying to validate StartDate and EndDate using System.ComponentModel.DataAnnotations, such that the End Date must not be lesser than the Start Date. In my Model, I have defined the dates as follows:

public partial class MyModel
{
    [Required]
    public DateTime StartDate { get; set; }

    [Required]
    public DateTime EndDate { get; set; }
}

And I have also created a View Model as follows:

public class CompareDateVM : IValidatableObject
{

    public MyModel myModel { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {

        if (myModel.EndDate < myModel.StartDate) {
            yield return
              new ValidationResult(errorMessage: "End Date cannot be lesser than Start Date.",
                                   memberNames: new[] { "EndDate" });
        }
    }
}

The server-side validation works and the error message is able to display in my View Page's `@Html.ValidationSummary(), but I am unable to get the validation working on the client-side.

@model CompareDateVM
<form asp-controller="AddDate" asp-action="Add" method="post">

    <label class="label">Start Date</label>
    <input type="date" asp-for="myModel.StartDate" />
    <span asp-validation-for="myModel.StartDate" class="validation"></span><br /><br />

    <label class="label">End Date</label>
    <input type="date"  asp-for="myModel.EndDate" />
    <!-- This is where the client side validation error message show up, but it does not appear-->
    <span asp-validation-for="myModel.EndDate" class="validation"></span>

    <input type="submit" value="Add Date" />
</form>
<!-- Server side validation works -->
<p>@Html.ValidationSummary()</p>

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.1.1.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.16.0/jquery.validate.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/5.2.3/jquery.validate.unobtrusive.min.js"></script>

How do I get <span asp-validation-for="myModel.StartDate" class="validation"></span> to show the error message on client side with jQuery Unobtrusive Validation?

Upvotes: 1

Views: 1701

Answers (1)

TanvirArjel
TanvirArjel

Reputation: 32069

To get the custom unobtrusive validation in ASP.NET/ASP.NET Core MVC, you need to use RemoteAttribute as follows:

Step1: Your Model class should be as follows:

public partial class MyModel : IValidatableObject
{
    [Required]
    public DateTime StartDate { get; set; }

    [Required]
    [Remote(action: "IsEndDateSmallerThanStartDate", controller: "Validation", AdditionalFields = nameof(StartDate), ErrorMessage = "End Date cannot be lesser than Start Date.")]
    public DateTime EndDate { get; set; }

   // This is for server side protection
   public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
   {
       if (EndDate < StartDate)
       {
          yield return new ValidationResult(errorMessage: "End Date cannot be lesser than Start Date.", memberNames: new[] { "EndDate" });
       }
   }
}

Step 2: Then in the Validation Controller:

public class ValidationController : Controller
{
    public JsonResult IsEndDateSmallerThanStartDate(DateTime endDate, DateTime startDate)
    { 
        bool isEndDateGreaterThanStartDate =  endDate > startDate;
        return Json(isEndDateGreaterThanStartDate); // if isEndDateGreaterThanStartDate variable value is true, that means validation is successful, if false that means validation fails.
    }
}

Remember you don't need any ViewModel, so remove the ViewModel.

Step-3 : Then your cshtml file should be as follows:

@model MyModel

<form asp-controller="AddDate" asp-action="Add" method="post">
    <!-- Server side validation works -->
    <p>@Html.ValidationSummary()</p>

    <label class="label">Start Date</label>
    <input asp-for="StartDate" class="form-control" />
    <span asp-validation-for="StartDate" class="validation"></span><br /><br />

    <label class="label">End Date</label>
    <input asp-for="EndDate" class="form-control" />
    <span asp-validation-for="EndDate" class="validation"></span>

    <input type="submit" value="Add Date" />
</form>

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.1.1.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.16.0/jquery.validate.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/5.2.3/jquery.validate.unobtrusive.min.js"></script>

Hope everything will now work as expected!

Upvotes: 2

Related Questions