Tuesday 21 June 2011

JavaScript useful stuff

In the last months I've been working pretty hard on an Asp.Net MVC project with a rich frontend based on jQuery, jQuery ui and jqGrid. I plan to do some write up about what I've learned about jqGrid, it's a beautiful beast, but depending on what you plan to do with it its documentation can be a bit scarce and you may end up spending much time with Firebug and reading how others have tackled similar problems in StackOverflow.
By the way, another really, really interesting piece of JavaScript wisdom that has been terribly useful to me is linq.js

To the point, in this post I'm just going to touch some basic stuff, but the kind of stuff that however clear it is now, in a few months could be blurry again to me... so good to spend a few minutes preparing a short entry for future reference and time saving.


  • Given how JavaScript evaluates expressions to boolean values and the short circuited nature of the || operator, we have a pretty useful "default operator", pretty similar to C#'s ?? operator:

    st = st || "default"; //if st is null initialize it to default

    remember that "", 0, null and undefined are evaluated to false, but " " or "0" are evaluated to true.

    A similar trick, when we want to coerce one value to boolean, we can use this:
    !!myValue

  • undeclared, undefined and null:
    When trying to access a variable that has not been declared we get a:
    ReferenceError: xxx is not defined
    if we have declared the variable, but have not assigned any value to it, it does not get initialized to null, but to undefined
    var a;
    console.log(a);

    it's the same when we access a parameter that has not been passed to a function:
    function f1(a,b){console.log(b);}
    f1("hi");

    We also get an undefined when we try to access to a missing property in an object:
    var ob = {name: "xose"};
    ob.age;

    curiously enough, if we are in the global scope and want to avoid a possible "a is not defined" error, we can access it as a property of window, and so we'll get undefined instead of that error.

    If we want to evaluate for undefined, given that we don't have an undefined keyword, we'll have to resort to this:
    if (typeof(a) == "undefined")

  • Array.prototype.splice function is a rather unnatural way to perform 2 pretty common operations (both operations modify the existing array):
    Remove 1 item from position index:
    ar.splice(index, 1);

    Insert 1 item ("Xana") in position index:
    arr.splice(index, 0, "Xana");

  • jQuery's $.inArray function has a pretty misleading name, cause contrary to what we would expect, it does not return a boolean value, but a numeric index indicating the position in the array (-1 if it's not there). This is rather troublesome cause if you were expecting a boolean and your searched item happens to be in the first position... you get a 0 that JavaScript will evaluate to false...

    It's also odd that it only works with values and not with predicates... good that it's so easy to implement our own:

    commonFunctionality.indexOf = function (predicate, arr) {
    for (var i = 0; i < arr.length; i++) {
    if (predicate(arr[i])) {
    return i;
    }
    }
    return -1;


  • Decimal separator and locales:
    There's a good discussion here. To summarize it and my own experience:
    The only decimal separator understood by JavaScript is ".". That means that irrespective of your locale settings, when you use floats in your code, you'll ever have to type them as:
    var myFloat = 5.4;
    and not:
    var myFloat = 5,4;

    also, if you want to feed parseFloat with a string to turn it into a float, the string has to use "." as separator, not ",".
    On the other hand, if you have a float number and you turn it to a string by concatenating it want an empty string:
    var str = myFloat + "";
    you'll ever get the "." as decimal separator.
    If you want to obtain a localized string, you can use:
    myFloat.toLocaleString();

  • Validate dates. This is not about masks to prevent non numeric, non separator characters, or regular expressions to check those characters, but when you already have a numeric day, month and year, and want to validate that we don't have a wrong date like February 30, or April 31...
    Well, what seems a weakness ends up being the solution. It would be convenient if when we create a Date with new Date(year, month, day), we got a null when the date is invalid in the sense formerly described. On the contrary, Javascript extends the Date in this way:

    new Date(2011, 3, 31);//remember that months start at 0, so 3 is April

    we get April 1 2011 as result instead of an exception or a null.

    Well, as I said before, the solution lies also in this behavior, we only need an extra step, comparing the new Date with the initial one:

    var day = 31;
    var month = 4;
    var year = 2011;
    var dt = new Date(year, month-1, day);
    if (dt.getFullYear() !== year ||
    dt.getMonth() !== month - 1 ||
    dt.getDate() !== day) {
    return "invalid date";


  • And finally, another couple of jQuery tips:
    Attribute selectors: select those checkboxes that are checked:
    $(input[type=checkbox]:checked);

    if you already have some jQuery objects, how do you merge them into an only jQuery object? I mean, let's say you have two jQuery objects wrapping 2 tables and want to apply the same function to all tr's in those tables:
    you can use .add with a new empty jQuery object, something like this:
    $().add($table1).add($table2).find("tr")....

    in some cases you could also do the trick with something like:

    $.each([$table1, $table2], function(){this.find("tr").css("backgroundColor","red");});

No comments:

Post a Comment