Building Enterprise HTML5 Application

Step 1) The First View

The first step is to implement the skeleton of the application, meaning setting up the code structure, main components, basic layout, and the minimal dataset sample, and the core views.

The result of this first step will look like this:

Tutorial 01 - Source | Demo

Code Structure

Here is the code structure of the application.

  • bootstrap/: Twitter/Boostrap is a very well thoughtout HTML/CSS boostrap libraries which is very complementary to brite. We use it in most of our projects. The best practice is to put in its own folder, so that it is easy to update it overtime (without having pick and replace in the common /css and /js folders)
  • css/: Here are the common css files for the application. By convention CSS files starting with UpperCase are View css files (as any other view file assets), and other are generic css ones. Here we can main.css as the generic css file for this application that will be included after the boostrap css (see the index.html), and the first view's css file MainView.css.
  • js/: Here are the common javascript files for the application and the View javascript files with the same convention as the css ones. jquery is brite only dependency, and we also use Handlerbars.js as templating engine, as it is a well known, performant, extensible, and string based templating engine (but brite.js does not didacte any particular templating engine, and developers can even choose binding aware templating engine).
  • tmpl/: Here are the View template files. They are regular HTML templates wrapped in a <script name="tmpl-ViewName" type="text/html"> tag and obviously need to be of the syntax of the templating engine used (in this case Handlebars.js syntax).
  • index.html: And finally, the index.html file that will start everything and call the first View with brite.display("MainView",...)

As shown above, the convention is that all view's asset files (.css, .js, .tmpl) start with UpperCase. This makes it easier to distinguish view files from other files, and also match the "Object Type" nature of those assets.

Index.html

In brite, applications are mostly single page based, and consequenlty the index.html is just about including the appropriate css and javascript libraries. In this step, it will include, jQuery, brite, bootstrap, and the main.js and main.css which will be the top css and javascript file for the applications. (see the tutorial-01 index.html for full code).

index.html

<html>
  <head>
    ...
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" />
    <link rel="stylesheet" href="bootstrap/css/bootstrap-responsive.min.css" />


    <!-- application css for generic css directive -->
    <link rel="stylesheet" href="css/main.css" />
    
    <script type="text/javascript" src="js/jquery.min.js" ></script>

    <script type="text/javascript" src="../../../others/handlebars-1.0.rc.1.js" ></script>

    <script type="text/javascript" src="js/brite.js" ></script>
    
    <script type="text/javascript" src="js/main.js" ></script>

And, the HTML body content code is extremely simple, and just contains the following couple of tags:

index.html

....
  <body>
    <!-- Best-Practice: Here with use a "pageBody" element to get more flexibility on how we want to display 
                        the application. This pageBody will be position in the main.css. -->
    <div id="pageBody">
    </div>
  </body>
</html>  

And finally, we just display the main view MainView inside the top div #pageBody with the following code.

main.js

Next, we will create the main.js which will have all the necessary logic to intialize and start the application. By convention, we do not put script tags in the HTML files anymore, but rather put them in their own files, as this make the application code more structure and flexible, as well as making it Chrome App ready (Chrome App does not support script tags in html pages).

The first thing we will do is tell brite to load the view .tmpl and .css on demand (as they are first needed) by setting the brite.viewDefaultConfig properties as follow.

main.js

// Tell brite.js to load the /tmpl/ViewName.tmpl and /css/ViewName.css on demand
// (very useful for development, and even on production for some cases)
brite.viewDefaultConfig.loadTmpl = true;
brite.viewDefaultConfig.loadCss = true;

This is extremely convenient for developement, especially for large project, as there is no central registry places that keeps conflicting when merging branches. The default of these properties are false, which is usually used in production environment.

brite.js also allow to set this properties at a view level, see the brite.registerView API for more information.

Then, when the document is ready, we just need to call brite.display to display the MainView which will in turn display the sub views.

// When the document is ready, we display the MainView  
$(document).ready(function(){
  brite.display("MainView","#pageBody");
});

Additionaly, we will implement an extremely simple wrapper for handlebars which is highly recommended as it will become very handy later if the application have to support pre-compiled templates or even another templating engine. Also, note that this render(...) will be called from the views create methods and that since we set the .loadTmpl=true the HTML content will be in the DOM and ready to be compiled.

// Just a little indirection to render a template using handlebars.
// This simple indirection allows much flexibility later one, 
// when using pre-compiling or other templating engine are needed.
Handlebars.templates = Handlebars.templates || {};  
function render(templateName,data){
  var tmpl = Handlebars.templates[templateName];
  if (!tmpl){
    tmpl = Handlebars.compile($("#" + templateName).html());
    Handlebars.templates[templateName] = tmpl;
  }
  return tmpl(data);
}

Note As a general practice, application developers should never hesitate twice to write simple framework or library wrappers. While framework people might not recommend it, we actually think it is a very efficient way to build more flexibile application code.

MainView

To define the MainView a brite.regiterView("MainView"... in the index.html head tag would suffice, but for this application we want to take advantage of Brite View assets componentization, and therefore, we will create the three typical following view files.

The first file is the JavaScript file that will define the View, and by convention should be at /js/[ViewName].js and will look like this.

js/MainView.js

brite.registerView("MainView",{emptyParent:true},{
  
  create: function(){
    // since this first view is static, no need to call js render, just a .html() on the template.
    return render("tmpl-MainView");
  }
    
});

The create method just get the HTML template element with the id format as tmpl-[ViewName] and return the content of it.

By convention, the MainView HTML template will be located in the /tmpl/[MainView].tmpl and will start with a first element with a css class name of class="[ViewName]" such as

tmpl/MainView.tmpl

<dscript id="tmpl-MainView" type="text/html">
  <div class="MainView">
    
    <div class="MainView-topNav">
      <h2>Task Manager</h2>
    </div>
    
    <div class="MainView-left">
      
    </div>
    
    <div class="MainView-content">
      
    </div>
  </div>
</script>  

And finally, the optional but often recommended view css file would be located at /css/[MainView].css and will prefix its css rules with ".MainView-___" or "MainView .___" as:

css/MainView.css

.MainView{
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  border: dashed 1px red; /* for layout debug */
}

.MainView-topNav{
  height: 36px;
}

.MainView-topNav h2{
  font-size: 20px; 
  line-height: normal;
  letter-spacing: .1em;
  margin: 0;
  padding: 5px 0 0px 10px; 
  
}

.MainView-left{
  position: absolute;
  top: 36px; bottom: 0; left: 0;
  width: 200px;
  border: dashed 1px blue; /* for layout debug */
}

.MainView-content{
  position: absolute;
  top: 36px; right: 0px; bottom: 0; left: 200px;
  border: dotted 1px #ddd;
}

.MainView-projectViewPanel{
  position: absolute;
  top: 20px; right: 20px; bottom: 20px; left: 20px;
  border-radius: 10px 10px 10px 10px;
  border: dashed 1px green; /* for layout debug */
}

By convention all View top template id are with the the format id='tmpl-[ViewName]', and the top HTML element as for css class name class="[ViewName]". If a view as sub templates, then, the id format look like id='tmpl-[ViewName]-[subTemplateName]'. Also the other convention is that main sub-elements css class name can be prefixed with '[ViewName]-' to allow simple selectors in the component css (but this convention is pretty flexible).

Step 0 - The Application Step 2 - The Sub Views

Ask, learn, share about brite.js

Go to brite.js G+ community