2010
01.17

Continuing with my current javascript theme i’ve been thinking quite a bit about the way in which we write RIAs. It would seem from many examples i’ve seen that it’s always approached like someones first windows forms application. All the code is in one file with a mixture of purposes and frequently very difficult to test. I’ve seen a few attempts to solve the problem but the intention/responsibility of the code is never quite clear.

After some experimentation the best way seems to be to adopt a MVP (Passive View) style approach. Here’s an example…

var CalculatorPresenter = {
  setup: function() {
    CalculatorView.setup();
  },
  addNumbers: function() {
    var firstNumber = CalulatorView.getFirstNumber();
    var secondNumber = CalculatorView.getSecondNumber();
    CalcualtorView.setResults(firstNumber + secondNumber);
  }
}

var CalculatorView = {
  setup: function() {
    $("addbutton").click(CalculatorPresenter.addNumbers);
  },
  getFirstNumber: function() {
    return parseInt($("firstnumber").val());
  },
  getSecondNumber: function() {
    return parseInt($("secondnumber").val());
  },
  setResult: function(value) {
    $("result").val(value);
  }    
};

$(document).ready(CalculatorPresenter.setup);

I really like this approach because the intention is not lost in a sea of UI code. Everything that relates to DOM manipulation or traversing should be in the view and the “logic” should be in the presenter. Testing this now becomes very simple, here’s an example using jsTestDriver to test the view…

CalculatorViewTest = TestCase("CalculatorViewTest", {
  testThatTheValueOfTheFirstFieldCanBeRetrieved: function() {
    $("body").append(
      $("<input/>")
        .attr("id","firstnumber")
        .attr("type","text")
        .attr("value","10"));
    assertEquals(10, CalculatorView.getFirstNumber());
  }
});

Same again but for the presenter, I’m also using the Jack mocking framework to isolate it from the view so i’m not testing both.

CalculatorPresenterTest = TestCase("CalculatorPresenterTest", {
  testAddingTwoNumbersTogether: function() {
    jack(function() {
      jack.expect("CalculatorView.getFirstNumber").returnValue(10);
      jack.expect("CalculatorView.getSecondNumber").returnValue(10);
      jack.expect("CalculatorView.setResult").stub().withArguments(20);
      CalculatorPresenter.addNumbers();
    });
  }
});
2010
01.16

Few conversations with colleagues later and a few small changes to the validation framework.

  • Fixed typo in adding custom rules test.
  • Added “length less than”, “length greater than” and “is a number” rules
  • Updated example to include some of the new validation rules

What next?

Date validation seems to be one that keeps cropping up. DateJs provides a great library for dealing with all sorts of date formats. Im considering whether this should be an optional set of rules as the sizes of DateJs would negate the bennifit of the small validation core if included with it. I’m also considering an optional set of patterns for common international problems (e.g.Email address and Uri), if they are small enough perhaps they should be in the core as well.

2010
01.16

Photography from the fields

Found this on my camera, I had totally forgotten about this picture. It’s not the best shot, i must remember to do that walk again for a second attempt.