Todd
beat me to releasing details on our Q1_2007 release, but here it is again: we
are finally releasing an update to the RadInput product: RadInput
2.0!!! The new version will include three brand new controls:
-
RadTextBox: a nice, skinnable <asp:TextBox> replacement control that will help you build slick-looking applications;
-
RadNumericTextBox: a textbox control, specifically created for numeric data entry: think quantities, currency, percentages;
-
RadDateInput: a completely rewritten version of the v1.x RadDateInput control that takes a different approach to date entry.
My favorite is RadDateInput as it posed one of the biggest challenges I
have met in my work here at Telerik: building a non-restrictive,
assistive date input control. The 1.x version of the component would
hurt users' feelings by being too restrictive. It would insist on
slapping your wrists the first time you would hit the wrong key.
This time we have learned our lesson! We felt that the best approach
here is to give the user absolute freedom at entering whatever s/he
feels is a correct date. We would then take that and parse it into
something meaningful. But how do we do that reliably enough? How do we
help users that want us to recognize dates like "1.1.07", "2007-Jan-1",
"January 1, 2007", "1/1/07"? How do we handle time entries both all by
itself, and accompanied by a date? This is where we found out handling
all this with a ton of if-then-else statements would be close to
impossible and even if we succeeded we would have never been able to
add a feature on top of the first release. That is when somebody asked
"can we express all this with a
formal grammar!" We toyed with the idea a bit, tried stuff out in the small, and then... just did it. Keep reading to find out how.
Right now RadDateInput features a full-blown
lexer, and a
recursive-descent parser that implement the date recognition. In total we have three components involved in date parsing and evaluation:
- The lexer. This guy splits the string into well known
tokens: it looks for separators, numbers, week days, month names (both
in full and abbreviated, all culture-specific), time values, AM/PM
designators. The result that we get after the lexer finishes is a
stream of tokens.
- The parser. Here we do not work with raw strings anymore: we
deal with tokens and apply the grammar productions to recognize if we
are dealing with a number-month pair, a full date triplet, a week day,
just an hour-minute-seconds time entry, etc. Some of the grammar,
expressed in BNF, might look like this:
DATETRIPLET ::= NUMBER DATEPAIR
DATEPAIR ::= NUMBER NUMBER |
NUMBER MONTH |
MONTH NUMBER
We use rules like the above to produce a tree structure that represents our date and time entry.
- The evaluator. This is where we take the number, month, week
day, hours, minutes, etc tokens and apply rules and heuristics, taking
into account both the specified date format and the current culture to
get to the final date. For example if we get a number pair, we would
look if the current culture usually specifies dates as month-day or
day-month and will respect that. We will do the right thing and will
assign values accordingly if we can infer something in addition, say
"30 4" is obviously April 30, no matter if you write it as "30 4" or "4
30".
I am really pleased with the final result: we easily handle a myriad of
possible input combinations without sacrificing flexibility. The most
important thing for us is that the parser is really extensible, and we
can extend it by adding advanced rules for things like "+2hrs" or "next
Friday" in the future. We will be expecting your feedback on this one
:-).
I and the entire team are really proud of the product and we are sure
this little control will be of great help to many people. Happy data
entry!