Archive for the ‘web html css’ Category

The Sound of Javascript: How to solve a problem with Maria …

Tuesday, May 15th, 2012

maria

Overview

Have you noticed the growing movement to developing thick clients on the browser? These thick clients move a complexity from the server to the browser while promising enhanced experiences tailored to the client device. A common theme with this movement is the use of Javascript, the Model View Controller (MVC) pattern and sending data between client and server, typically in JSON format.

This post is about developing just enough of an MVC based client on the browser to see how and where all the parts fit together, what design considerations might need to be taken into account and how the MVC pattern is applied. What is not implemented is the mechanism for communicating between the client and the server to remove a complexity that might otherwise obscure the client code. Client to server communications will be discussed without implementing code.

I’ll walk you through the code to exemplify the approach taken and how MVC comes into play. A goal is be to keep things minimal and clear in the hope you can use one or more of the techniques and tools outlined in your own projects. This post may even help you select alternative tools and frameworks.

* * The title of this blog is a play on the musical The Sound Of Music which contains the song “Maria“.

The Code

The code discussed in this post can be found here

Goal

My goal is to develop a small yet exemplary application and the canonical Todo application fits that bill quite nicely, with its simple data model and a user interface that needs little explanation. A Todo application can also be quite useful without server side functionality so conceptually its a whole application. The Todo Applications core model is essentially a list of entries outlining what is to be done, with each entry having a flag indicating if the entry has been completed and a description of what is to be done. To make the design and the use of MVC as clear as I can I have chosen to model the client side application as separate from the Todo model it manipulates. I find this helped me keep the separation of Client side and Server side clear and provide a more obvious ‘entry point’ for see where the Client Application begins and ends.

Tip - I strongly suggest that when Client Server data exchange is implemented that the data exchanged is not a direct mapping of the AppModel, rather it is an exchange of messages to manipulate each ’sides’ model indirectly. For example, when server data is processed it becomes a series of calls on the AppController rather than a direct replacement of the AppModel. A direct replacement or manipulation of the AppModel would be a tight coupling that would lead to possible change impact issues later.

MVC - Model View Controller

The Todo Client Application is embodied in the classes AppModel, AppView and AppController (see figure x), with the file src/js/initializer.js bringing them into existence when the browsers window load event is fired. The initializer.js code is the equivelant of a Java or ‘C’ programs ‘main’ function. Each class (AppModel, AppView & AppController) implements their part in the Model View Controller (MVC) pattern. There is a lot of material out there describing the MVC pattern in depth so I wont regurgitate it here, suffice to say I’m following the pattern as described by GOF and implemented in Smalltalk examples.

In a nutshell a View listens for events to happen on a HTML Element. When an event happens like the input field has changed the View is notified (by Maria). The View then extracts or builds whatever data is needed so it can communicate the event to the Controller by calling one of its methods. The Controller takes the notification and applies whatever Business logic it embodies (via other classes - don’t contain it within the controller) and calls a method on the associated Model to inform it of the change. The Model applies the appropriate changes to the model and then notifies all the observers of the model (via Maria) that the Model has changed. A View typically observes both a HTML Element and a Model meaning it will have a method called on it when either the HTML element or Model changes. When the HTML element changes the Controller is notified, when the Model changes the View is rendered. This is the circle of MVC life.

Looking at src/js/AppController.js you will notice little more than what is required to subclass the Maria Controller class and some may feel the controller is therefore unnecessary. Resist the urge to remove a Controller that is as simple as this because doing so removes a clear indication of where certain functionality belongs and tempts the lazy or uninformed developer to directly bind aspects of the Model to the View and that isn’t MVC. Not following MVC quickly couples and bridles the parts of an application with responsibilities that don’t belong, starting you on a road to despair.

Maria

To implement MVC I wanted to use a library that would implement MVC effectively yet not dictate an approach with lots of methods or classes that must be implemented, nor require a large library of dependent Javascript to be loaded. The Maria library developed by Peter Michaux and available here is such a library. Maria is thin and un-opinionated* making working with it simple and quick. At the time of writing this Maria is not well documented but I was lucky enough to have the support from Peter for my experiment. Maria is so straight forward that I rarely called on Peter to explain the library, instead we mostly discussed design issues like the progressive enhancement of existing HTML or the dynamic rendering of HTML by View objects, both of which Maria supports. Even if you don’t use Maria I suggest you have a look at the code behind it as an example of good Javascript.

* Maybe Maria is opinionated and I just happen to agree with the opinion.

Design Considerations

I chose to use a kind of progressive enhancement approach in the Todo Application, where the AppView attaches sub-views to HTML elements already present on the page when the AppView is created. This supported my working style where I created the HTML separately to writing and running my Javascript. With most applications there will come a time when a view cannot attach to an existing HTML element and will have to create elements at runtime. Consider this when making the choice of which style you want to use. Doing both helps make my Todo Application an example of both approaches.

Another design decision I made was to ensure dependencies are passed to a class instance when they’re are created. For me this helped make the dependencies more explicit and facilitated easier testing. However Javascript is such a flexible beast that inverting dependencies for testing isn’t strictly required as you can get at the innards of an object quite easily. I’d say that I probably inverted the dependencies more out of a personal style or ethic of not referring to global variables and not instantiating what could be passed in. Note that Maria follows the Smalltalk MVC implementation closely and will create a Controller for a view on demand (see maria getDefaultControllerConstructor) but I didn’t use this approach, and to Maria’s credit this didn’t cause any problems.

A design decision I have touched on already is embodied in AppModel, a Class that represents the data of the Client Application as a whole. The AppModel contains a reference to the set of Todos that are being manipulated. This set of Todos could be seen as the core model but a higher level abstraction helps here as the Model in MVC is typically manipulated through an assortment of views and sub-views created on the same Model. When this model is not the ‘parent’ you eventually end up with a Controller needing to track a parent and a child model, or a model that keeps a parent relationship unnecessarily. Typically the top level model will expose the behavior that manipulates sub-models making it ideal as a parent and ‘documenting’ the behavior of the Application, ie: addTodo().

The Application

My Todo Application is minimal in that it only captures items to be done and doesn’t currently allow you to mark an item as done. This is enough to illustrate the points I wanted to make in code and to use the Maria framework in a ‘real’ way.  The code for the Todo application is available in here (link) and what follows is a walk through of the code from the entry point through each class as it participates in the MVC pattern to enable the collection of Todos. It is hoped that following the code from the entry point down with a description of each line is the most appropriate way of describing what is going on and how the parts of the application come to interact with each other.

maria-files

Running The Application

To run the Todo Application you need to make the todo-maria.js file by issuing the “make” command in the root folder. This results in a todo-maria.js file being created in a ‘build’ sub-folder. When this is done you can open the index.html file with your browser and you should see the Todo Application. Should you run into problems please check the README file in the distribution.

src/js/initializer.js

maria-initializer

This file is packaged into the todo-maria.js file by the ‘Makefile’ where the initializer code is run as the full todo-maria.js is interpreted. The code in this initializer
creates the root triad of AppModel, AppView and AppController with their dependencies when the browser window has loaded. Since the AppView requires an existing HTML document there is no need to create the view before the document is ready. The initializer fragment of code uses the Maria event listener API to register our function to be called when the window loads. The initializer tests if the global ‘window’ object is defined before continuing because in my test scenarios the ‘window’ object is not present. There is probably a nicer approach than this but I have not looked into it.

src/js/AppView.js

maria-appview

The AppView is the main view of the application but it doesn’t attach itself to any HTML element, instead it binds other views to HTML elements using the DocumentToViewBinder class. The AppView requests the DocumentToViewBinder to bind the HTML elements ‘entry’ and ‘list’ to the associated View and Controllers, with each sharing the same AppModel. You can think of the AppView as an Abstract View. You should note that the AppView is an observer of the AppModel and when the AppModel is changed the update() method is called on the AppView. This update() method doesn’t perform any action as the sub-views themselves perform these actions as they are also observers of the AppModel.

src/js/AppModel.js

maria-appmodel

The AppModel class represents the data model for the whole application and is composed of a set to contain the Todo’s. The ‘Set’ class is provided by Maria and it has some neat Collection methods making working with a collection more natural than when working with an array. When additional data is required for the application it would be added to the AppModel. When a Controller needs to manipulate data it calls a method on the AppModel to ask it to do the work. At the time of writing this the AppModel exposes the Todo set with a method and this is wrong, wrong, wrong. The AppModel should instead allow a function to be applied to each element of the Todo Set, keeping the implementation private and using the Tell Don’t Ask principle. I’ll be changing this as a priority.

src/js/AppController.js

maria-appcontroller

The AppController coordinates requests from the View to update the model. Looking at the code right now you can see that the AppController does nothing more than subclass the Maria Controller and remember the associated Model. Not all the controllers in the Todo Application are this trivial but resist the urge to remove the ones that are. Controllers that do nothing provide two things, a place to add functionality when needed and a clear indication that the associated View doesn’t make requests to modify the associated model. A Controller is the ideal place to expose the behaviour needed to update the model, typically taking the notification from the View and then packaging that up in a new object before calling a method on the model. This flow is shown in the InputController which I’ll detail below.

src/js/DocumentToViewBinder.js

The DocumentToViewBinder is a Factory for finding a HTML element from the DOM and creating an associated View and Controller. It is the element map passed to the DocumentToViewBinder that defines which Views are bound to which HTML elements, and these views will typically register to be notified when certain events are fired by the elements they are bound to. See InputView as an example of this. Technically the DocumentToViewBinder should be constructed with another class that handles the finding of the HTML element to be bind, as mixing this responsibility into the DocumentToViewBinder class violates the Single Responsibility Principle. I’ll add this as a TODO for me.

src/js/namespace.js

The namespace.js file ensures that a todo object exists into which all the todo application components can be bound. Using a namespace reduces the probability that class names and function names will collide with already defined classes and functions.

src/js/InputView.js

maria-inputview

The InputView class listens for events on the associated HTML text input field, and for notifications of the AppModel being updated. Maria will call the ‘initialize’ method on a View to give it the opportunity to register for the events on the HTML element that is it interested in. In this case the InputView is interested in the ‘change’ event on the HTML element and when that event occurs it wants the ‘inputChanged’ method called on the InputView. When the ‘inputChanged’ method is called the View extracts the contents of the HTML text input field and tells the associated InputController that the view changed passing the input text along. The InputView also provides an ‘update’ method which is called (by Maria) when the AppModel has been updated. In this case the InputView does nothing with this notification and I could remove this method as Maria provides a no-operation implementation, however I left it defined as an explicit extension point for people less familiar with Maria or myself at a future date.

src/js/InputController.js

maria-inputcontroller

The InputController provides a method to be called when input has been given via the InputView. When input is received it is packaged up into a simple object and the method for adding todo entries is called on the AppModel. The View is also asked to clear its input ready for the next input.

src/js/ListView.js

maria-listview

The ListView class is slightly different to the InputView in that it doesn’t listen for event on any HTML elements, instead it listens only for notifications that the
AppModel has changed. When the AppModel has changed the ListView clears the associated HTML unordered list and adds each of the items in the Todo set as items in the unordered list.

Testing

I used the BusterJS framework for testing for two main reasons, firstly it provides behavior style testing that I am used to from my use of Ruby and RSpec, and secondly because it was being used by Maria for it’s testing. I found BusterJS to be fast and effective and its ability to automatically test on different browsers is very attractive.

At times I found that my tests would fail but running them two more times and they would pass. I have not looked into this and would not use BusterJS in a Continuous Integration environment until I could find out why this is happening.

You should note that some of the tests are not up to my usual standard as they don’t check all arguments passed to methods when they check a method call. This means it is possible to forget a parameter and tests continue to pass. I let the tests get this way as I was new to BusterJS and the underlying SinonJS library. I’ll be tightening up the tests.

Conclusions

Writing my Todo Application as a browser based client was a worth while experience and it helped me get a grasp on what it means to develop this style of application. Some important things I learned were:

  1. Follow MVC and always have a Controller even if it does nothing. Don’t communicate directly from View to Model, or Model to View. The MVC circle of life is all about being called back in response to events on objects being observed.
  2. Create a top level Model composed of other models to conceptualize the Client as a whole. I went so far as to have a top level Controller and View which helped.
  3. Use Maria or another MVC framework that is light and unobtrusive. I recommend you start with Maria even if you plan on moving onto more opinionated frameworks as it will provide a grounded understanding of MVC principles.

Your feedback is welcomed.

A Fully Personal Interface …

Monday, May 5th, 2008

rocks

So what interfaces do users really want and what do they really like ?

Over at Fully Personal Interface they are finding out with a verify interesting survey on different aspects of ‘interface’ and you can see a report on them. Please take a moment to take the survey.

When I visited the site I was survey participant 2010.

Also check out this good eZine on making your life easier and your interfaces, called Smashing Magazine.

a holiday on facebook and recomfriend …

Tuesday, November 20th, 2007

I’m on holidays from Aegeon for a week and so I thought I would do what I like to do when I am relaxing, and that is to write some code.

I created a little facebook application called recomfriend, which will show recommendations from friends and enable you to share recommendations with them. For example, if you saw a movie, or you went to a restaurant, and you think a friend would like them, then maybe you can write a recommendation so your friends can make more informed choices. You can also ask for a recommendation for an activity, but your friends need to opt into this, so you can’t spam them.

It’s early days for the app, and if you want a particular feature then email me on facebook.

These are a couple of tutorials I followed to get started:

http://services.tucows.com/developers/2007/07/25/getting-started-with-facebook-application-development/

http://www.liverail.net/articles/2007/6/29/tutorial-on-developing-a-facebook-platform-application-with-ruby-on-rails

http://developers.facebook.com/step_by_step.php

jaw-dropping javascript …

Sunday, August 12th, 2007

I was looking around the net for some examples of how to represent related data in a three dimensional way on a HTML page using just Javascript and came across this site http://www.dhteumeuleu.com.

The creative interface explorations along with clean simple code make Gerard Ferrandez  javascript legend in my book.

Please take some time to have a look at the examples and how you could possibly use the interface elements in your next web project.

What is Web 2.0 ?

Sunday, July 15th, 2007

Ever wondered what Web 2.0 and Enterprise 2.0 is really all about? Then wonder no more and come along to the Web 2.0 Melbourne User Group. I hope to see you there.  The group details are here.

The first meeting will be held between 6:30pm and 8pm on Tuesday 24th
of July at the Aegeon office, Level 5 / 10 Queens Road, Melbourne.

To get things started we’ll have an introductory presentation to set
the scene for the group which will be followed by general discussion
to get feedback about what everyone would like to get out of the group.

Pizza will be provided between 6:15 and 6:30.

Hope to see you there,
Rob Monie

’super fly’ code …

Friday, June 29th, 2007

It’s not often that I see some code out there especially in a javascript library where I sit back and think ‘wow, that’s not only neat in a functional way, but also in the aesthetic’. jQuery / flyDOM is one of the occasions.

flyDOM uses various javascript shorthand declarations (like {} for maps) to provide some very flexible functions that modify the DOM. The use of this approach makes the code layout very readable.

Take a look and see if you find the code as aesthetically pleasing. It’s also a very handy library too.

More along the path …

Thursday, June 21st, 2007

I’m still keen in looking into how Lisp can be used in each tier of an application, from the very front in the browser executed on the client to the very back end executed in the database (or similar).

Here are two links to bits of the puzzle.

Hop home page

FramerD home page

I’m hoping to write up my vision in more depth in the coming weeks.

Put Web Based LISP to the test …

Tuesday, June 19th, 2007

Want to try out some LISP in a Web Page? Try Little Scheme. The accompanying article is a must read.

I also recently blogged about how LISP can remove the cognitive friction of going from one domain to another and gave an example. For a much better and possibly more relevant example see the “parenscript-tutorial“, an excerpt of which follows:

(defun tutorial1 (req ent)
  (declare (ignore req ent))
  (html
    (:html
      (:head (:title "ParenScript tutorial: 1st example"))
      (:body (:h1 "ParenScript tutorial: 1st example")
                (:p "Please click the link below." :br
                      ((:a :href "#" :onclick (js-inline
                                                    (alert "Hello World")))
                      "Hello World"))))))

So just like the SQL example given earlier, LISP is usable in every tier. What other language can do that?

Check out the ParenScript project which is very exciting.

JavaScript is LISP in a sheeps clothing …

Tuesday, June 12th, 2007

Chances are your already using LISP but didn’t know it and that’s because it goes by the name JavaScript.

The following snippets of code achieve the same result, defining an anonymous function that multiplies one argument by another and returns the result.

javascript    new Function("x", "y", "return x * y");
lisp          (lambda (x y) (x * y))

The two statements are equivalent as the functionality of the two languages is the same in this respect and JavaScript can be used as a functional language but without the automated evaluation provided by LISP. It wouldn’t surprise me to find out that Ruby also has a genealogy in LISP.

Personally I prefer LISP since the syntax is simple and regular, unlike the curly-brace derivatives that have variations for this, that and the other thing.

So whats something useful I can do with a function in JavaScript ?

Consider a function that finds all the document elements of a particular type and calls your function for each document element. In this way you can build functions and objects that can be extended by others without them modifying the code.

0    :
1    function eachElement(yourFunc) {
1        var nodes = document.getElementsByTagName("*");
1        for (var i = 0; i < nodes.length; i++) {
1            yourFunc(nodes[i]);
1        }
1    }
0    :
2    eachElement(new Function("element", "alert(element.toString())");
0    :
3    var visitor = function(element) {
3        alert(element.toString());
3    }
0    :
3    eachElement(visitor);
0    :

In the example above, lines starting with a 2 and a 3 represent the building of an anonymous function and passing it as a parameter to another function. This is common place in most JavaScript libraries in use today. However, the building of a function inline is rare (lines starting with 2).

The real power of JavaScript starts to show when you bind a function like eachElement() directly onto another object enabling you to use it like it was part of the original object. This sort of power makes me wonder why JavaScript isn’t used more on the server side in place of other less dynamic and less powerful languages.

Maybe a JavaScript that is used across tiers is around the corner?

Bout #2: Boxing with CSS …

Tuesday, February 27th, 2007

I continued with my box styles and removed each of the background elements and replaced them with colors so I could see which elements were where and how they overlapped thinking this could really help me place the backgrounds and it did.

My goals were to have as small and simple xhtml and CSS as possible. I wanted to see what I could remove and still have what I wanted rather then introduce new elements (DIV’s etc) just to support my markup. After all I thought CSS is meant to replace the need for tables and cells so I didn’t want to just rename these to DIV.

Onward I pressed and in very short time I had all the corners in place but the lower right was still giving me trouble so I turned the background colors back on to hopefully get more info. It turns out that the bottom right wasnt appearing the way I had wanted because of the background color and so I changed it and all was good. It’s possible something else may fix the bottom right without the need to change the background color but right now I’m ok with having to do this.

Now that I am done and I look back at the box that scales horizontally and vertically upto a point* and the simplicity of the xhtml I am very happy with the results. One DIV marked with a class and the contained DL/DT and DD all do the right thing, a knockout you could say. So the round and bout goes to CSS.

* The Bulletproof Web Design book suggests that the ’sliding doors’ technique that I have used is bulletproof because it scales horizontally and vertically which isn’t entirely true since increasing the font size will eventually reveal the extent of the graphics underneath. However a solution that allows a limitless scroll would require adding elements (DIV’s) to the xhtml to support the style which I didn’t want to do as it seems like a backward step.

The final working files