Developing ASP.NET MVC 3 Application with EF CTP (Part 4)

In this post I will examine a couple of things.  I am going to use jQuery calendar UI functionality to improve user interface.  I will also add client side validation to my input form.

First, let’s add calendar control.  To do so, we have to download jQuery UI from .http://jqueryui.com/

Once this is completed, I will copy jquery.ui.core.js and jquery.ui.datepicker.js into Scripts folder of my application and include them in my project.  I will also copy calendar.gif as image for calendar button.  Next, I will add links to those scripts to my master page – in case of Razor view engine it is _Layout.cshtml.  Here is what it looks like:

<head>
    <title>@View.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.4.1.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>
    <link href="@Url.Content("~/Content/jquery-ui-1.8.6.custom.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery.ui.core.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.datepicker.js")" type="text/javascript"></script>
 
</head
>

 

It appears that if I just drag the script into _Layout.cshtml, then it does not work.  I had to add @Url.Content to make it work.  Now that this is completed, I have to update my partial page for blog entry and update my date textbox to use date picker from jQuery.  Here is what my code looks like now:

            <div class="editor-label">
                @Html.LabelFor(model => model.PostedOn)
           
</div>
            <div class="editor-field">
                @if
(Model.PostedOn.HasValue)
                {
                   
<input type="text" name="PostedOn" id="PostedOn" class="uidatepicker" 
value=@string.Format("{0:MM/dd/yyyy}", Model.PostedOn) />
                }
               
else
                { 
                   
<input type="text" name="PostedOn" id="PostedOn" class="ui-datepicker" />
                }
                @Html.ValidationMessageFor(model => model.PostedOn)
           
</div
>

 

As you can see, the code is pretty simple, but I will explain it in more detail just in case.  Since I am using formatting for the value, I would like to account for blank date.  If I do not do conditional control, my blank date will show up as “/”.  This is pretty ugly, so I am using different input controls – one with formatting, the other without.  Now, I need to call datepicker function  to setup my input control for Posted On date.  I am going to use ready function and add a small script to the bottom of my partial view I am using to edit blog:

<script type="text/javascript">
    $().ready(function
() {
        $(
‘.ui-datepicker’
).datepicker({
            dateFormat:
‘mm/dd/yy’
,
            buttonImage:
@Url.Content("~/Content/calendar.gif")
,
            buttonImageOnly:
true
,
            showOn:
"button"
        });
    });

</script
>

 

A few configuration options for date picker as pretty simple.  I am using month/day/year format, I am using the image I got from jQuery, and I showing image only, not the button and image on it.  That is all there is to it.  Now when I click on calendar image, I get calendar popup.

 

Next step is to get client validation to work.  I need a couple of scripts I am including in the code above: jquery, jquery.validate, jquery.validate.unobtrusive.  Next step is to simply enable validation on my view by calling EnableCleintValidation as in below (in bold):

@model MvcSampleApp.Models.BlogEntry
@{Html.EnableClientValidation();}
@
using
(Html.BeginForm())
{
@Html.ValidationSummary(
true
)
 
       
<fieldset
>

Here is the final version of my view:

@model MvcSampleApp.Models.BlogEntry
@{Html.EnableClientValidation();}
@
using (Html.BeginForm())
{
@Html.ValidationSummary(
true
)
 
       
<fieldset>
            <legend>Blog Post</legend>
            <div class="editor-label">
                @Html.LabelFor(model => model.Title)
           
</div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.Title) 
                @Html.ValidationMessageFor(model => model.Title)
           
</div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Title)
           
</div>
            <div class="editor-field">
                @Html.DropDownListFor(model => model.CategoryID, new SelectList(Model.Categories, "CategoryId", "CategoryName", Model.CategoryID), "– Select Category –"
)
                @Html.ValidationMessageFor(model => model.CategoryID)
           
</div>
            <div class="editor-label">
                @Html.LabelFor(model => model.PostText)
           
</div>
            <div class="editor-field">
                @Html.TextAreaFor(model => model.PostText) 
                @Html.ValidationMessageFor(model => model.PostText)
           
</div>
            <div class="editor-label">
                @Html.LabelFor(model => model.PostedOn)
           
</div>
            <div class="editor-field">
                @if
(Model.PostedOn.HasValue)
                {
                   
<input type="text" name="PostedOn" id="PostedOn" class="ui-datepicker" value=@string.Format("{0:MM/dd/yyyy}", Model.PostedOn) />
                }
               
else
                { 
                   
<input type="text" name="PostedOn" id="PostedOn" class="ui-datepicker" />
                }
                @Html.ValidationMessageFor(model => model.PostedOn)
           
</div>
            <div>
                <input type="submit" value=@TempData["Action"] />
            </div>
            @Html.Hidden("BlogEntryId"
)
       
</fieldset>
 
}
 

<script type="text/javascript">
    $().ready(function
() {
        $(
‘.ui-datepicker’
).datepicker({
            dateFormat:
‘mm/dd/yy’
,
            buttonImage:
@Url.Content("~/Content/calendar.gif")
,
            buttonImageOnly:
true
,
            showOn:
"button"
        });
    });

</script
>

 

You can see that validation works by typing one letter into title and tabbing out. You will see immediate error without post back.  This is because I have a rule on my title:

        [Display(Name = "Title")]
        [
StringLength
(30, MinimumLength = 5)]
        [
Required
]
       
public string Title { get; set; }

 

image

And that is all there is to it.

Thanks.

3 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *