Using the jQuery Globalization plugin to toggle between edit and display
The web application I am working on involves a lot of data entry. Since my client is an insurance company, some of the values we are expecting to see inputted can venture into the millions.
The project manager came around the other day and mentioned, “You know … if you are entering large numbers in Excel, it automatically shows the comma separator so you can easily discern the amount you are entering. It sure would be nice if the application displayed commas in the fields like Excel does.”
So … I put on my jQuery hat and came up with a solution that I think works rather nicely.
I remembered that the Gu recently posted about using the jQuery globalization plugin. By using this plugin, we can avoid writing custom parsing and formatting functions. Instead, we can leverage the work that has already been done to do those functions with the added bonus of instant support for over 350 cultures.
Setting it up
First of all, download the plugin and add a reference to it on your View:
<script type="text/javascript" src="/Scripts/jquery.glob.min.js"></script>
And here are the custom jQuery extensions I wrote that can be called on our text boxes.
jQuery.fn.formatForDisplay = function () {
// call formatValue() passing in a formatting function
return $(this).formatValue(
function(val,fmtString) {
// format the string using the globalization plugin
// i.e. 1500000 becomes 1,500,000.00
return jQuery.format(val,fmtString);
});
}
jQuery.fn.formatForEdit = function () {
return $(this).formatValue();
}
jQuery.fn.formatValue = function(fnDoFormat) {
var that = $(this);
// default to 2 decimal places unless it is marked
// with a "numbers" class
var decPlaces = that.hasClass("numbers") ? 0 : 2;
var fmtString = "n" + decPlaces.toString();
var thatVal = that.val();
if (thatVal && thatVal !== '') {
// parse the value using the globalization plugin
var parsedVal = jQuery.parseFloat(thatVal, fmtString);
if (!isNaN(parsedVal)) {
// call the format function if it was passed in
var fmtVal = fnDoFormat ? fnDoFormat(parsedVal, fmtString) : parsedVal;
that.val(fmtVal);
}
}
return that;
}
Here’s how it works. When the page is rendered, the fields are formatted to “display” mode using the browser’s default locale. Once a user enters a field, the field enters into “edit” mode and the formatting is removed. When the user leaves a field (i.e. the blur() event is fired), the field value is formatted once again.
Wiring it up
I am using CSS classes to mark if a textbox should contain decimals or numbers. I am also using a “noformat” class to make sure we can ignore certain textboxes if we don’t want them formatted.
$(document).ready(function() {
var fieldsForFormat = $(".numbers:not(.noformat),.decimal:not(.noformat)");
fieldsForFormat
.live('focus', function() { $(this).formatForEdit(); })
.live('blur', function() { $(this).formatForDisplay(); })
.each(function () { $(this).formatForDisplay(); });
});
When the page is rendered, we get the fields we want to toggle for display/edit. We wire the focus() event so that the value is stripped of location formatting, and wire the blur() event to add the formatting back in. We also initialize each field for display.
How does it look?
Here are two screenshots, showing how a field will look on focus and on blur:
| Focus (Edit mode) | Blur (Display mode) |
One more thing…
Keep in mind, the field values are now “strings” and not “ints” or “floats”. If you are expecting these values to be numbers, you will have to do some manipulation, either in javascript before the form is submitted or in your controller.
