-
Notifications
You must be signed in to change notification settings - Fork 2
Web UI
The user interface of Webelexis. First a short introduction.
Browser based software is normally written in JavaScript. People who don't like the somewhat easygoing style of this script language, tend to use some form of preprocessor, like CoffeeScript or TypeScript. Or even huge frameworks like Google's GWT. But in the end, it's always JavaScript going to the browser. So, in my opinion, you better learn JavaScript to understand, what's going on.
You can write JavaScript code in a simple editor, and you can try it in almost any browser. Even more: Most browsers offer a debugger for your JavaScript code right at your fingertips: Just hit F12 in Firefox or Chrome. (well, this won't work on Mac. There you hit Alt-Cmd-I, or go to the Menu and select: Developer Tools).
Unfortunately, there are some drawbacks with this approach. The biggest one is: You will end up with a single file of several thousand lines of code for a nontrivial program, and an awfully crowded global namespace. I bet: after a short while, you won't understand your own code anymore.
Obviously, there's a need to modularize code and to separate namespaces. And there is even a standard for this: AMD (No, not the Company, but the "Asynchronous Module Definition"). The term 'asynchronous' means: The browser doesn't have to load the whole code at once, but can fetch code modules later, when they are needed. There are several tools to handle AMD compliant JavaScript Modules. I chose RequireJS.
Another need is a fast, responsive UI. The user doesn't want to wait for page reloads as in the good old Web 1.0 times. Therefore we can not ask the server to send a whole new neatly prepared HTML-Document for every user action. Instead, we only ask the server to send the data we are actually interested in, and let the client do the work to present them nicely. This technique is frequently referred to as "AJAX" (Asynchronous JavaScript And XML. Today, it's not necessarily XML, though.)
But how display new data in an existing HTML document in the user's browser without reloading? The way to go is direct manipulation of the browser's internal representation of the HTML. The so called DOM (Document Object Model). Doing this is not very fun. There are so many elements and markups in a single HTML page and its resulting DOM. You don't really want to manipulate this manually.
The trick is, to identify in the HTML source the places, where interesting data should show up and let a framework do the boring job to change contents according to user actions. Such a framework is KnockoutJS It is not the only one. But it's the one I chose. With KnockoutJS you produce your data in JavaScript (the "Model"), including server calls to get them, and bind them to previously declared HTML elements (the "View"). KnockoutJS listens for changes of the model and mirrors them to the view, and vice versa, if the user changes something on the view, it reflects this back into the model.
If the user clicks on the "back" button of the browser, they expect to return to a previous state. And if the user bookmarks a page, they expect to get exactly to this place, when calling the bookmark at a later time, Achieving this behaviour programmatically, is a bit tricky, since the browser's back button simply goes back to the previous stored URL. Therefore, a first step is, to connect URLs to program states. A commonly used technique is 'hashtag routing': The Meaning of http://www.website.com#someState is not to go to a subdirectory of the site, but to launch the application on that site in a defined state. There are some libraries to help with such routing (e.g. Sammy.js or CrossroadsJS). Of course, it's also possible to hand-wire such a routing system, similar to the concept described by lshift.
It is difficult to create a layout which is equally useful for small and big screen sizes. In fact, it is quite impossible. Some designers create several layouts for several devices. Others use toolkits that provide some help with this task. Both approaches have their advantages and disadvantages. The latter needs less manpower but never matches completely to every screen. I decided to follow this path, because I'm not a talented designer. A great CSS library is bootstrap. The designer creates 'mobile first', i.e. match smaller screen sizes, and the library helps in making better use of more screen estate. The basic principle is, to place vertical arrangements of functional blocks horizontally on wider devices. With bootstrap, each element uses between 1/12 and 12/12 of the available width, and the designer can distribute these 12/12 differently for different screens (xs, sm, md, and lg). Besides this basic layout, bootstrap offers lots of CSS goodies and components. Last but not least it comes with a subset of the great Glyphicons set of font-icons.
Some people really like writing HTML. I don't. There are too many < and > and / around to write quickly and it is difficult to see what happens without loading the page into the browser. On the other hand, there are WYSIWYG editors for HTML where you don't see what happens under the hood and where it is difficult to make predictable layouts. And it is difficult to use a tool like bootstrap with a WYSIWYG editor.
There is a better (in my opinion) solution: Jade. Jade is a terse, concise language and a compiler to produce plain HTML from easy readable templates.
While it is perfectly possible to connect KnockoutJs, Bootstrap, RequireJs, JQuery and all the other tools manually, there is a single application framework exactly for this purpose: Durandal. So, the client part of Webelexis now (as of 1.0.0) is a Durandal App.
As you might guess, there are a lot of libraries needed to do all the things I mentioned above. Fortunately, the build system will collect all for you.
Look here for notes on installing the build tools.