How to REALLY Learn JavaScript Series: Part 9 JavaScript Frameworks

JavaScript was born out of the necessary need to manipulate elements on a web page and provide more interactivity than HTML and CSS alone were capable of. JavaScript will likely always remain as the go-to language for use in performing these enhancements. Almost every website makes use of JavaScript in some shape or form these days so it’s essential for any good web developer to understand the language to the best of their ability.

Developers and designers alike, strive to find more than just interactivity within their websites and apps but rather faster response times, realtime updates, and more efficient code. There has been a plethora of new JavaScript frameworks that have popped up across the web lately. These frameworks work together with your front-end code (and sometimes author the front-end code) to make web pages or applications more dynamic and efficient than ever before.

In Part 9 of the How To REALLY Learn JavaScript Series I’ll introduce you to a few of the most popular frameworks to date as well as give you a quick introduction of each.

This is a long blog post. Towards the end of this article I build a very simply Angular application. It is rather long and I wanted preface this content with a quick warning/surprise to you. Hopefully you don’t mind! If you want to jump to the Angular section feel free.

Web Apps over Websites

Before you dive in to a JavaScript framework you may need to ask yourself if your project even really requires one. There are a lot of websites out there built with so many frameworks which sadly end up being full of useless code (a.k.a. code bloat). Don’t fall into this trap with your own projects.

If your website is so simple that you only need static HTML and CSS, then you should only use those languages. There’s no need to install a CSS framework like Bootstrap or a JavaScript like Angular.js for very minimal things you could author with your own custom code. That said, if you are in the beginning stages of your app or site and you want to quickly prototype your ideas then these frameworks turn out to be a Godsend because of how easy they are to install and use.

Web apps, compared to websites, are built to serve a purpose rather than be purely informational. Some websites provide both realms of this but for the sake of discussion I’ll separate them in this way. New frameworks like [Angular.js]((https://angularjs.org/) and Ember.js entered the world to solve the problem of authoring dynamic HTML.

App-based websites require frameworks and a lot of JavaScript in order to work. Frameworks are made to help make your life easier.

In the end, remember to keep file sizes small as possible, the number of frameworks to a minimum, and as concise of code as possible. People using your website or app will have very little patience when loading content or waiting for something to happen after performing an interaction.

Your app may fall into the JavaScript framework category and it may not. There are plenty of other languages out there to build your apps and some can be more powerful. Languages like Ruby, PHP, Python and more can be used to do similar functionality as JavaScript frameworks. The major draw to JavaScript-based frameworks are the lightweight file size and the speed.

The Most Popular JavaScript Frameworks

Currently the most popular JavaScript frameworks are Ember, Backbone, and Angular. All of these frameworks have similar characteristics in terms of how data is rendered and binded to an HTML document. Each goes about this routing and manipulation in their own specific way but just remember you can use any of these three to perform the same functionality your application may require.

Ember.js

Ember JS | web-crunch.com
http://emberjs.com/

As stated on their home page, Ember.js is a framework for creating ambitious web applications. Out of the box, you can tie into their API to integrate very simple code into pre-existing HTML pages. It is a framework designed to build large web applications that compete hand to hand against similar native apps.

Ember makes use of Handlebars integrated templates that update depending on the state of data being sent or received.

These templates update depending on the HTML element(s) you write. Within separate JavaScript files you define the app as well as underlying objects which contain data that can be parsed from the front-end. This is what’s known as the MVC Model.

Installing

Installing Ember is relatively easy. You will need node.js installed and configured on your machine to install in the simplest way. Ember even has it’s own command line build tool called ember-cli which brings some built in tools and add-ons to make your experience with ember that much more badass.

I could teach you step-by-step how to install ember but I think the website’s guide does a great job at this. Find out how to install it here.

General Ember Concepts

Ember makes use of templates which are written in the Handlebars templating language. Read more about Handlebars here.

Inside these templates are what ember calls Expressions, Outlets, and Components.

Expressions – consider these placeholders for dynamic content. Say you want a name to update your content based on what user enters into a form somewhere within your app. Adding an expression to your template would be presented as {{Username}}.

Outlets – If you want to include a template inside another template to keep your code more concise and easier to manage. You can do that with outlets. These look similar to expressions {{outlet}}.

Components – A component is a custom HTML tag in which you create using JavaScript. You can configure how or where the component is displayed in the template. It can be configure as a unique HTML element <project-name></project-name> or as an attribute like this <div projectname></div>. This allows for the reuse of code and a very D.R.Y.(Don’t Repeat Yourself) approach to building your app.

Outside of the Handlebars templates and inside the JavaScript sector of Ember are the Router and Model

Router
Ember makes use of what they call a router. This translates a URL in a series of nested templates, each backed by a model(more on models in a second). As the models being shown change, Ember keeps the URL in browser up to date in relation to what the user is seeing.

Models
In Ember, a model is an object that stores a state or data to later get converted. Templates are essentially the model being turned into HTML for the browser to render.

Putting it into practice

I pulled the example below from the home page of Ember’s site. It is a very basic example of how dynamic Ember makes a simple snippet of HTML.

The code below would go into the application.hbs file inside app/templates/application.hbs. Make sure you have the server running within ember to run this code in your browser once you save it. Try entering your name and watch it update dynamically.


<div>
 <label>Name:</label>
 {{input type=“text” value=name placeholder=“Enter your name”}}
</div>
<div class=“text”>
<h3>My name is {{name}} and I want to learn Ember!</h3>
</div>

You should see something like this.

Pulling Data From A Server

Similar to using jQuery, you can pull data from a server pretty easily with JSON and some custom functionality from Ember.

In your app.js file you’ll need to enter this block at the bottom:


App.ApplicationRoute = Ember.Route.extend({
  model: function() {
    return Ember.$.getJSON(‘<your file path to JSON data>’).then(function(data) {
      return data;
    });
  }
});

Inside your template you’ll need to loop through the data and display it by accessing parameters set within the JSON data returned. Ember’s example uses this type of code to render a list of pulls from their Github repo.


<h3>Last 3 Pull Requests to Ember.js</h3>
<ul>
{{#each model as |pr|}}
  <li>
    <div class=“issue-number”>#{{pr.number}}</div>
    <div class=“issue-title”>
      <a href={{pr.html_url}}>{{pr.title}}</a>
    </div>
    <div class=“author-name”>
      Opened by <a href={{pr.head.user.html_url}}><strong>@{{pr.head.user.login}}</strong></a>
    </div>
  </li>
{{/each}}
</ul>

Personal Thoughts on Ember
Ember is a pretty awesome framework in my opinion and is one of the innovators of this type of dynamic templating paradigms you see in other frameworks. Angular, for example, is incredibly similar but goes about a few things differently. One neat thing with Angular is that you only need to include a single JavaScript file instead of all of the other dependencies required for Ember. I’ll talk more about Angular in a bit.

Backbone.js

backbone.js | web-crunch.com
http://backbonejs.org/

Backbone.js is a JavaScript library that adds structure to your client-side code. It essentially makes it easier to manage your application leaving you with code that is more maintainable.

Backbone is built upon the MVC structure. MVC stands for Model View Controller. This structure separates different parts of the application in a way that makes sense for the role each part plays. MVC Frameworks come in handy when you’re looking to maintain an advanced application with the least number of requests.

Developers should consider Backbone as it not opinionated; leaving you able to author your application in the way that best suits you. There is some out of the box structure you can make use of or you can always extend it.

Templates
Backbone doesn’t supply a specific templating engine thus giving you the freedom to use whichever you please. Common templating frameworks to use with Backbone are Underscore.js and Handlebars.js

Backbone Examples
I think with backbone it is easiest to understand by jumping straight into examples. Check out the structure below (source).

Say we want to build a simple to-do type of application. We can use Backbone and it’s MVC structure to go about this fairly easily.


<!— todo.html —>
<!doctype html>
<html lang=“en”>
<head>
  <meta charset=“utf-8”>
  <title></title>
  <meta name=“description” content=“”>
</head>
<body>
  <div id=“todo”>
  </div>
  <script type=“text/template” id=“item-template”>
    <div class=“view”>
      <input id=“todo_complete” type=“checkbox” <%= completed ? ‘checked=“checked”’ : ‘’ %> />
      <label><%= title %></label>
      <button class=“destroy”></button>
    </div>
    <input class=“edit” value=“<%= title %>”>
  </script>
  <script src=“jquery.js”></script>
  <script src=“underscore.js”></script>
  <script src=“backbone.js”></script>
  <script src=“todo.js”></script>
</body>
</html>

Here the example requires the <div> element with an id of todo. We also need a template containing placeholder information for a basic to-do item. You’ll see at the bottom of the file we included jQuery, underscore.js, backbone.js, and a todo.js file for our own code. Underscore.js’ is a good contender when it comes to templating with Backbone. A lot of developers use this combination as you might find out and hence why you see it here.

In our todo.js file we create Backbone models to hold data for each to-do item.


/* 
 todo.js
*/

// Define a Todo Model
var Todo = Backbone.Model.extend({
  // Default todo attribute values
  defaults: {
    title: ‘’,
    completed: false
  }
});

// Instantiate the Todo Model with a title, with the completed attribute
// defaulting to false
var myTodo = new Todo({
  title: ‘Check attributes property of the logged models in the console.’
});

We need a way to get our model to render into our initial HTML from earlier. To do this we create a Backbone view which defines the type of element, what kind of events, and any call back functions on those events. It looks a little complicated but the view is doing quite a few things to render our data on the page.


/*
  todo.js
*/

var TodoView = Backbone.View.extend({

  tagName:  ‘li’,

  // Cache the template function for a single item.
  todoTpl: _.template( $(‘#item-template’).html() ),

  events: {
    ‘dblclick label’: ‘edit’,
    ‘keypress .edit’: ‘updateOnEnter’,
    ‘blur .edit’:   ‘close’
  },

  // Called when the view is first created
  initialize: function() {
    this.$el = $(‘#todo’);
  },

  // Re-render the titles of the todo item.
  render: function() {
    this.$el.html( this.todoTpl( this.model.attributes ) );
    this.input = this.$(‘.edit’);
    return this;
  },

  edit: function() {
    // executed when todo label is double clicked
  },

  close: function() {
    // executed when todo loses focus
  },

  updateOnEnter: function( e ) {
    // executed on each keypress when in todo edit mode,
    // but we’ll wait for enter to get in action
  }
});

// create a view for a todo
var todoView = new TodoView({model: myTodo});

If you refer to the HTML earlier you may have noticed some new syntax styles within the view div. That syntax is what underscore.js uses to display dynamic data on the page. The templating engine connects with the model and controller to work to bring the data.

Personal Thoughts on Backbone
Truth be told. I find Backbone.js to be the most confusing of the three frameworks I’m discussing in this article. It is used by many well know applications you probably use often such as Disqus, Flow, Airbnb and more.

I’ve only meant to touch briefly on each framework so apologies if this isn’t quite in depth but as with any language or new tool you need to learn by doing. I followed along with a few resources to get more familiar with Backbone on my own. Take a look for yourself if you’re interested in learning more.

Angular.js

angular js | web-crunch.com
https://angularjs.org/

The almighty Angular.js framework is currently taking the web app and mobile app world by storm. More and more apps are using Angular for it’s extensibility, ease of use, and powerful features.

Other frameworks deal with HTML’s shortcomings by either abstracting away from the HTML and CSS itself or by providing a poor way to manipulate the DOM. Angular tries to fix that by offering many solutions to common problems we face within static content like HTML.

Angular plays nice with other libraries. Every feature can be modified or replaced to suit your own developmental needs. It, like the other frameworks I’ve discussed., is a MVC type of framework developed by Google.

Installation

Installation is a breeze. For Angular all you need to do is include a <script> tag with a link to the Angular.js library itself. Google even hosts the file for you so it’s extremely easy to stay up to date as improvements are made.

Basic Setup


<!doctype html>
<html ng-app>
  <head>
    <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js”></script>
  </head>
  <body>
    <div>
      <label>Name:</label>
      <input type=“text” ng-model=“yourName” placeholder=“Enter a name here”>
      <hr>
      <h1>Hello {{yourName}}!</h1>
    </div>
  </body>
</html>

The code above is just some boilerplate HTML code with a few new attributes and placeholders.

One required attribute with any Angular application is including the ng-app attribute on either the <html> tag or the <body> tag. You can name your app whatever you like to make it easier to reference with you start adding some control. Naming it is as easy as adding a value.

<html ng-app=“myApp”></html>

Concepts
Like Ember, Angular makes use of Expressions and Components but it adds it’s own technologies called Directives and Helpers with Localization.

Example App

Let’s get an example project going with Angular. I personally like this framework the most as it’s easy to understand and implement, but is also very powerful. The syntax feels natural compared to other frameworks I’ve tried.

The app I’m going to build as a simple example, is a search engine for famous guitarists. You can filter through them in real time as well as add new ones to the list to keep on file.

Basic Setup

To start lets create a folder and add a few files. Lets title our folder TopGuitarists. The structure should look similar to below. Use whatever subject matter you prefer to create your own version:

- TopGuitarists
| - mainController.js
| - app.js
| - index.html

For this specific app I’m going to make use of Bootstrap to prototype this quickly as this example isn’t focused on CSS.

Open your index.html file and make sure it’s pretty similar to the code below. Your versions may be different than mine but that is perfectly fine. You can find the latest version of Angular here and the latest version of Bootstrap (CDN) here.


<html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>Top Guitarists</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    </head>
    <body>

        <!-- :) Scripts -->
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
        <script src="app.js"></script>
        <script src="mainController.js"></script>
    </body>
</html>

In the code snippet above I’ve included the following

  • Bootstrap.min.css
  • Angular.js
  • app.js
  • mainController.js

To initialize our Angular app we have to add a module for use with the entire application. That takes place in the app.js file. Enter the code below to get things rolling.

angular.module(‘topGuitarists’,[]);

The angular.module function acts as a setter and a getter. The first parameter is the name of our app topGuitarists. I used camel-case type here because we will be using this inside of our controller coming up soon.

For now ignore the empty array after the comma. It is typically used inside more advanced applications that require specific dependencies. This example is meant to be a starter course so you’ll have to read the documentation to understand more about Angular.

With the module function added to our app.js file we can now connect our index.html page. Doing this is easy by simply updating the <html> tag to have a new attribute with our app’s name as we defined in app.js. Check out the difference below:


<html ng-app=“topGuitarists”>
    <head lang=“en”>
        <meta charset=“UTF-8”>
        <title>Top Guitarists</title>
    <link rel=“stylesheet” href=“https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css”>
    </head>
    <body>

        <!— :) Scripts —>
        <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js”></script>
        <script src=“app.js”></script>
        <script src=“mainController.js”></script>
    </body>
</html>
Controllers

Controllers are where the basic logic is handled in any Angular application. The controller is responsible for ‘controlling’ the data and sending it to the view to display inside an MVC setup like we have here. Let’s declare the controller for our Top Guitarists app inside mainController.js.


angular.module(‘topGuitarists’).controller(“MainController”, function(){
   var topGuitarists.this;
});

The code above is similar to the way we initialized our angular app. The major difference is the .controller addition which defines a controller for us to use inside our index.html page. Defining this inside our HTML gives our controller code the rights to this specific area as you’ll see.

To include our controller in our index.html page type the attribute on the body element like I have below. It doesn’t matter where you add the controller but it typically makes sense to add it on a block level HTML element like a body tag or div tag.


<html ng-app=“topGuitarists”>
    <head lang=“en”>
        <meta charset=“UTF-8”>
        <title>Top Guitarists</title>
    <link rel=“stylesheet” href=“https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css”>
    </head>
    <body ng-controller=“MainController as main”>


        <!— :) Scripts —>
        <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js”></script>
        <script src=“app.js”></script>
        <script src=“mainController.js”></script>
    </body>
</html>

Here we include our controller as an attribute on the body page of the index.html page. You’ll see the name we defined inside our mainController.js file is there as well as an alias main we will use to reference the controller easier coming up.

Displaying Data

Inside our controller we now have access to Angular and all it’s magic. Let’s add a simple title for now. Open your mainController.js file and modify it to look like the code below.


angular.module(‘topGuitarists’).controller(“MainController”, function(){
   var topGuitarists = this;
   topGuitarists.title = “Top Guitarists”;
});

Great now to get it to display in our HTML document we need to use an Expression to get the data to output to our page. Think of an expression as a placeholder for dynamic to target and inject into based on how you authored your controller. Update the index.html file to include the new elements below.


<html ng-app=“topGuitarists”>
    <head lang=“en”>
        <meta charset=“UTF-8”>
        <title>Top Guitarists</title>
    <link rel=“stylesheet” href=“https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css”>
    </head>
    <body ng-controller=“MainController as main”>
        <div class=“container”>
            <h1 class=“page-header”>{{main.title}}</h1>
        </div>
        <!— :) Scripts —>
        <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js”></script>
        <script src=“app.js”></script>
        <script src=“mainController.js”></script>
    </body>
</html>

I’ve added a div with a class of container (part of bootstrap) and an h1 tag. In between the tag you’ll notice our expression which is {{main.title}}. main is the alias to our controller named MainController. We are binding that with dot notation to title which was configured in our controller.

This might not seem that spectacular now but if you check your index.html you should see that our Title Top Guitarists appears. Cool right?

Two-way Binding. You will love it.

Two-way binding is probably what makes Angular such a popular choice in frameworks not to mention that it’s developed by Google. Anyways, lets make our app more badass by introducing our search field. You’ll soon see the effects of two-way binding. Open your mainController.js file again and update the code to match mine below.


angular.module(‘topGuitarists’).controller(“MainController”, function(){
   var topGuitarists = this;
   topGuitarists.title = “Top Guitarists”
   topGuitarists.searchField = ‘’;
});

Here I’ve defined a new variable to make use of in our app called .searchField. I also set it equal to an empty string so we can later reset the form easily after someone performs the search.

Next let’s add some more HTML as well as the new search field to index.html.


<html ng-app=“topGuitarists”>
    <head lang=“en”>
        <meta charset=“UTF-8”>
        <title>Top Guitarists</title>
    <link rel=“stylesheet” href=“https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css”>

    </head>
    <body ng-controller=“MainController as main”>
        <div class=“container”>
            <h1 class=“page-header”>{{main.title}}</h1>
                <div class=“input-group”>
                    <input type=“text” class=“form-control input-lg” ng-model=“main.searchField” placeholder=“Search…”>
                    <span class=“input-group-btn”>
                        <button class=“btn btn-default btn-lg” type=“button”>Search</button>
                    </span>
            </div>
                <p>{{main.searchField}}</p>
        </div>
        <!— :) Scripts —>
        <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js”></script>
        <script src=“app.js”></script>
        <script src=“mainController.js”></script>
    </body>
</html>

Our HTML file is growing and as you can probably tell I’ve added some new elements to make the search form both look presentable and function using our new variable we defined inside the MainController.

The input itself now has a new attribute called ng-model. I assigned this to our new variable main.searchField. Then after the search field I’ve added a simple p tag with an expression that will output the search terms we type as we type them ({{main.searchField}}). Check it out for yourself. Everything should be happening in real time. This is the magic of Angular and two-way binding.

ngRepeat

Cool, so now our form interacts like we want it to now we need to tie in some data to actually perform a search as well as well as output the data on our page.

First lets add some data to our controller. Open mainController.js again and update it to include the new array of objects I’ve provided below.


angular.module(‘topGuitarists’).controller(“MainController”, function(){
   var topGuitarists = this;
   topGuitarists.title = “Top Guitarists”
   topGuitarists.searchField = ‘’;
   topGuitarists.guitarists = [

        {
            name: ‘Jimi Hendrix’,
            band: ‘The Jimi Hendrix Experience’,
            guitarModel: ‘Fender Stratocaster’,
            favorite: true
        },
        {
            name: ‘Stevie Ray Vaughn’,
            band: ‘Double Trouble’,
            guitarModel: ‘Fender Stratocaster’,
            favorite: true
        },
        {
            name: ‘Jimmy Page’,
            band: ‘Led Zeppelin’,
            guitarModel: ‘Gibson Les Paul’,
            favorite: true
        },
        {
            name: ‘Slash’,
            band: ‘Slash’,
            guitarModel: ‘Gibson Les Paul’,
            favorite: false
        },
        {
            name: ‘Eric Clapton’,
            band: ‘Eric Clapton’,
            guitarModel: ‘Fender Stratocaster’,
            favorite: false
        },
        {
            name: ‘Jerry Cantrell’,
            band: ‘Alice In Chains’,
            guitarModel: ‘G & L Tribute Series Rampage’,
            favorite: false
        },
        {
            name: ‘Steve Vai’,
            band: ‘Steve Vai’,
            guitarModel: ‘Ibanez JEM’,
            favorite: false
        },
        {
            name: ‘B.B. King’,
            band: ‘B.B. King’,
            guitarModel: ‘Gibson ES-335’,
            favorite: false
        },
        {
            name: ‘Mark Tremonti’,
            band: ‘Alterbridge’,
            guitarModel: ‘PRS Custom 24 Singlecut’,
            favorite: false
        },
        {
            name: ‘Joe Satriani’,
            band: ‘Chickenfoot’,
            guitarModel: ‘Ibanez JS2410’,
            favorite: false
        },
        {
            name: ‘John Frusciante’,
            band: ‘Red Hot Chili Peppers’,
            guitarModel: ‘Fender Stratocaster’,
            favorite: false
        },
        {
            name: ‘Dimebag Darrell’,
            band: ‘Pantera’,
            guitarModel: ‘Dean ML’,
            favorite: true
        },
        {
            name: ‘Eddie Van Halen’,
            band: ‘Van Halen’,
            guitarModel: ‘Kramer Frankenstrat’,
            favorite: true
        }
   ];
});

Here I’ve added a handful of guitarists. There are so many to choose from I’ve only picked the ones the first came to mind.

A quick note: Most of the time data will be coming from a server elsewhere. Most apps are pulling JSON or from an API to get the data to use within their apps. This data can be self-hosted or provided from another party. Keep this in mind when authoring your own apps.

Now that we have an array full of data we can finally make use of the ngRepeat directive supplied by Angular. ngRepeat allow us to loop through the data we just added rather than having to type all that repetitive HTML. This is how it looks back in our index.html file.


<html ng-app=“topGuitarists”>
<head lang=“en”>
  <meta charset=“UTF-8”>
  <title>Top Guitarists</title>
  <link rel=“stylesheet” href=“https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css”>
</head>
  <body ng-controller=“MainController as main”>
    <div class=“container”>
       <h1 class=“page-header”>{{main.title}}</h1>
      <div class=“input-group”>
         <input type=“text” class=“form-control input-lg” ng-model=“main.searchField” placeholder=“Search…”>
        <span class=“input-group-btn”>
          <button class=“btn btn-default btn-lg” type=“button”>Search</button>
        </span>
       </div>
       <h3>Guitarist List</h3>
         <ul class=“list-group”>
        <li class=“list-group-item” ng-repeat=“guitarist in main.guitarists”>
           <h4>{{guitarist.name}} <small>{{guitarist.band}}</small></h4>
        </li>
        </ul>
          </div>
    <!— :) Scripts —>
    <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js”></script>
    <script src=“app.js”></script>
    <script src=“mainController.js”></script>
    </body>
</html>

The element that we want to repeat is the li element as you see above. To do that we add the ng-repeat attribute to the li and set it’s value to guitarist in main.guitarists. On any ng-repeat attribute you’ll take the singular name of the controller you authored before. I named the variable topGuitarists.guitarists if you remember so to reference it in a repeatable form you would use guitarist in main.guitarists.

ngShow & ngHide

You may have noticed a favorite property in each of the objects inside our guitarists array. By default I have these set to random boolean properties. If you don’t know what a boolean is I recommend check out an earlier post I wrote.

Let’s use an icon to show if a guitarist is favorited or not in our HTML. Update the li in your code to read like this.


<li class=“list-group-item” ng-repeat=“guitarist in main.guitarists”>
  <h4>{{guitarist.name}} <small>{{guitarist.band}}</small>
    <span class=“glyphicon glyphicon-star pull-right” ng-if=“guitarist.favorite”></span>
  </h4>
</li>

Here we added another attribute to a span element called ng-if and assigned it a value of guitarist.favorite. So all this is doing is accessing the guitarists array of data and showing a star icon if the favorite property inside each object has a boolean value of true. If it has a boolean value of false then it won’t show. Pretty simple right?

Filters with ngRepeat

We have our search form, our list of guitarists and all the data displaying nicely on the page. It’s time to make the search field actually do something. We want to make use of filters on the ngRepeat directive. Doing so is pretty simple and only requires a small addition to our index.html file.

Once again we need to modify our li element within our unordered list. Update it to match the code below.


<li class=“list-group-item” ng-repeat=“guitarist in main.guitarists | filter:main.searchField”>
  <h4>{{guitarist.name}} <small>{{guitarist.band}}</small>
     <span class=“glyphicon glyphicon-star pull-right” ng-if=“guitarist.favorite”></span></h4>
</li>

All we added is a filter to the ngRepeat directive above. A filter is separated by a pipe or |. The parameter to the right of the pipe filters the data to the left and reassigns it dynamically. Save your file and go try to search for one of the guitarists. You’ll hopefully see the whole list of guitarists update in real time.

Adding data

Great we have built our search form but what if we wanted to update the list with another guitarist? We can do this pretty easily. To do this effectively we will need to add some HTML to make sure we have all the necessary data in place. The updated HTML is below. Add it below the entire Guitarist List


<h3>Add another Guitarist</h3>
  <form name=“main.addForm” class=“form”>
    <div class=“form-group”>
      <label>Guitarist’s Name</label>
        <input type=“text” class=“form-control” ng-model=“main.new.name” required/>
    </div>
    <div class=“form-group”>
      <label>Band Name</label>
        <input type=“text” class=“form-control” ng-model=“main.new.band” required/>
    </div>
    <div class=“form-group”>
      <label>Guitar Brand and Model</label>
         <input type=“text” class=“form-control” ng-model=“main.new.guitarModel” />
    </div>
    <div class=“row”>
       <div class=“col-xs-6”>
         <label>Favorite Guitarist? <input type=“checkbox” ng-model=“main.new.favorite” /></label>
       </div>
       <div class=“col-xs-6”>
         <button class=“btn btn-success pull-right”><span class=“glyphicon glyphicon-plus-sign”></span> Add Guitarist</button>
       </div>
    </div>
</form>

Here I’ve introduced a form that when submitted will update the same data properties we entered within our mainController.js file earlier. At this point this form is rendered useless. I’ve added ng-model attributes as well as assigned their values. You will notice a .new property added between .main and the data title. This tells angular it is new data and when submitted will push data. We need to add some functionality to this within our controller. Open your mainController.js file and add this to the bottom.


topGuitarists.new = {};
topGuitarists.addGuitarist = function(){
  topGuitarists.guitarists.push(topGuitarists.new);
  topGuitarists.new = {};
};

I’m sure this looks confusing and because of my naming conventions I’ll admit that it is but let me digress.

The code above first declares a new object which our form will use to store its values by attached data to each ngModel we added each input. Then I created a new function called addGuitarist(). This will be called when we click the submit button on the form. The function takes the data from all the form elements, saves it to the empty object we created and then creates a new entry. From there, I assigned the same object we started to nothing so we can repeat the process whenever we please.

Events

To get the data to fire using the new function we created we have to modify the form in our HTML a tiny bit. Update the first line of the form in your html to this.

<form name=“main.addForm` class=“form” ng-submit=“main.addGuitarist()”>

Here I make use of the ng-submit directive provided by Angular. Once a user clicks submit on a form a callback function (the one we defined) will fire and something will happen. In our case if you were to add another guitarist the new entry would show up on our list. Pretty flipping neat! If you want to find out more about all the other event directives in Angular check them out within the Angular API documentation

Some nifty ones I’m a fan of are

  • ngClick
  • ngChange
  • ngChecked
  • ngClass
  • plus tons more..

Conclusion

We’ve reached the end of our rather long look at JavaScript frameworks. This series has covered both simple and advanced topic on JavaScript and I hope to continue it. If you have any suggestions for future topics I’d love to hear about them in the comments. Be sure to follow along from the beginning if you’re just getting here!

The Series So Far