July 1, 2015
•Last updated November 5, 2023
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 forms 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 have 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 simple Angular application. It is rather long and I wanted to 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 into 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 as 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 is the lightweight file size and 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 bound 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
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 the 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 the 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 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.js 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 that 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 wells 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 a 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.
- Addy Osmaniâs Backbone Fundamentals
- Code Schoolâs Backbone.js Course
- Official Backbone.js Documentation
- Introduction To Backbone.js Video - YouTube
- A very neat framework of a framework for Backbone called Marionette
Angular.js
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 its 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 an MVC type of framework developed by Google.
Installation
Installation is a breeze. For Angular, all you need to do is include a 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 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:
bash
- 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.
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 an Angular application. The controller is responsible for âcontrollingâ the data and sending it to the view to display inside an MVC setup as 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, let's 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 the 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 as we want it to now we need to tie in some data to actually perform a search as well as output the data on our page.
First let's 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 by another party. Keep this in mind when authoring your own apps.[/callout]
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..
Download Source Code or Preview
Conclusion
Weâve reached the end of our rather long look at JavaScript frameworks. This series has covered both simple and advanced topics 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
Categories
Collection
Part of the Beginner JavaScript collection
Products and courses
-
Hello Hotwire
A course on Hotwire + Ruby on Rails.
-
Hello Rails
A course for newcomers to Ruby on Rails.
-
Rails UI
UI templates and components for Rails.