Using the jQuery UI datepicker with ASP.NET MVC

I wanted to start the real code for my side project by making a small skeleton of the project in ASP.NET MVC. This skeleton includes a basic form to create an event, which will be the starting point of the application. An event has a name with a start date and an end date that are represented as DateTime, so I figured I’d try my hand at integrating the jQuery UI datepicker to my form. That way, I’ll be able to make sure that jQuery UI is properly included in the application.

First, I included a bundle for the jQuery UI library along with jQuery on the page where I wanted the date picker to be.

After this, I created a input box using the TextBoxFor Razor helper which will be used to initialize the datepicker in JavaScript. I used the short date string so I would only get the date and not the time, and set the control as being read only so the user would be forced to pick the date from the picker. That way, I won’t have to handle the various date formats that could be entered.

<div>
   @Html.LabelFor(model => model.ScheduledEvent.StartDate)
      <div>
         @Html.TextBoxFor(model => model.ScheduledEvent.StartDate, 
                          new { Value = Model.ScheduledEvent.StartDate.ToShortDateString(),
                                @class = "datefield", 
                                @readonly = "readonly" })
      </div>
</div>

After this, I added the following to the JavaScript for my page to initialize the jQuery UI datepicker when the page is loaded.

$(document).ready(function () {
   $(".datefield").datepicker();
});

This already looked good when the page was first loaded, but there was a bug when a date was selected in the picker: the format of the date was not the same. Here is how it looked like with the original start date and the end date that was modified by the date picker:

AfterDatepicker

It works for saving the date, but it doesn’t look very good so this has to be fixed. But why is the format wrong? Well, my development machine is currently set to the fr-CA culture. ASP.NET MVC understands the fr-CA culture just fine and renders the dates in the format specified for that culture. On the client side thought, jQuery UI does not include the localization file to handle the date format for this culture by default, so it fallbacks to a standard format when setting an new date.

Fortunately, the fix is simple: you must set a default culture in you Web.config that jQuery UI can understand, which is en-US if no localization file is included. That will also make sure that you have the right culture in ASP.NET too regardless of the current culture of the server the application is executing on.

<system.web>
   <globalization uiCulture="en-US" culture="en-US" />
</system.web>

If you want to handle other cultures you must download and use the localization files from the jQuery UI at https://github.com/jquery/jquery-ui/tree/master/ui/i18n. For my project, I decided to force everything to en-US for now since the date format should be the same regardless of the culture of the browser of the user. This is to avoid confusion if multiple users with browsers set to different cultures are using the application to plan an event together.

A few closing notes

Don’t set the type of the input text box to the HTML5 date format, leave it as a standard text box. Otherwise, Chrome will use its own format for the date and you will get the following error when posting the form:
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.

I also looked for the problem in the wrong place for quite a while: I usually submit values to WebAPI instead of submitting an ASP.NET MVC form, and WebAPI uses a different parser for dates.

Minimalist programming for the web

I’m not the most minimalist person in real life: I always have a ton of things going on, be it gardening, cooking, crafting or coding projects. This is a pretty common plight for a programmer since we like to tinker. But when I code something for production and not as a toy project, I believe that minimalist is something important to keep in mind. This way, my code is simpler and easier to maintain for me and for other people.

There are many aspects to minimalist in a software project, from your technology choices from the start to good coding practices when the project is ongoing.

Keeping you code simple

The number one priority is readability and easy of maintenance, by you and by others. Trying to reduce the length of variables names or function names at all costs gets in the way of being understood. You want to keep a reasonable length so the names are clear while still being able to fit a line of code on the screen. Another good thing is to use a common coding standard for all the code on a project: there is no one true coding standard, but it’s easier to understand code without distractions when it all looks similar. In doubt, you can just use the same standard as the library or framework you are using.

Also, you want to eliminate pointless complexities in your code. First, all the code in your codebase should be actually used. Don’t code things just in case they may be needed. It just adds more moving parts that needs to be maintained, and when the case you coded it for finally happens, you’ll most likely find out that what you need is a bit different than what you implemented anyway. Following the same ideas, parts that are no longer needed should be removed, not just commented or left lying around. You can always retrieve the code you removed using source control if you ever need it again.

Finally, keep the things you are doing simple, for example, don’t use CSS selectors from hell if you could simply add a meaningful class to your markup instead. Also, useless conditions should be eliminated: if doing a piece of logic every since time has not negative consequences and has a negligible performance cost, you can do it all the time. It may even be faster to just run the code instead of checking a condition! Also, you can use returns to leave methods as early as possible to reduce the levels of indentation and make code easier to read.

Less is More Minimal Simplicity Efficient Complexity Concept

Using libraries

If your goal is maintainability, you can’t always go with the shiny new toy: something new is always a risk, and you don’t want to spend a lot of time with it if it’s going to be dropped in a few months. So, when I create a new project, I aim to start with as little components and tools I can get away with. The simplest code that is closest to the HTML/CSS/JavaScript standards are always the best for long-term maintainability.

For example, for a ASP.NET MVC web application, even the default template is pretty bloated: the ASP.NET MVC framework itself (and the dependencies like the Entity Framework), jQuery and a good control library like jQuery UI is more than enough. Any additional library that you add have a cost: they will need to be maintained and updated, and you have to keep yourself up to date with all the new upgrades. If you are not using the library at the moment or only a tiny part, it’s a lot of noise to sort through while you could be doing something that moves the project forward.

Don’t get me wrong, I’m not anti-library: I don’t believe in reinventing the wheel, and if a part of my application has special requirements not covered by the .NET framework, I’ll gladly use a library that implements it. For me, a good library to use is one that does the job it needs to and not a few dozen other things, has good documentation and is regularly upgraded and maintained. It also should not take over my architecture by forcing me to use complicated patterns and by pulling along any other dependencies.

Separating concerns

I’m not a testing wizard, but there are many things you can do to help yourself start on the right foot even before you start writing that first unit test. First, you should have a simple but clean architecture, separating the business logic in the model, the controllers getting the data and the views handling the display logic. The truth about the business logic should be kept in one place in your architecture so it is easier to modify it. For performance and usability, you can add a few validations to the client-side JavaScript, but the server-side code saving the data should always has the last word. A validation that’s on the client can always be bypassed anyway, so you should never trust something sent to the server by the browser.

Also, on a lower level, you should make it clear what are the responsibilities of each class and method is doing and document each of them properly, including all the edge cases. I don’t believe in zero comments: the documentation is there to explain why you are doing something and how to use that method, not just to repeat details about the inner working of the method. A method should do only one thing: if it gets too big, it’s going to be hard to know what are all the possible code paths. Nice and small methods or views with clear responsibilities are easier to reuse in your code, and don’t need as many new tests since it’s known code.

What is SignalR and why should I use it?

When I first heard about SignalR, I was not sure what was the point of it. The official description says that SignalR is a library that can be used with any ASP.NET application to add real-time communication. But since what they meant by real-time was not totally clear to me, and the only example was a chat room, I pushed it aside for a while.

When I started to work on my side project, I also started thinking about SignalR again. One of the things I want to was refresh the schedule as soon as a change was made: if a user makes a modification, it should be visible to all other users. The classic way to do something like that would be to call the server at regular intervals to get the status of the schedule, but to have pseudo real-time update your must call the server pretty often.

With SignalR, the server can call a JavaScript methods on all the clients by itself when updates are required. The library will handle the connection needed to achieve this: by default WebSocket is used, but it will fallback automatically to older connections types if WebSocket is not available in the browser. The JavaScript can also call the server: this can already be done with AJAX, but if two-way communication is needed it may be easier and cleaner to do it all with SignalR.

So, using a real-time library is the way to go if you want to build an application that requires collaboration between users. Common uses cases includes editors, social networks, chats or a schedule like my project.

Getting started wtih SignalR is pretty simple. Here is an example with my side project: sessions for an event can be modified by any user, and when a session is modified the change is visible for all the user currently logged in the application.

On the server
First, you must add the Microsoft ASP.NET SignalR package to your ASP.NET application using NuGet, along with the jQuery package if you don’t already have it.

After this, you must create a class that derives from the Hub class. All the methods of the hub can be called from JavaScript. Also, those methods can call JavaScript methods on the client.

namespace EventScheduling
{
public class SessionsHub : Hub
   {
   public void SessionModified(ScheduledSession scheduledSession)
      {
      // Call the JavaScript method sendSessionChanged on all the clients
      Clients.All.sendSessionChanged(scheduledSession);
      }
   }
}

To enable communications between the hub and the JavaScript, you must also enable SignalR in the Configuration method in the Startup class of your application.

namespace EventScheduling
{
public class Startup
   {
   public void Configuration(IAppBuilder app)
      {
      app.MapSignalR();
      }
   }
}

On the client
On the client, you must include the jquery.signalR-2.2.0.js file containing the JavaScript for the SignalR library and the package ~/signalr/hubs. This package is automatically generated from your Hub classes and contains all the JavaScript required to call the server and receive message from the server.

<script src="/Scripts/jquery-1.10.2.js"></script>
<script src="/Scripts/jquery.signalR-2.2.0.js"></script>
<script src="~/signalr/hubs"></script>

After this, when the page is loaded and ready, you must declare the JavaScript function called by the server-side code. Since the Hub class is called SessionsHub and the SessionModified method of the hub class calls the sendSessionChanged method, this function must be declared in the $.connection.sessionsHub.client.sendSessionChanged variable.

Once this function is created, you must also connect to the hubs using the $.connection.hub.start method. You can also add initialization code in the done() callback which will be called when the connection is started.

$(document).ready(function () {
   // Create a function that the hub can call to broadcast messages.
   $.connection.sessionsHub.client.sendSessionChanged = function (session) {
      // Display the session again using the new data received from the server
      });
   };

   // Start the connection and create a function that the hub will call when loaded
   $.connection.hub.start().done($("#Sessions").on("click", ".Session", function (event) {
      var that = $(this);
      var currentSession = that.data("session");
      currentSession.Title = currentSession.Title + "Clicked";
      // Call the server, which will notify all clients of the change in the title
      $.connection.sessionsHub.server.sessionModified(currentSession);
   }));
});

In the example, when the hubs are done starting, a click handler is added to each session on the page. When the users clicks a session, the word Clicked is added to the title of that session, and all browsers showing the page are notified. Since the SessionModified method was declared in the SessionsHub class of the server, it can be called from JavaScript using using the $.connection.sessionsHub.server.sessionModified method.

With only this small bit of code, you now have two-way communications between the client and the server, which you can use to update data in real-time for your users. I will use SignalR in future projects that’s for sure!