Become A CoccyxJS MVC Ninja – Mini Tutorial #5: DOM Events

coccyxjs_ninjaWelcome to the 5th tutorial in a series of CoccyxJS mini tutorials. In the previous tutorial we learned how easy it is to use the CoccyxJS Collection component. In this tutorial we will explore how to handle DOM events. 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.

DOM Events

Views register the DOM events they want to be handled by Controllers by passing a hash with controller and events properties to Coccyx.views.extend. The value of the “controller” property is used as the context when calling the event handler functions. Additional properties are defined by the events hash for each DOM event to be handled and are of the form “event selector”: handler. When a DOM event is triggered, CoccyxJS will call the handler with a jQuery event object as an argument.

tutorial05.js

In your project’s root folder, specifically its javascripts folder, create a file named tutrotial05.js. In tutorial05.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 05.
 * Expands on tutorial 04.
 * Handling DOM Events.
 */

(function(v){

    'use strict';

    //The object that we will use to create selectedDowView.
    var selectedDowViewTemplate = {
        tagName: 'h3',
        domTargetAttrs: {
            style: 'color: #f00; font-style: italic;'
        },
        render: function(dow){
            this.$domTarget.text('You clicked on ' + dow);
            return this;
        }
    };

    //Responds to click events on the days of the week.
    //We get the inner text of the target element.
    //Then we create a new selectedDowView and pass the inner text to its render method.
    //We then append the selectedDowView to the DOM.
    var dowClicked = function(event){
        //Get the inner text which happens to be the day of the week.
        var innerText = $(event.target).text();
        //Create a new selectedDowView by extending selectedDowViewTemplate.
        var selectedDowView = v.views.extend(selectedDowViewTemplate);
        //Render the day of the week to the DOM.
        v.$('#container').append(selectedDowView.render(innerText).domTarget);
    };

    //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 Collection's data which is an array of
    //days of the week objects as a parameter and it will wrap each
    //day of the week object's day property in a header tag
    //and render it to the page.
    var daysOfTheWeekView = v.views.extend({
        render: function(data){
            var self = this;
            data.forEach(function(dayOfTheWeek){
                self.$domTarget.append('<h2 style="color: #00f">' + dayOfTheWeek.day + '</h2>');
            });
            //Return 'this' allows for chained access to
            //View properties when rendering to the page.
            return this;
        }
    }, {
        //The context that will be used when calling the event handlers.
        controller: this,
        //The events we will handle.
        events: {
            //Handle click events on all the h2 elements in dowClicked.
            'click h2': dowClicked
        }
    });

    //Implement a route handler for 'get /'
    var showIndexPage = function showIndexPage(){
        //Render the data to the DOM. Notice how we are taking
        //advantage of chaining!
        v.$('#container').html(daysOfTheWeekView.render(this.collection.getData()).domTarget);
    };

    //A simple controller that declares one route
    //and an init method that will be called immediately
    //before its route handler is called.
    //The route it will handle is 'get /'.
    //The function it will call is showIndexPage.
    var controller = {
        init: function(){
            //The data for the Collection.
            var data = [
                {day: 'Monday'},
                {day: 'Tuesday'},
                {day: 'Wednesday'},
                {day: 'Thursday'},
                {day: 'Friday'},
                {day: 'Saturday'},
                {day: 'Sunday'}
            ];
            //Create a Collection and initialize it with some data.
            this.collection = v.collections.extend();
            this.collection.setModels(data);
        },
        name: '',
        routes: {
            'get /': showIndexPage
        }
    };

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

}(window.Coccyx));

Add tutorial05.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>
    <script src="javascripts/tutorial03.js"></script>
    <script src="javascripts/tutorial04.js"></script>
    -->
    <script src="javascripts/tutorial05.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:

minitutoutput4

Now click on a one or more of the days of the week that are displayed on the page. You should see something similar to this:

minitutoutput#5

What Just Happened?

Lets break this down by focusing only on what we added to the code from the previous tutorial:

  • We modified the way we are extending the daysOfTheWeekView to include a hash that has both a controller property and an events property. The controller property’s value will be used as the context whenever the event handlers are called which is convenient since it points to the controller. The events property is a hash whose property names are used to define the event type and the elements we are targeting, respectively, and the property’s value is the event handler function that we want to be called anytime an event on the element(s) is raised. So by defining these properties as we did, the function dowClicked will be called anytime a click event is raised on any h2 element on the page and it will be passed a jQuery Event object as its only argument.
  • In the dowClicked function we grab the inner text of the element that was clicked, which is the day of the week, and pass that on to the selectedDowView’s render method. The selectedDowView’s render method will render its DOM target by wrapping the text in an h3 element. Then the dowClicked function renders selectedDowView’s domTarget to the page by appending it to the div element whose id is container.

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

With the conclusion of this tutorial we have learned about Models, Collections, Views, Controllers and how to wire up event handling. In our next mini tutorial we will go back to Collections and explore its rich API in greater detail. See you soon.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s