31 October 2010

Model/UI Model/UI Controler javascript patter in short

I've watched today an interesting presentation about functional design patters and I wanted to share it with you my dear and loved reader.

http://www.infoq.com/presentations/Functional-Design-Patterns

Functional programming and functional languages started interesting my from the moment I grokked Javascript. Javascript is an interesting language that blends, in my opinion, good sides from both the object oriented paradigm and the functional paradigm.

Lets face it. Javascript is used mostly for dynamic GUI's on the web and on the mobile platform. User interface events are behavior(action oriented) and the functional style of programming can be very useful in such and environment with some good speed gains. But also the DOM or the UI is an object rich environment , full of entities, relations and etc. Not to mention custom POJSO's (Plain Old Javascript  Object) indicating  varius states our screen can take or coordinating the behavior of other objects in the same screen.

I generally do something like this. First I define my screen entities, those objects that correspond to specific entities which live happily on my screen:


function Person(name, age, sex)
{
  this.Name = name;
  this.Age = age;
  this.Sex = sex;
}



I will then link those two entities to corresponding UIEntities. UIEntities are those POJSO's that group a set of DOMElements and coordinate their UI logic in respect to the current state of the associated Entity object.

For example:

function PersonUIModel(element,person)
{
    this.Element= element;
    this.Name = this.Element.find("input.person-name");
    this.Age = this.Element.find("input.person-age");
    this.Person = person
}

PersonUI.prototype = {
  validateRequired:function(textBox)
  {
      if (textBox.val()=="")
      {
         textBox.css('border','1px solid red');
         return false;
      }
     
      textBox.css('border','');
      return true;    
  },

  Bind:function()
  {
     var object = this;
     //Populate values
     object.Name.val(object.Person.Name);
     object.Age.val(object.Person.Age);
     
     //Bind events
     object.Name.change(function(e){
        if (!object.validateRequired(object.Name)) return;
        object.Person.Name = object.Name.val();
     });
     
     object.Age.change(function(e){
        if (!object.validateRequired(object.Age)) return;
        object.Person.Age= object.Age.val();
     });

     
  }
}


The previous code piece needs some explanations. First for everything UI related I use JQuery, so all examples here that touch the DOM will make use of its innate capabilities.
The constructor of the PersonUIModel object gets two values an JQuery object named Element which corresponds to the actual HTML rendered with the page and attached to the PersonUIModel for controlling. The second argument is the actual Person entity binded to the HTML through the PersonUIModel object.
For ease of use I've extracted the two actual controls I'll need in separate fields of the PersonUIModel object.
The Bind method is used to start the actual two-way databinding between the Person entity and the HTML associated with the PersonUIModel object. Nothing fancy here except for two things.
Just on the start of the Bind method the this indentifier is associated with the object variable. This is done because of the change handlers latter in the code the context of their anonymous methods relies on the PersonUIModel object. If I would make a call like this in the Age.change event handler :

this.Age.change(function(e){
        if (!this.validateRequired(this.Age)) return;
        this.Person.Age= this.Age.val();
     });
I would receive a nice, fat, juicy error indicating the the validateRequired function doesn't exits on the DOMElement. The 'this' inside the event handler actually points to the textbox associated with the Person.Age property (not the JQuery object but the actual DOMElement). But with the power of closures I magically convert my PersonUIModel 'this' to object (or any other variable name) and everything is fine).
The PersonUIModel objects binds to a html code like this:


<div class='person'>
Name: <input class='person-name' type='text' />
Age: <input class='person-age' type='text' /></div>


Now we are left with the question who creates the PersonUIModel instance and binds it to a Person instance and the related HTML code. This is the role of the PeopleUIControler a specific class that coordinates the lifecycle of PersonUIModels.
The PeopleUIControler has the following roles:
  • Finding or creating the appropriate DOMElements on the Screen.
  • Loading and Saving Person models.
  • Binding Person models to DOMElements through PersonUIModel instances.
This means the the Person model is totally decoupled from the UI in which it is located. The PersonUIModel knows only of its little piece of HTML code and its Person model and nothing else. This means that the PersonUIModel doesn't know about other PersonUIModel's on the screen nor does it have any impact on the HTML outside its little realm.

The PeopleUIControler will look like this:

function PeopleUIControler()
{
      this.People = [];
      this.PeopleUI = [];
}

PeopleUIControler.prototype = {
  btnSave: null,
  btnLoad: null,
  pnlPeople: null,
  Load:function(){
      //Ajax loading ... loads a bunch of Person entities
      this.People = bunchOfPersonEntitesLoadedThroughAjax;
  },

  Save: function(){
     for(var i=0;i < this.People.length;i++)
     {
         var person = this.People[i];
         //Save the person through AJAX
         //....
     }
  },
  Bind:function(){
     var object = this;

     this.pnlPeople=$('.panel-people');

     this.btnSave=$('.person-save');
     this.btnSave.click(function(e){
        object.Save();
     });

     this.btnLoad=$('.person-load');
     this.btnLoad.click(function(e){
        object.Load();
     });

    //Load entities synchronously (just for the sake of the argument)
    this.Load();

    var html="<div class='person'>
Name: <input class='person-name' type='text' />
Age: <input class='person-age' type='text' /></div>";

    for(var i=0;i < this.People.length;++){
      var personUI = new PersonUI($(html), this.People[i]);
      personUI.Bind();
      this.PeopleUI.push(personUI);

      this.pnlPeople.append(personUI.Element);
    }
  }
}

The code for the PeopleUIControler is similar to that of the PersonUIModel. The controled has two methods Load and Save for loading and saving Person entities to a permanent source and a Bind method which binds all elements. The PeopleUIControler ties it self to an html structure that sports a panel for PersonUIModels and two buttons one for loading and saving. When first loading PersonUIModels each model is binded to a generated piece of html and then the same html is appended to the PeopleUIControler panel. The final html code used by the PeopleUIControler would look like this:
<div class='panel-people'></div>
<div>
<button class='person-save'>Save</button>
<button>load<="" <="" button>="" class="person-load" div>=""></button>

24 October 2010

Went to Zagreb and maybe lived to tell the tale

I went to Zagreb today with my colleague Hrvoje Hudoletnjak to the monthly WebUG meeting. There were two topics:
  • Lightswitch by Gjuro Kladarić, FFZG
  • Hybrid Mobile Applications by Matija Šmalcelj, Pet minuta
I was really excited to go there. It was an opportunity to learn and to network with some like minded people over the mountain (Istra where I live is separated from the rest of Croatia by a mountain named Učka). 
What I was looking for is more Lightswitch education. I just started some Silverlight development my self and the idea of Lightswitch intrigued me. There are a lot of applications being developed in pure code today which could just easily be developed by a Lightswitch-like tool.

In my opinion developers tend to be to high horse about development practices and techniques. The majority thinks if something wasn't developed in pure code, using the hottest techniques and frameworks its something to keep quiet at leat or at worst to be ashamed of.

Latter experience taught me some lessons. For the majority of LOB applications nobody really cares how we do it except us. Now, I'm of the opinion that we should care how we do what we do. But I also think that we can do a good job by not being such asses about the way we do things regularly. For somethings there is no need for unit tests, for somethings database design is just enough. Not to mention that not everything needs to be a three layer architecture and that some forms with code behind and a data store are the proper solution for some LOB applications.

The Lightswitch presentation was purposefully short.  It reminded me about Microsoft Access and my faith in the tool just sunk. It seems it wasn't really what I hoped it would be. The presenter repeatedly pointed out that this tools isn't for the regular developer but for fairly advanced administration personel. Ok. I can achieve more with Drupal, CCK and Views.

The second presentation, about Hybrid Mobile Applications was really interesting. The presenter works in a company specialized in social networks and mobile applications and he illustrated the business case for developing Hybrid Mobile Applications, e.g. web applications written for webKit and run inside a native wrapper in order to give an illusion of a native iPhone or Android app.

Whats the deal here? If you want to write a cross platform mobile app you need to write a separate implementation for each platform. One in objective-c for iPhone, one in Java for Android and so on. With Hybrid Mobile applications you just write (or take an open source one) native wrapper e.g. an application that internatlly starts the browser as a control and that resizes its self that all browser specific features are hidden from the screen thus leaving the page content. The real application is written using webkits HTML5 capabilities CSS3 animations, Javascript local storage, geolocation etc.

The application runs inside a single html page and the entire source code is shipped as single build with the wrapper thus by just changing the wrapper one can ship the same code on any native mobile application. The best thing is that the user doesn't know he is using a web application.

The most important thing  is to develop the application with no connectivity in mind, which is really easy by the existence of the local storage api that gives to the developer a full fledged relational database to use.

The development is really cheap also. The developer needs a webkit browser (Google Chrome or Safari) an IDE (Eclipse comes to mind) and a couple of mobile frameworks to ease the development effort.

 Here are a couple of links given by the presenter:
The presentation gave me a couple of ideas about some project I might do:
  • A mobile Mantis Bug Tracker interface
  • Hmm thats all just one ... :(
Of course I still have some learning to do about WPF 4  and MongoDb. I will wait till I learn those with other activities.