Monthly Archives: September 2013

Become A CoccyxJS MVC Ninja – Mini Tutorial #2: View

coccyxjs_ninjaWelcome to the second tutorial in a series of CoccyxJS mini tutorials. In the previous tutorial we learned how easy it is to use a CoccyxJS Controller component in a Web application for declaring and handling routing requests. In this tutorial we will expand on that and add a View to our application which will render markup to the DOM. But before we get on with today’s mini tutorial please follow the instructions at “A Series jOf CoccyxJS Mini Tutorials”, if you haven’t already, for setting up a project directory structure and installing http-server which we will use throughout this series.

Views

Views are generic components which applications use to render and remove markup to and from the DOM, respectively. Applications can also use Views to declare the DOM events that Controllers respond to. In todays mini tutorial we will focus only on rendering markup, leaving DOM event handling for a future tutorial. Views, like Models and Collections, which we will also learn about in future tutorials, are manipulated by Controllers and their route handlers.

Two common use patterns exist when working with Views:

  1. passing data that is to be rendered, whole or in part, to a View’s method which, by convention, is often named “render”, and
  2. returning “this” from the rendering method, allowing for “chained” access to View properties.

tutorial02.js

In your project’s root folder, specifically its javascripts folder, create a file named tutrotial02.js. In tutorial02.js paste the following code and save the file. We’ll discuss the code in a moment but it is so much better to see it played out first:

/**
 * CoccyxJS mini tutorial 02.
 * Expands on tutorial 01.
 * Creating a View that renders makrup to the DOM.
 */

(function(v){

    'use strict';

    //Implement a route handler for 'get /'
    function showIndexPage(){
        //We'll create a View that renders markup to the page.
        //We define a method for the View named render. We
        //will pass it a message as a parameter and it will
        //wrap the message in a header tag and render it to
        //the page.
        var helloWorldView = v.views.extend({
            render: function(message){
                this.$domTarget.html('
<h2 style="color: #00f">' + message + '</h2>
');
                //Return 'this' allows for chained access to
                //View properties when rendering to the page.
                return this;
            }
        });
        //Show the message. Notice how we are taking
        //advantage of chaining!
        v.$('#container').html(helloWorldView.render('Hello World!').domTarget);
    }

    //A simple controller that declares one route.
    //The route it will handle is 'get /'.
    //The function it will call is showIndexPage.
    var controller = {
        name: '',
        routes: {
            'get /': showIndexPage
        }
    };

    //Register the controller &
    //begin handling routing requests.
    v.history.start(true, [controller]);

}(window.Coccyx));

Add tutorial02.js to index.html

Open the index.html file, which is located in the project’s root directory, and then copy and paste the following markup into the file and save the file.

<!DOCTYPE html>
<html>
<head>
    <title>CoccyxJS Mini Tutorial Series</title>
</head>
<body>
<h1>CoccyxJS Mini Tutorial Series</h1>
<d id="container"></d>
    <!-- JavaScripts -->
    <script src="javascripts/libs/jquery.js"></script>
    <!-- Shim file has to be loaded before coccyx.js is loaded!!! -->
    <script src="javascripts/libs/shim.js"></script>
    <script src="javascripts/libs/coccyx.js"></script>
    <!--  Previous mini tutorials
    <script src="javascripts/tutorial01.js"></script>
    -->
    <script src="javascripts/tutorial02.js"></script>
</body>
</html>

Start http-server

Now open your terminal and make the project folder the current directory. Once you’ve done that start the server by typing http-server at the command line and hit enter. Depending on your operating system (I am running on a Mac) you should see something similar to the following:

Terminal

Run The Application In The Browser

Now open your browser and navigate to http://localhost:8080 and you should see the following in response:

minitutorialoutput02

What Just Happened?

Lets break this down:

  • First we created a View by extending the CoccyxJS View component, passing it an object “template” that defines the View we want it to create for us. We then assigned the returned View object to the variable helloWorldView.
  • In the View template that we passed to extend we created a method called render which takes a single parameter named message. In the body of the render method we wrapped message inside an h1 tag and called this.$domTarget.html, passing it the wrapped message and returned this to allow for easy chaining. Since we didn’t “tell” the View what it should use for the domTarget the View defaulted to using a plain div element and rendered our wrapped message to that div element while it was still detached from the DOM (see the Guide for a detailed explanation of detached and attached rendering and for how the View component creates its $domTarget property from its domTarget property).
  • Next, in our route handler we actually rendered the content of $domTarget to the DOM by calling v.$(‘#container’).html(helloWorldView.render(‘Hello World!’).domTarget). Notice how we are passing the value of message to the View’s render method as well as how we are making use of chaining.

(Note: In a real application it isn’t advisable to dynamically build markup using strings like we did here and instead we would probably chose to use one of the many templating libraries that are available.)

Now wasn’t that ezpz? Give yourself another pat on the back because you are one step closer to becoming a CoccyxJS Ninja.

What’s Next

In our next mini tutorial we will learn about Models and we will expand upon tutorial02.js by passing a Model to the View’s render method. See you soon.

Advertisements

Become A CoccyxJS MVC Ninja – Mini Tutorial #1: Controller

coccyxjs_ninjaWelcome to the first in a series of CoccyxJS mini tutorials and today we are going to learn how easy it is to add routing to our Web applications using the CoccyxJS Controller component. But before we get on with today’s mini tutorial please read the instructions in my article, “A Series jOf CoccyxJS Mini Tutorials”, which has instructions for setting up a project directory structure that we will use throughout the series as well as instructions for installing http-server, which we will use to run our mini applications.

Routing Request

Controllers manage your applications’ views, models and collections. They are also responsible for handle routing request, which is what we will focus on here today. Routing request can result whenever the URL in the browser’s address bar changes by clicking the browser’s forward and back navigation buttons or when a user clicks on an anchor tag or submits a form.

When a routing requests is made the CoccyxJS router will attempt to match the request to a route handler defined by a Controller in it routes hash. If found then the router will call the route’s handler function. If not found the router will ignore it.

Since CoccyxJS implements RESTFUL routing we always have to define our routes as “verb url”: handler, where verb can be one of “get”, “post”, “put” and “delete” and the url is the actual URL associated with the route. The verb plus the url together serve to uniquely identify the resource, which in the case of routing is the route handler function that will be called.

The most important thing to know at this point though is that CoccyxJS ignores all routing request until it is explicitly told to begin handling them. For that we need to call its History component’s start method which is used to register one or more Controllers and to begin processing routing requests.

I am sure that all this must sound a lot more complicated than it really is so instead of talking about it, lets implement it and we’ll see how CoccyxJS makes all this really easy.

tutorial01.js

In your project’s root folder, specifically its javascripts folder, create a file named tutrotial01.js if it doesn’t already exist. In tutorial01.js paste the following code and save the file. We’ll discuss the code in a moment but it is so much better to see it played out first:

/**
 * CoccyxJS mini tutorial 01.
 * Creating our first Controller and route handler.
 * The route we want thato handle is 'get /' and the
 * route handler that will be called will simply
 * alert 'Hello World!'.
 */

(function(v){

    'use strict';

    //Implement a route handler for 'get /'
    function showIndexPage(){
        //Alert "Hellow World!" just so we know
        //our routing request was actually handled.
        alert('Hello World!');
    }

    //A simple controller that declares one route.
    //The route it will handle is 'get /'.
    //The function it will call is showIndexPage.
    var controller = {
        name: '',
        routes: {
            'get /': showIndexPage
        }
    };

    //Register the controller &
    //begin handling routing requests.
    v.history.start(true, [controller]);

}(window.Coccyx));

Now, if you are on a Mac open up the terminal and make the project folder the current directory. Once you’ve done that we will start our server. Type http-server and hit enter. You should see the following:

Terminal

Now open your browser and navigate to http://localhost:8080 and you should see the following in response:

running_tutorial01

What Just Happened?

Ok so lets break this down:

  • First we created a function named showIndexPage which when called simply alerts “Hello World!”.
  • Next we created a Controller and its routes hash with one route definition defined to handle a request of “get /” by calling the showIndexPage function. We also gave the Controller a name by assigning it a property called… you guessed it… name and assigned it a value of “”. Since name is an empty string the router interpreted our route definition’s URL to just “domain/”. Had we given it a real name, say “invoices” for instances, then the router would have interpreted our route definition’s URL as domain/invoices. We will cover route definitions in more detail in a later mini tutorial but for now it is important just to realize that every Controller defines the routes it wants to handle and a name.
  • Lastly we called history.start(true, [controller]) to register our Controller and to begin processing route requests. By passing true as the first argument, we are instructing the router to not only begin processing routing requests, but to also route the browser’s current address. In response, after having registered our Controller, the router found a matching route definition (which it does because our Controller defined one) and called its handler, which is the showIndexPage function that we defined which displayed an alert of “Hello World!”.

Now wasn’t that ezpz? Give yourself a pat on the back because you are well on the way to becoming a CoccyxJS Ninja.

What’s Next

In the next mini tutorial we will learn about Views and we will expand upon tutorial01.js by adding a View to the route handler function. See you soon.

Become A CoccyxJS MVC Ninja – A Series Of CoccyxJS Mini Tutorials

coccyxjs_ninjaWhen learning how to use a new library there is nothing better than “hands on” experience. So in a series of mini tutorials I will teach you how easy it is to become a master at writing Web applications using CoccyJS. Each mini tutorial will be short and to the point and will be limited in focus to one or two aspects of CoccyxJS.

But before we actually begin with the mini tutorials we will need to create a simple project structure and install http-server (a simple command line server which we will use to serve static content).

Please follow the instructions below which will explain how to create the project structure which will be used throughout the series.

Project Structure

To begin, lets create a root project folder that we will use to contain the files for the mini tutorials. You can name it anything you like.

Once you have created the root project folder create the same project structure as pictured below. Please note that you do not have to create the javascripts/tutorial01.js file now. We will create that file together in the first mini tutorial.

projectstructure

With our project structure now in place, we need to add some JavaScript files to the javascripts folder.

Core JavaScript Library Files

Download CoccyxJS and save it to a file named coccyx.js in the javascripts/libs folder.

Download jQuery and save it to a file named jquery.js in the javascripts/libs folder.

Create a new file in /javascripts/libs and name it shim.js. Then paste the code below into it and save the file.

(function(){
    'use strict';
    window.define =  function define(){
        (arguments[arguments.length - 1])();
    };
}());

index.html

Create a new file in your root project folder and name it index.html. Then paste the markup below into it and save the file.

<!DOCTYPE html>
<html>
<head>
    <title>CoccyxJS Mini Tutorial Series</title>
</head>
<body>
    <h1>CoccyxJS Mini Tutorial Series</h1>
    <d id="container"></d>
    <!-- JavaScripts -->
    <script src="javascripts/libs/jquery.js"></script>
    <!-- Shim file has to be loaded before coccyx.js is loaded!!! -->
    <script src="javascripts/libs/shim.js"></script>
    <script src="javascripts/libs/coccyx.js"></script>
    <script src="javascripts/tutorial01.js"></script>
</body>
</html>

http-server

http-server is a simple command line http server that we will use. Please visit https://npmjs.org/package/http-server and follow the instructions there for installing http-server.

Reference Materials

Please take the opportunity now to read the Guide and scan through the API Reference. They will provide context that will be very helpful as we work through each mini tutorial and you can refer back to them at any time.

With our project structure now in place and http-server installed we are ready to begin with our very first mini tutorial.

How CoccyxJS uses RequireJS to define its own dependencies but can also be used from the global name space

images-1RequireJS is a great asset when you want to write highly modularized applications, but when it comes to using RequireJS to write highly modularized JavaScript libraries that are meant to be shared with others, then there are challenges. It is a fact that for what ever reasons, not everyone is enamored with RequireJS; they just wont use your library if it means they also have to use RequireJS for their own applications. I think that it is telling that many of today’s most popular libraries do not directly use RequireJS internally to define their own dependencies and modules because they don’t want to discourage other developers from using their libraries by imposing RequireJS as a dependency.

The ultimate solution to this problem would be if there was a way to create a library that is itself built using RequireJS, which defines its own modules and dependencies using the RequireJS define method, but that can also be used in the old “global” fashion that most libraries still tend to adopt and users like. It is easy to draw a comparison to jQuery, which is both AMD compliant and capable of being used from the global name space, and say, “just do it the way jQuery does.” The problem with that is that although jQuery is AMD compliant, it actually doesn’t use RequireJS at all to define its own modules and inter module dependencies.

As you can guess, I struggled with this very issue myself while developing CoccyxJS v0.6, which will be released very soon. I wanted to use AMD modules to break up CoccyxJS into its logical components and have its components declaring their own dependencies upon other CoccyxJS components, such as define(‘views’, [‘application’, ‘helpers’], function(app, helpers){…}); for example, but I also didn’t want to discourage the adoption of my library just because I chose to implement it using RequireJS. After some thought it dawned on me that conceptually it should be possible to have my cake and eat it too, to use RequireJS in a way that would make CoccyxJS a compliant AMD module, usable by applications that are also using RequireJS, and usable by application that access it from the global name space as well.

The solution I employed is actually quite simple and I offer it up to anyone else who is considering developing a library they’d like to build using RequireJS, but who also don’t want to discourage its adoption.

First and foremost, CoccyxJS is built as one would build a library that is intended to be used from the global name space. The difference though is that it also defines its own inter dependencies between its modules using the RequireJS define method. In order to get this to work, so that it can be used both as an AMD module and from the global name space, you never use modular dependencies as arguments to define’s callback functions and you never define your modules by returning objects from those callback functions.

For example, in CoccyxJS, the views module is defined as define(‘views’, [‘application’, ‘helpers’], function(){…}). The views module declares its dependency upon both the application module and the helpers module, but it doesn’t use them as arguments in the callback function. By declaring its dependency on these 2 modules, the callback function won’t be called until they are loaded and resolved. Internally, anything that is exposed in these two modules is done so in the old fashioned global way, by tacking them onto the single global variable, Coccyx. By the time the callback function is called, everything that the views module needs from the 2 other modules has already been placed into the Coccyx name space. For example, the helpers module, in total, is shown below:

define('helpers', [], function(){
    'use strict';

    var Coccyx = window.Coccyx = window.Coccyx || {};

    Coccyx.helpers = {
        //Returns true if s1 contains s2, otherwise returns false.
        contains: function(s1, s2){
            var i, len;
            if(typeof s1 === 'string'){
                for(i = 0, len = s1.length; i < len; i++){
                    if(s1[i] === s2) {
                        return true;
                    }
                }
            }
            return false;
        },
        //Returns a deep copy object o.
        deepCopy: function(o){
            return JSON.parse(JSON.stringify(o));
        },
        //Pass one or more objects as the source objects whose properties are to be copied to the target object.
        extend: function(targetObj){
            var len = arguments.length - 1,
                property, i;
            for(i = 1; i <= len; i++){
                var src = arguments[i];
                for(property in src){
                    if(src.hasOwnProperty(property)){
                        targetObj[property] = src[property];
                    }
                }
            }
            return targetObj;
        },
        //For each matching property name, replaces target's value with source's value.
        replace: function(target, source){
            for(var prop in target){
                if(target.hasOwnProperty(prop) && source.hasOwnProperty(prop)){
                    target[prop] = source[prop];
                }
            }
            //0.6.0 Return target.
            return target;
        }
    };

});

Within the views module, when it needs to call helpers.extend(), it would do so by calling Coccyx.helpers.extend(), which is how it is defined within the helpers module.

I use Grunt to concatenate all the modules that make up the CoccyxJS library into a single file. The last file concatenated at the end, the amd.js file, looks like this:

define('coccyx', ['application', 'helpers', 'router', 'history', 'models', 'collections', 'views', 'eventer', 'ajax'], function () {
    'use strict';
    return window.Coccyx;
});

The amd.js file is ultimatley responsible for turning CoccyxJS into a compliant AMD module. It states its dependencies on all the sub modules and it returns window.Coccyx, which allows it to be used from the global name space.

Now, in order to use CoccyxJS from the global name space, you just need to add this little JavaScript shim before your script tag that loads CoccyxJS:

//A shim that mocks the RequireJS define() method so that Coccyx.js can be used without RequireJS.
//Calls the RequireJS define callback function, allowing Coccyx.js modules to "define" themselves.
//IMPORTANT - include this script before Coccyx.js.
(function(){
    'use strict';
    window.define =  function define(){
        (arguments[arguments.length - 1])();
    };
}());

And there you have it. By using this technique when creating your own libraries you will be able to satisfy developers who want to use RequireJS and those that don’t. Your library will gain all the benefits of using RequireJS to build itself from individual AMD modules and ultimately defining itself as a compliant AMD module, while also being able to be used from the global name space.

I really like RequireJS, but I don’t want to alienate potential adopters of my library who might otherwise adopt CoccyxJS for their own development efforts but for its RequireJS dependency. By using this technique, I feel like I am able to have my cake and eat it too, and able to pass that cake on to the users. “Let them eat cake,” that’s what I say 🙂

:wq