Unfortunate Things with JSON, jQuery UI Datepicker, and Dates
I’m trying to write an HtmlHelper extension that lets you dump out options that build a jQuery UI datepicker on the client. (I know there are some of these out there, but for various reasons I won’t get into… I get to make one, too.)
Something that will let me do this:
@Html.DatePickerFor(m => m.SomeDate);
In doing that, I’ve uncovered a lot of frustration around getting the options specified on the server over to the client and working in a consistent format.
- jQuery UI datepicker has its own date formatting mechanism. It doesn’t use the same format strings as .NET, sprintf, strftime, or anything else I can figure. Same goes for parsing. That means integration with validation (or other stuff that needs to get the date on the client) is kind of painful. It also means you either end up writing crazy date format converters or you replace the date parsing/formatting wholesale. I ended up writing tiny proxy methods that make use of the Microsoft parsing/formatting extensions because then I can also let the default MVC model binder do whatever it needs to do in a locale-aware manner without having to special-case stuff.
- jQuery UI datepicker localization is lacking. In .NET resources, you have this sort of fallback mechanism where “en-US” falls back to “en” which falls back to invariant culture. You provide the most specific culture, fallback handles the rest. Not so with the jQuery UI datepicker. You have to sort of “know” whether the specific culture is supported and/or the general culture and set it directly yourself. This, of course, means dates from the server (String.Format style) will potentially be inconsistent with dates formatted on the client side. I ended up generating all of the localized options on the server and piping them to the client rather than using the script-based localization.
- jQuery.data() hates camelCase attributes. Yeah, I know HTML
attributes are all supposed to be lowercase. But try this with
jQuery 1.9.0: Set up an HTML element like this:
<div id="test" data-someDataHere="1">Content</div>now try and get that using jQuery.data():
var data = $("#test").data().someDataHere;It won’t work. You’ll get some sort of exception down in the bowels of things because it’s looking for an attribute that’s all lower-case-dashes like
data-some-data-hererather than the actual attribute name.
Anyway, I got to find these through experience so hopefully it’ll help others save some time.