This article describes the process of creating simple password keeper app, step by step, from scratch. App itself is located in System DB, its name is PassKeeper.
To make an app we must start from very short formulas, describing what app must do and who are users, and guesses about main scenario. For password keeper these points are:
Thats enough for PassKeeper. More complex apps may take 15–20 points, if you got more lines – rewrite, it’s redundant.
UI sketch made with pencil and paper is quickest way to pre-construct user interface layout, DOM structure and main logic. I’ve tried nearly all possible sketching and UI prototyping apps, bought 4 different tablets, and finally get back to paper.
It took several minutes to draw. Often one UI sketch takes
one A4 papersheet.
Sketch must not be accurate or heavily detailed – just key elements, their layout and main user interactions. Sketch is not a dogma, final app sometimes has very little in common with sketch – but it’s best way to start.
Sketching UI with pencil and paper is far less rapid then dragging buttons around prototyping app workbench, also pencil-drawn line is harder to remove. All it forces you to think before drawing – result is better and cleaner UI.
Open manifest editor, name your app, define if your app is just app or it’s intended for doc authoring/editing/saving. Our PassKeeper is editor, it will create and recognize docs of type passkeeper.
Screenshot fragment at right represents App editor panel, that defines app properties. All these properties are accessible by app during runtime and explained in API reference.
It’s good idea to unify were your doc is located in apps data objects – editor node is clear read and self-explaining, so CloudWall demo apps use editor to mount doc. You may use any other name – system will put doc being opened to this node.
Attach icon and when all done – save doc. Don’t mind that CloudWall says manifest is invalid. Certainly it is – we just start.
‘Beta’ marks that app now is in beta state – if it is replicated, other users can not exec it.
We already decided that doc edited by our PassKeeper is mounted under editor key, and the command (like edit or create) is passed using cmd property. Now we need to define structure and defaults for doc itself.
For our toy application it’s quite easy – we have just name, cryptokey and two nested repeated sections.
In more sophisticated apps creating underlying doc structure can be much more complex. Good point is that you can extend your doc structure any time later.
Now we need to write HTML a little and create static DOM structure that later get alive. CloudWall has two built-in template engines – jQuery tmpl (well documented) and $.my.formgen (poor documented). In our simple case we need none of them.
In most of cases vanilla HTML is good enough. When overall amount of raw HTML is 100- sloc there is definitely no reason to use template engines. We have exactly this case – our code is 20 sloc.
Divs #list (line 7) and #atts (line 17) are empty – they will contain repeating nested forms, which are defined in their own manifests. Click to zoom.
Array with HTML is mounted to AppHTML property of manifest. All functions of manifest will see it as this.AppHTML – so when we init the form, we just join array and put string into form’s jQuery object, which is appslot.
We also need two more carcasses – for .item and for .user repeating sections. These repeating sections are child manifests, so we can do it later.
All CloudWall system and demo apps use mnemonic CSS rules extensively. So when you see
fs150 – they are mnemonics for
font-size:150%. Mnemonics are very useful in quick prototyping – they are short, clear and reduce amount of css code to write dramatically.
Most mnemonics are defined in cw.general.css resource in grains fine enough for real cases. Manifest-specific rules are defined in style section of manifest.
Now we can write ui section of manifest and then make first run. In fact we can make first run after just one control is bind – it’s good practice to check how newborn HTML fits sketched layout.
Final ui section is 60 sloc, it’s structure maps controls’ selectors to functions, that bind selectors with data.
The only selector that has slightly different syntax is
#list – it’s a container for nested form.
One of the most sweet features of jQuery.my is nested and repeated forms. Any jQuery.my form instance can serve as control for parent form.
In our app we use repeated forms – URL sections and Users.
#list selector has property manifest with value "Url". It is a reference pointing to child manifest – see source code. Manifests also can be inlined.
This app use external system component that manages file attaches. This component is buit-in system manifest
cw.Sys.Attachments. It receives source doc as param and manage only its
_attachments property where files are stored.
To save doc we just send event commit to parent form. To close app – event cancel. Both events bubble, so they can be trigger anywhere inside app.
When system closes app, it checks if doc was changed since last save and asks to save doc, to discard changes or to abort app termination. This check is system-driven, app does not need to worry about it.
Ok, now we can test everything, tune UI, tune behavior and so on. There is special paragraph in API reference about debugging. Final result vs sketch:
|Total time||3¾ hours|
|20 minutes||App HTML|
|20 minutes||Nested HTMLs|
|20 minutes||Layout tuneup|
Now Beta marks can be removed and app ready to release. To deploy app it’s enough to copy it into shared DB.
Final manifest is 4Kb / 200 sloc long. It has 63 revisions – it means I saved it every 2-3 minutes, opened, then fixed issues, then saved again. 63 times.
More or less working alpha appeared in 1½ hours – in next 2 hours it came from ugly buggy mock into app.