Although I’m a C# guy, I’ve recently really started to like JavaScript. It is so dynamic and “different” that it forces you to really think what you are doing and how do you want it structured – which is a good thing. And if you just want to get things done quick and dirty JavaScript is also a perfect match for that.

When I begun to use JavaScript on daily basis I naturally soon learned to use more and more closures and all that they bring with them. For a while I wrote over and over again code like this:

whatever.success(function(data) {
    render(data, context);
});
function render(data, context) {
    $.tmpl("tmpl", data).appendTo(context);
}

Then I realized that this is not very JavaScript-like. I guess this was the moment I actually started to understand JavaScript. Since then I have more and more used the power of “this” and currying in JavaScript. Both of these materialize in bind-function, like so:

whatever.success(render.bind(context));

function render(data) {
    $.tmpl("tmpl", data).appendTo(this);
}

But opening a page with such code in IE8 brought me back to reality: out of the box bind works only on certain browsers. Luckily almost everything in JS can be fixed afterwards with polyfills and bind is no exception. Since I had some troubles finding/creating a polyfill for both bind and curry that would work on most browsers I’ll document what I’ve used below. I hope these save someone else’s time. Bind function is taken almost directly from excellent Mozilla article, and curry is derived from that.

// Function.prototype.bind polyfill from 
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
if (!Function.prototype.bind) {
    Function.prototype.bind = function (obj) {
        // closest thing possible to the ECMAScript 5 internal IsCallable function
        if (typeof this !== 'function') {
            throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
        }

        var slice = [].slice,
            args = slice.call(arguments, 1),
            self = this,
            nop = function () { },
            bound = function () {
                return self.apply(this instanceof nop ? this : (obj || {}),
                                  args.concat(slice.call(arguments)));
            };

        bound.prototype = this.prototype;

        return bound;
    };
}

if (!Function.prototype.curry) {
    Function.prototype.curry = function () {
        var slice = [].slice,
            args = slice.apply(arguments);

        return this.bind.apply(this, args.concat(slice.call(arguments)));
    };
}

I intended to use Feedburner from the beginning, but I did not find an easy way to modify Orchard (the CMS behind this blog) to link to an external feed. Luckily Bertrand Le Roy came to rescue and created Vandelay Feedburner plugin, which works great.

From now on this blog’s feed is hosted at feeds.feedburner.com/Tero-Teelahti; old address still works but if you follow this blog please change to the new location since that will be more reliable in the long run.

JQuery’s date picker UI component is very easy to localize on Javascript level. On this blog post I’ll describe how to ensure that date picker culture follows site’s server side culture. This is pretty trivial to accomplish, but it won’t hurt to document it here.

First, you need to pick the translations you need from jQuery UI trunk. Place these files on your script folder and include them on your page (or master page), here I’m using my favorite static content bundler SquishIt to combine and minify scripts:

<%=SquishIt.Framework.Bundle.JavaScript()
    .Add("~/Scripts/jquery-ui-1.8.9.custom.min.js")
    .Add("~/Scripts/jquery.ui.datepicker-sv.js")
    .Add("~/Scripts/jquery.ui.datepicker-fi.js")
    .Render("~/Scripts/Site.#.js") %>

Next you need to store language information somewhere for client side use. Good or even best practice is to store that into HTML document root level with “lang” attribute:

<html lang="<%=System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName %>">

Finally date picker needs to be told which language to use. This should be done on page load like this (note, that to set default language en-US you need to give an empty string):

$(function () {
    // Current document language is at HTML root tag
    var lang = $('html').attr("lang");
    // Set datepicker language. 
    $.datepicker.setDefaults(
        $.datepicker.regional[lang === 'en' ? '' : lang]);
});

That’s it! Now your date picker follows your site’s language. This same pattern can of course be used for other JS libraries.

I had a very common requirement to fill: when user clicks form submit button (or enter on keyboard) the button needs to be disabled in order to prevent double submits. Double submits could of course be filtered at server side with various timestamp mechanisms, but this was not what I was after this time.

The first option that came into my mind was of course just to subscribe into form submit and disable buttons there like this:

// Disable all submit buttons within 
// the form that is being submitted
$("form").submit(function () {
    var b = $("input[type=submit]", this);
    b.attr('disabled', 'disabled');
    // Re-enable button after some time in case something went wrong
    setTimeout(function () { b.removeAttr("disabled"); }, 3000);
});

This worked like a charm… except that this code acted also if form validation failed, which is far from optimal. So I needed to find a place to hook into jQuery validation pipeline. This is easy if you call .validate() from own JavaScript code, but in ASP.NET MVC jQuery validation is automatically wired up behind the scenes. So the only easy option I found was to slightly change the default MicrosoftMvcJQueryValidation.js file by tampering the default validation options (see MODIFIED: comments below):

var options = {
        errorClass: "input-validation-error",
        errorElement: "span",
        errorPlacement: function (error, element) {
            var messageSpan = fieldToMessageMappings[element.attr("name")];
            $(messageSpan).empty();
            $(messageSpan).removeClass("field-validation-valid");
            $(messageSpan).addClass("field-validation-error");
            error.removeClass("input-validation-error");
            error.attr("_for_validation_message", messageSpan);
            error.appendTo(messageSpan);
        },
        messages: errorMessagesObj,
        rules: rulesObj,

        // MODIFIED: Ignoring hidden elements
        ignore: ":hidden",

        // MODIFIED: Submithandler added to be able to disable submit button
        submitHandler: function (form) {
            var b = $("input[type=submit]", form);
            b.attr('disabled', 'disabled');

            // Re-enable button after some time in case something went wrong
            setTimeout(function () { b.removeAttr("disabled"); }, 3000);

            form.submit();
        },

        success: function (label) {
            var messageSpan = $(label.attr("_for_validation_message"));
            $(messageSpan).empty();
            $(messageSpan).addClass("field-validation-valid");
            $(messageSpan).removeClass("field-validation-error");
        }
    };

There are two changes above: hidden elements are ignored by default for easier operation with complex forms (toggle block visibilities), and submitHandler is set to disable buttons.

Worked for me, hope this helps someone else.

Ever faced this situation: You have nice and easy controller method, say:

public ActionResult Demonstrate(string id) {   
    this.Repository.Demonstrate(id);   
    string url = this.Url.Action(MVC.Errors.Suck(id));   
    return this.Redirect(url); 
}

Then you go and create test for it (or created the test before, whatever suits you):

[TestMethod]   
public void Demonstrate_ValidInput_Redirects()   
{   
    // Arrange   
    var controller = new MyDemonstratingController();   
 
    // ... mock something here   
   
    // Act  
    controller.Demonstrate("kaboom");  
        
    // Assert  
    // ... test that everything was called  
}

…only to get NullReferenceException, since you did not set everything up that is needed by the UrlHelper class (controller’s Url property).

To satisfy the basic dependencies for a controller you can use MvcContrib’s TestControllerBuilder class like this:

TestControllerBuilder builder = new TestControllerBuilder();   
builder.InitializeController(controller);

InitializeController method adds mock implementations of the following:

  • HttpContext
  • HttpRequest
  • HttpResponse
  • HttpSession
  • Form
  • TempData
  • QueryString
  • ApplicationPath
  • PathInfo

There are also other helper methods than InitializeController in TestControllerBuilder, but for me InitializeController has been the most useful method from that library so far.