Showing posts with label jQuery UI. Show all posts
Showing posts with label jQuery UI. Show all posts

Validating Date with MVC Foolproof Validation on the client side

This is a quick tip for something that I just tried with an ASP.NET MVC app and that worked as expected.

I use MVC Foolproof Validation to complement the standard validators that come with ASP.NET MVC in the System.ComponentModel.DataAnnotations assembly. Foolproof has some awesome validators like:

[Is]
[EqualTo]
[NotEqualTo]
[GreaterThan]
[LessThan]
[GreaterThanOrEqualTo]
[LessThanOrEqualTo]
[RequiredIf] [RequiredIfNot] [RequiredIfTrue] [RequiredIfFalse] [RequiredIfEmpty] [RequiredIfNotEmpty] [RequiredIfRegExMatch] [RequiredIfNotRegExMatch]

You can get it through a NuGet package here.

Let’s say you have a form with a DateTime field called “Show Until” that is part of a Notice object. This property stores a date value that should be in the future obviously. It makes no sense to set a date in the past for this field. So the question is: how can you get client side validation for this field without the need of going to the server to compare the date the user entered with today’s date?

This is what this post will show you…

This is the model property decorated with the respective data annotation GreaterThanOrEqualTo:

[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Localization))]
[Display(Name = "ShowUntil", ResourceType = typeof(Localization))]
[GreaterThanOrEqualTo("Today", ErrorMessageResourceName = "GreaterThanOrEqualTo", ErrorMessageResourceType = typeof(Localization))]
public DateTime ShowUntil { get; set; }

Pay attention to that "Today", string value. It tells Foolproof’s validator to compare the ShowUntil property with a property called Today (the dependent property). Wait a moment: the Notice object doesn’t have a property called Today since it’s not necessary. What’s the point? Confused smile

Now let’s add a partial class to extend the Notice class with a property called Today. This property returns Today’s date of course.

public partial class Notice
{
    public DateTime Today
    {
        get { return DateTime.Today; }
    }
}

Run the app now, enter a date in the past for the ShowUntil field and submit the form. You’ll see that a postback is made to the server and only after that the validation error message is shown to the user. Foolproof’s validator doesn’t know what’s the value of Today yet since it’s not part of the form data being edited. Remember: this kind of server side validation is not what we want. We want client side validation. We don’t want this data round-trip to the server just to validate one field in the form. So, how to solve this? It’s pretty simple…

Inside your form view (.cshtml file) since I’m using C# as the programming language and Razor view engine, add this hidden field:

@Html.HiddenFor(model => model.Today)

Now reload the page and try entering a date in the past like yesterday’s date. You’ll see that the user gets the validation error message instantly. Why? Because now Foolproof’s jQuery validator that is added to page has Today’s date value present in the form’s HTML output (that’s the purpose of the hidden field). If you look at the form/page source code in the browser (right click the browser window and select “View Page Source” in Firefox), you’ll se this value:

<input data-val="true" id="Today" name="Today" type="hidden" value="29/06/2012 00:00:00" />

That’s it. No date in the past is allowed when adding a new Notice to the system.

This use case can be considered a good use for Hidden fields. They serve a multitude of purposes…

Hope it helps.

Updated at 12:45 PM

You see how things are... after posting this I just discovered a really straightforward way of getting what I wanted (by chance) I can tell you. I wasn’t looking for this anymore when I hit this StackOverflow question. Looks like God took me there… Open-mouthed smile I happen to be using jQuery UI Datepicker control too. It has between its vast array of options a minDate property. So if you do this:

<script type="text/javascript">

    $(document).ready(function ()
    {
        $("#ShowUntil").datepicker('option', 'minDate', new Date());
    });

</script>

new Date() is Today in Javascript and so the datepicker won’t allow the selection of dates in the past. One word: AWESOME. One liner with jQuery help!

Using jQuery to disable/enable and check/uncheck Radio Buttons on Date selected

Motivated by this question on StackOverflow - Disable radio button depending on date, I decided to help and here I’m with another code snippet post.

This time I show you how to use jQuery UI and its Datepicker control to control a set of radio buttons (only 2 in this post to make things easier) that have their state (enabled/disabled) changed depending on the date selected by the user.

Here’s the code:


<!DOCTYPE html>
<html>
<head>

   
<meta charset="UTF-8" />
    
   
<title>jQuery UI - Datepicker & Radio Buttons</title>

   
<!-- Linking to jQuery stylesheets and libraries -->
   
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/themes/base/jquery-ui.css" type="text/css" media="all" />

   
<link rel="stylesheet" href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" type="text/css" media="all" />
   
   
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>

   
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js" type="text/javascript"></script>
   
   
<script src="http://jquery-ui.googlecode.com/svn/tags/latest/external/jquery.bgiframe-2.1.2.js" type="text/javascript"></script>

   
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/i18n/jquery-ui-i18n.min.js" type="text/javascript"></script>

</head>

<body>

   
<script>

   
$(function()
    {
       
$("#datepicker").datepicker
        ({          
           
// Event raised everytime a date is selected in the datepicker
            onSelect: function(date)
            {
               
// Self explanatory :) - used to get today's date
                var today = new Date();

               
// Business logic to change radio buttons' state                 if($("#datepicker").datepicker("getDate") > today)
                {
                   
$("#radioButton1").attr('disabled', true);
                   
$("#radioButton2").attr('disabled', false); 
                }
               
else
                {
                   
$("#radioButton1").attr('disabled', false);
                   
$("#radioButton2").attr('disabled', true); 
                }
            }
        });

       
// Just setting the default localization for the datepicker
        $.datepicker.setDefaults($.datepicker.regional['']); 
    });
    
   
</script>

   
<p>Date: <input id="datepicker" type="text"></p>

   
<input id="radioButton1" type="radio" value="myValue1" name="radioButton1"/>Radio button 1<br/>
   
<input id="radioButton2" type="radio" value="myValue2" name="radioButton2"/>Radio button 2

</body>

</html>

If you wanted to control the state (checked/unchecked) you’d have to make a small change in the code as follows:


// Business logic to change radio buttons' state                 if($("#datepicker").datepicker("getDate") > today)

   
$("#radioButton1").attr('checked', true); 
   
$("#radioButton2").attr('checked', false);  

else 

   
$("#radioButton1").attr('checked', false); 
   
$("#radioButton2").attr('checked', true);  
}

When you open the page for the first time you get this screen:

Page when viewed for the first time (both radio buttons are enabled)
Figure 1 - Page when viewed for the first time (both radio buttons are enabled)

If you pick a date that is greater than today’s date, Radio button 1 is disabled (turns to gray) and Radio button 2 is enabled according to the logic implemented.

Radio button 1 is disabled (turns to gray) and Radio button 2 is enabled
Figure 2 - Radio button 1 is disabled (turns to gray) and Radio button 2 is enabled

Otherwise, Radio button 2 is disabled and Radio button 1 is enabled:

Radio button 2 is disabled and Radio button 1 is enabled
Figure 3 - Radio button 2 is disabled and Radio button 1 is enabled

Hope you make good use of it.