DEV Community

Cover image for JavaScript Learn Object Literal Pattern
Raja Tamil
Raja Tamil

Posted on

JavaScript Learn Object Literal Pattern

In this JavaScript design pattern tutorial, you are going to learn how to build a simple web app using object Literal pattern.

At the end of this tutorial, you will be able to build an app similar to the screenshot below.

Alt text of image

Here is the HTML code for the app. Pretty straight forward!

index.html

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <title>Country List App with MVC</title>
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <h1>Javascript MVC -  Object Literal Pattern</h1>
    <p> Country List App</p>
    <section class="wrap"> <!--container-->
      <!--leftview-->
      <div class="wrap-listview">
        <ul id="contry-list"></ul>
      </div>
        <!--rightview-->
        <div class="wrap-detailsview">
          <!--img-view-->
          <div class="img-view">
            <img src=""  width='300' id="country-flag"/>
          </div>
          <!--text-view-->
          <div class="text-view">
            <h2 id="country-name"></h2>
            <h3>Country</h3>
            <h2 id="country-capital"></h2>
           <h3>Capital</h3>
            <h2 id="country-language"></h2>
            <h3>Language(s)</h3>
          </div>
        </div> <!-- /wrap-detailsview -->
      </section>  <!-- /container -->

      <script
        src="httpss://code.jquery.com/jquery-3.1.1.min.js"
        integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
        crossorigin="anonymous"></script>
        <script src="app.js"></script>
      </body>

</html>
Enter fullscreen mode Exit fullscreen mode

style.css

/*=======reset===========*/

* {
  box-sizing:border-box;
}

body, h1, h2, h3 {
  margin:0;
  padding:0;
  font-family:Arial;
}

h1 {
  text-align: center;
  padding:20px;
  background:black;
  font-weight:300;
  color:#999;
  font-size:1.4em;
}

p {
  padding:5px 10px;
  background: orange;
  display:inline-block;
  margin:10px;
}

/*=======container===========*/

.wrap {
  padding:10px;
}

/* ======left-listView====== */

.wrap-listview, .img-view {
  min-width:250px;
  float:left;
}

.img-view {
   min-width:50px;
}


.text-view {
  margin-top:-4px;
  text-indent:10px;
}

.text-view h2 {
  font-size:1.3em;
  color:#666;
  font-weight:500;
}

.text-view h3 {
  font-size:1em;
  font-weight:300;
  color:#999;
}

ul {
  margin:0;
  padding:0;
}

li {
  border:1px solid #cccccc;
  border-bottom:none;
  list-style-type:none;
  padding:10px;
}

li:last-of-type {
   border-bottom:1px solid #cccccc;
}

li:hover, li:hover h2,  li:hover h3{
  cursor:pointer;
  background:#63c7fc;
  color:white;
}

.active {
  background:#63c7fc;
}

/* ========right-detailsView====== */

.wrap-detailsview {
  overflow:auto;
  padding-left:10px;
}

.wrap-detailsview .img-view{
  min-width:300px;
}

.wrap-detailsview .text-view {
  overflow:auto;
}

.wrap-detailsview .text-view  h2 {
  margin-top:5px;
}

.wrap-detailsview .text-view  h3 {
    margin-bottom:25px;
}

Enter fullscreen mode Exit fullscreen mode

MVC – Model-View-Controller

MVC has been around since 1970 and is highly recommended by Apple and other companies. M – Model is responsible for all your data and business logic. V- View is responsible for your views (this is what the user actually sees and interacts with). C – Controller is a mediator that connects your Model and View.

Model and View should NEVER interact with each other. They can only talk through Controller. Now you understand the rules applying MVC in your application. I know it’s kind of vague, however, it will make more sense when we apply them in action.

Object Literal Pattern

var Human = {
   this.name = "Raja",

    speak : function() {
       return this.name + 'can speak';
    }
};
Enter fullscreen mode Exit fullscreen mode

As you can see in the above example, you create a simple javascript object literal {} as you normally do, but this time I added variables (properties) and functions (methods) into it, as one self-contained module.

This is how we are going to organize our code using MVC (separation of concerns). One module for Model, One for Controller and one for View. You can add more than one in any of MVC buckets as your application gets bigger.

Now, you understand what’s MVC and Object Literal pattern. Let’s see the well-organized code below and will explain after:

(function(){

"use strict";

// ================ Model ======================
const countryList = {
    selectedItem:null,
    countries: [
      {name: 'Canada' , continent: "North America", flagUrl: 'https://flagpedia.net/data/flags/normal/ca.png', capital: "Ottawa", language: "English and French"},
      {name: 'USA' , continent: "North America", flagUrl: 'https://flagpedia.net/data/flags/normal/us.png', capital: "New York", language: "English"},
      {name: 'Singapore' , continent: "Asia", flagUrl: 'https://flagpedia.net/data/flags/normal/sg.png', capital: "Singapore", language: "English, Tamil, Malay, Mandarin"}
    ]
};


// ================ Controller ==================
const countryListApp = {

  init:function(){
    // set first index of an array object as a currentItem
    countryList.selectedItem = countryList.countries[0];



    // initialize two view - ListView (left) and DetailsView (right)
    countryListView.init();
    countryDetailsView.init();

  },

  getCountryList:function(){
    return countryList.countries;
  },

  getSelectedObject:function(){
    return countryList.selectedItem;
  },

  setSelectedObject:function(newSelectedObj){
    countryList.selectedItem = newSelectedObj;
  }

}

// ================ View ======================


// listview
const countryListView = {

    init:function(){
      this.cacheDom();
      this.render();
    },

    cacheDom:function(){
      // cacheDom
      this.$ul = $("#contry-list");
    },

    doClickListItem:function(selectedCountryObject){
      return function(){
        countryListApp.setSelectedObject(selectedCountryObject);
        countryDetailsView.render();
      }
    },

    render:function(){

      // temp vars
      let i, $li, $lichild;

      // add and give event listener at the same time
      const clArray = countryListApp.getCountryList();

      // ----- loop -------
      for(i = 0; i < clArray.length; i++) {
        console.log(clArray[i].name);

        // you could use templet for this
        $li = document.createElement("li");
        $li.innerHTML = `<div class="img-view">
                  <img src="${ clArray[i].flagUrl}"  width="50"/>
                </div>

                 <div class="text-view">
                       <h2>${ clArray[i].name}</h2>
                       <h3>${ clArray[i].continent}</h3>
                      </div>
                `;

        // adding event listener to li
         $li.addEventListener("click", this.doClickListItem(clArray[i]));

        // append li to ul
         this.$ul.append($li);

      }
      // ----- loop -------

    }

}

// detailsview
const countryDetailsView = {
  init:function(){
    this.cacheDOM();
    this.render();
  },

  cacheDOM:function(){
    this.$countryName = $('#country-name');
    this.$countryFlag = $('#country-flag');
    this.$countryCapital = $('#country-capital');
    this.$countryLanguage = $('#country-language');
  },

  render:function(){
    var selectedCountryObj = countryListApp.getSelectedObject();
    this.$countryName.html(selectedCountryObj.name);
    this.$countryFlag.attr("src", selectedCountryObj.flagUrl);
    this.$countryCapital.html(selectedCountryObj.capital);
    this.$countryLanguage.html(selectedCountryObj.language);
  }
}


// ================ Start Point ======================
countryListApp.init();


})();
Enter fullscreen mode Exit fullscreen mode

As you can see in the above code, I have split it into three sections by adding comments: Model, View, and Controller.

Let’s take a look at the Model first:

countryList Object Literal that contains some data. In this case, we have one property named selectedItem set to null initially.

This property is basically set to the currently selected object when the user clicks a list item. This might be new to you but YES we are storing that information into Model, not in a click event that lives inside View.

Continue Reading...

Discussion (0)