Coalesce in JavaScript

March 2, 2011

IMHO, one of the most underused operators in C# is the coalesce operator (??).  If you’re not familiar with this operator, it allows you to perform a ternary-like operation testing against a null reference object.  Essentially, it’s a shortcut that returns the left-hand side of the coalescing operator if it’s non-null, or the right hand side if it is null.

Here is an example…

string foo = "foo";
string emptyString = "";
string nullify = null;

string testFoo = foo ?? "foo must have been null";
// testFoo = "foo"

string someString = emptyString ?? "something";
// someString = "";

string testNullify = nullify ?? "nullify must have been null";
// test Nullify = "nullify must have been null"

JavaScript does not have a coalesce operator per se, but idiomatically it does have a equivalent.  Before we dive into that, let’s back up and discuss how JavaScript handles conditional tests. 

In addition to the traditional boolean values of “true” and “false”, JavaScript has the concept (as Doug Crockford calls them) of “truthy” and “falsy” values.  These values don’t map exactly as what a C# developer might expect them to do so since they’re not exactly explicitly 0 or 1. 

Here are the values JavaScript considers “falsy” (taken directly from JavaScript: The Good Parts):

  • false
  • null
  • undefined
  • The empty string ”
  • The number 0
  • The number NaN

All these values, when evaluated in a boolean conditional test, will return false.  Everything else is considered a “truthy” value – but doesn’t necessarily return true.

In JavaScript, when using the || operator, the return value is: 1) the value of the first operand (i.e. not necessarily “true”) if it is “truthy”; or 2) the value of the second operand.  So in order to return false from an or expression in JavaScript, but sides of the expression must be “falsy” values.

Idiomatically, JavaScript developers use the || operator as a de facto coalescing operator.  It is probably confusing to a traditional C-based language developer, but here is how it looks:

var foo = "foo";
var emptyString = "";
var nullify; // null

var testFoo = foo || "foo must be null";
// testFoo = "foo"

var someString = emptyString || "something";
// someString = "something";

var testNullify = nullify || "nullify must be null";
// test Nullify = "nullify must have been null"

So you can use the || operator as a way to initialize objects by comparing it against a “falsy” value.  Think of it as a way to create an object using a default value if one is not already set.  Indeed, this is one of the main ways JavaScript developers use it.

If you are a C# developer, this operator might not make immediate sense.  But once you understand the “truthy” and “falsy” values in JavaScript, you are on your way to writing great JavaScript code.

0

Using the jQuery Globalization plugin to toggle between edit and display

August 9, 2010

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)
On Focus Display

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.

0

Using Server-Side Constant values in Javascript

August 1, 2010

One of the challenges with writing rich web UIs is managing business logic across the client-side and the server-side.  Oftentimes, the lines are somewhat blurry as to where this logic should occur and if/when it needs to be repeated.

I recently ran into a bug in my web application that surfaced when the values from a lookup table in the database had changed.  Even though the constants in the server-side C# code were updated to map to the new values, the literal DB values were hard-coded in the javascript code.  So our javascript code no longer worked since the IDs on the client-side no longer matched what was present in the DB.

Unfortunately, even tools like ReSharper are not enough to help us here.  Since the values were hard-coded in the javascript, a “Rename” operation would not catch the change.  Bugs like these can be very hard to  track down.

In order to prevent this from happening in the future, I decided to take a “DRY” approach to keeping the server-side and client-side variables in sync.

If you need to create global or “application” variables in javascript, you need to do so with some caution.  Anything you name these variables can potentially clash with other 3rd party javascript libraries you are using, as well as other variables in your own code.  A good practice to use is to create a single object literal that will hold all the global variables for your application.

  if (!myApp) { var myApp = {}; }

Now we can starting using this variable to embed our application variables.  The global variable effectively “namespaces” all variables you declare within it.

What I did was to create a separate partial view whose sole purpose is to hold client-side application level information.

The nice thing about this approach is:

  1. it is modular
  2. the information is stored in one recognizable place
  3. it can be included as needed in any web page.

Since the javascript values I declare will be directly mapped to C# constants that will be escaped in the view rendering process, this needs to be performed in a web view rather than in a .js file (where you would normally expect to see it).

So here is my partial view, which I’ve named ~/Views/Shared/JavascriptGlobals.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

<script type="text/javascript">
  if (!myApp) { var myApp = {}; }

  if (!myApp.ccType) { myApp.ccType = {}; }
  myApp.ccType = {
    visa: <%= LookupItem.CC_TYPE_VISA %>,
    amex: <%= LookupItem.CC_TYPE_AMEX %>,
    mastercard: <%= LookupItem.CC_TYPE_MASTERCARD %>
  }
</script>

Now, we can embed this partial into any view we want.  Personally, I include it at the bottom of my master page.

<% Html.RenderPartial("JavascriptGlobals"); %>

Now we can use our application variables in our web pages.

<script type="text/javascript">
  $(document).ready(function() {
    $("#CreditCardType").change(function(evt) {
      var val = $(this).val();
      if (val) {
        var ccType = parseInt(val);
        if ( ccType === myApp.ccType.visa ) {
          // do something
        }
        else if ( ccType === myApp.ccType.amex ) {
          //
        }
        // etc
      }
    }
  }
</script>
1