<

Bootstrap sequence for portable web applications

Published on
10,571 Points
4,271 Views
3 Endorsements
Last Modified:
Having worked on larger scale sites, we found out that you are bound to look at more scalable solutions to integrating widgets, code snippets or complete applications and mesh them into functional sites, in any given composition.

To share some of our best practices, possibly the most important thing we changed is to eliminate all body onloads and instead rely on a different loading design, which is extremely friendly when your application is to be included by many webpages.

Because it scales both in case of server-side rendering as well as cases of lazy loading content, we are pleased to share a simplified version of the approach as a best practices with Experts Exchange.

So lets start with some code and take, for example, a simple AJAX driven search application.

<html>
  <head>
    <script type="text/javascript" src="jquery-1.6.2.min.js"></script>
  </head>
  <body>
    <div class="my-search-app">
       <form action="/search">
         <input type="text" name="q" /><input type="submit" value="search" />
       </form>
       <div class="my-search-results"></div>
       <script type="text/javascript" src="my-search-app.js"></script>
     </div>
  </body>
</html>

Open in new window


In any other, non-portable, application the most sensible JQuery logic to add in my-search-app.js would be:

// Closure
(function(window, document, $) {

  $(document).ready(function() {
     // Capture search form submit and transfor into AJAX request
     $('form').submit(function() {
       // AJAX Logic and stuff
       fnResults = function(data) {
          $('.my-search-results').html('Results ... ');
       }
     });
  });

// End of closure
})(window, document, jQuery);

Open in new window


This portable approach is more complex but we'll explain later on.

(function(window, document, $) {

  // Generic bootstrap function for each
  // instance of my-search-app
  function init(node) {
     
     // Prevent duplicated execution of
     // the bootstrapping logic
     if (node.isInitialized) {
        return;
     }
     node.isInitialized = true;

     // Store reference to the JQuery wrapped node.
     var $node = $(node);

     // Capture search form submit and transfor into AJAX request
     $node.find('form').submit(function() {
       // AJAX Logic and stuff
       fnResults = function(data) {
          $node.find('.my-search-results').html('Results ... ');
       }
     });
  }

  // When this code executes, trigger the
  // bootstrapping if all instances
  $(document).ready(function() {
     $('.my-search-app').each(init);
  });

})(window, document, jQuery);

Open in new window


The most important change one notices is that we use the classname of the outer div element to look up the functional scope of the search application and in further code only execute changes within the scope of that application root node. This is the core principle of portable applications and sometimes called the Isolation Ground Rule: Don't change things outside your application scope, even though javascript and browsers allow you to do so.

So nothing exiting just jet, so let's continue. From this point onwards I can include the code anywhere in other pages and it will work as expected, even when we include it multiple times:

<body>
   <div id="my-header-wrapper">
      <div id="my-search-box">
         <div class="my-search-app">
            <form action="/search">
               <input type="text" name="q" /><input type="submit" value="search" />
            </form>
            <div class="my-search-results"></div>
         </div>
       </div>
   </div>

  <div id="my-full-page-search">
    <div class="my-search-app">
      <form action="/search">
        <input type="text" name="q" /><input type="submit" value="search" />
      </form>
      <div class="my-search-results"></div>
    </div>
  </div>

  <script type="text/javascript" src="my-search-app.js"></script>
</body>

Open in new window


The power of this loading sequence however is shown when you start lazy loading the applications:

<body>
  <div id="my-search-form"></div>

  .. more html ..

  <script type="text/javascript">
  // Lazy load the search box application
  $(document).ready(function() {
     $('#my-search-form').load('my-search-box.html');
  });
  </script>
</body>

Open in new window


When you scale this up to the size of enterprise applications the design pattern holds and some additional patterns are added:

<body>
  <div class="my-lazy-app" data-src="my-search-box.html"></div>
  <div class="my-lazy-app" data-src="login-app.html"></div>
  <div class="my-lazy-app" data-src="contextual-navigation.html"></div>
  <div class="my-lazy-app" data-src="user-profile.html"></div>
  <div class="my-lazy-app" data-src="social-buttons.html"></div>
  <script type="text/javascript">
   $(document).ready(function() {
     // Load all applications based on their 
     // declarative application src.
     $('.my-lazy-app').each(function() {
        $(this).load($(this).data('src'));
     });
   });
  </script>
</body>

Open in new window


If you add to the mix that some of the applications, themselves include sub-applications, you can see the increasing benefit to software reuse that is delivered by this design.

In reality the code is far more complex, including cancellable loading events, plugin points and in general a more complete application lifecycle. But as a best practice this is the minimum baseline we used for our increasing number of applications. As indication that this approach works in reality, let's add that in the latest project we currently number 36 applications that have different compositions running throughout the clients legacy site; it's new internet site; it's intranet site; and ramping up to social networks such as Facebook apps.
3
Comment
Author:Roonaan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 
LVL 49

Author Comment

by:Roonaan
Thanks, I can see the total, but was wondering if there was a breakdown somewhere.
0

Featured Post

Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

Join & Write a Comment

The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month