≡ Menu

The Complete Beginner’s Guide to jQuery

beginners guide to jqueryjQuery is a technology that’s used with JavaScript, more specifically it’s a JavaScript library.

You can think of jQuery as a plugin whenever you’re writing JavaScript code inside of an HTML page.

The purpose of jQuery is to make your life easier as a programmer… this is typically the case for any technologies that are released these days.

More specifically, jQuery was created the solve a very annoying JavaScript problem.

You see, ages ago (before jQuery was invented), if you wanted to write some JavaScript code to make your HTML page dynamic, you’d have to test it in all the major browsers.

This meant that if you wrote some JavaScript, you’d have to test it in Internet Explorer, Firefox, Chrome, Opera, Safari, etc.

This was a HUGE pain in the butt, as I’m sure you can imagine.

But the question is, why the heck would you have to test out your JavaScript code in all these browsers?

The answer was that each browser would behave slightly differently when given the same JavaScript code. Sometimes the differences wouldn’t be too big of a deal, other times your code would just plain NOT work in certain browsers.

So the work-around to this issues was to create specific JavaScript code depending on what browser was being used.

So not only was this process time consuming, but it would also force you to create some REALLY unruly code. It was a mess.

Introducing jQuery

When jQuery was released, there was a collective sigh of relief in the JavaScript community.

Here’s how the people at jQuery define the library:

[jQuery] makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript.

It was the “write once, run on any browser” solution everyone wanted.

So when it was released, the amount of time dedicated to browser testing decreased significantly. Also, the awful browser specific coding practices vanished.

jQuery was originally released back in 2006, and it’s still used today by a large volume of programmers.

There have been criticisms lately from people saying that jQuery is “passé” and if you use it then you’re living in the past. My opinion on this is that if you’re using something like React or AngularJS, then sure, jQuery probably isn’t of use to you. But for a Java programmer who’s not using another JS framework, jQuery is still the way to go.

Installing jQuery

The first step when using jQuery is “installing” it into your HTML pages.

This is done using a simple script import tag.

Typically what I do is a Google search for the term “jQuery CDN” so that you can copy/paste a script import from a Content Distribution Network (CDN).

The CDN I use is jQuery’s own CDN, you can visit their CDN page if you’d like to see all the version of jQuery they’re hosting.

But I typically use the minified version of their latest release.

As of the time of writing this article, this is the latest minified version script:


How Do You Use jQuery?

Let’s get into some more detailed explanations of how to use this library and see some examples.

The most important aspect to jQuery in my opinion is something called selectors.

Selectors are used to interact with a specific element or elements on an HTML page.

For example, a typical use case is:

  1. User clicks on a button
  2. Button knows its been clicked on and executes a method
  3. Method runs and executes whatever needs to happen based on the button click

Well jQuery uses something called “selectors” to isolate elements like buttons and allows you to do things like add a listener for a click event.

Let’s assume I had the following HTML code:


With this code, we can use jQuery to “select” our button and then add a listener to it.

Let’s add a “click” event listener to our button with jQuery:

$("#myButton").click(function () {
  // the button was clicked, do something cool here
});
// note: this code won't actually work yet, there's one more piece of code you'll need to learn about in the next section

So in the code above we have three things happening:

  1. A selector is being used to “grab” the buttton
  2. A click listener event is being added to the button that we’ve selected
  3. We pass in a function as an argument to the click() method

So now we can put code in the function that’s inside of the click method. And whenever someone clicks on that button, the code inside of our function will be executed.

And the best part is that this will function identically across all web browsers, no more IF statements checking to see if a user is using Internet Explorer vs Chrome!

Now, this was only a small taste of what jQuery is capable of doing.

But before we dive further into what awesome things we can use jQuery to do, let’s see a more complete example.

I left out a critical piece of code in our jQuery code above, and without this code, the code won’t work properly… you’ll click the button and nothing will happen.

So I’ll need to introduce you to the document.ready() method.

The Document.ready Method

“My jQuery code isn’t working!” – you

If you’re saying this then that means you’ve tested my code above, but it’s not working.

There’s one more thing you’ll need to do to get things moving along.

You’ll need jQuery to let you know when the page has fully loaded before trying to execute your jQuery code.

Here’s an updated version of the code to reflect this “page loaded” concept:

$(document).ready(function () {
  $("#myButton").click(function () {
    // the button was clicked, do something cool here
  });
});

REMEMBER: if for some reason none of you jQuery code seems to be working, the most likely cause is that you forgot to use your $(document).ready() code.

The Document Ready Shorthand

One important thing to note before we can move forward is that since the $(document).ready() code is used so often, there’s a “short-hand” version of it for us lazy coders out there.

Here’s an equivalent block of code to the one above with the new shorthand:

$(function () {
  $("#myButton").click(function () {
    // the button was clicked, do something cool here
  });
});

Note: just to re-state what’s already been said, this code is equivalent to the one above it, as it’s using the short-hand version of $(document).ready().

The Full Working Example

Now let’s put all our code together into a fully working example that you can use yourself.

What you’ll do is create an HTML file and paste in the following code:

<html>
  <head>
    My First jQuery Example
    
    
  </head>
  <body>
    
  </body>
</html>

jQuery Selectors – By ID

The heart and soul of jQuery starts with its selectors.

You’ve already been introduced to one selector with the $("#myButton") code.

What you might not know is that there are MANY ways to select elements on an HTML page with jQuery.

What we’ve seen already is a selector by ID. That’s what the pound symbol denotes, a “select by ID” selector.

You’ll notice that in our HTML code, our button was assigned an ID as follows:


Because our button was created using an ID, we can use jQuery to select just that one button.

Let’s expand our HTML code to include some other elements:

Welcome to Our jQuery Example

There's a whole bunch of cool stuff that you can do with jQuery.

It's all in the name of making your HTML more dynamic and function universally across all browsers

With the new code above, we’re able to play a little bit more with our “select by ID” jQuery code.

Let’s say we want to select the first paragraph so that we can dynamically add more text to it. But more specifically, we’ll add more text to the first paragraph when we click on our button!

Inside of our jQuery code (within the <script> section of our code) we’ll add another jQuery selector that appends text to an element).

$(function () {
  $("#myButton").click(function () {
    // the button was clicked, do something cool here
      $("#paragraph1").append(" With jQuery we can even dynamically add text anywhere we want!");
  });
});

jQuery Selectors – By CSS Class

So we’ve seen how to grab elements from the HTML DOM (document Object Model) with the “pound” symbol (#), which is used to select elements by their IDs.

But what if the element we want to “select” doesn’t have an ID?

Well, another useful way to select elements is by their CSS class.

But remember that selecting by ID should guarantee you only select ONE element at a time. When you try to select by a class (or by many classes) you have a chance to select more than one element at a time.

Let’s dive into how to select elements by their class first, then we’ll tackle how to handle multiple elements at the same time.

First thing’s first, we need to modify our example code to include some CSS classes:

<html>
  <head>
    My First jQuery Example
    
    
  </head>
  <body>
    

Welcome to Our jQuery Example

There's a whole bunch of cool stuff that you can do with jQuery.

It's all in the name of making your HTML more dynamic and function universally across all browsers.

</body> </html>

Okay, so we’ve not added two classes firstParagraph and secondParagraph and we’ve added these classes to our two paragraph elements.

Now let’s change our jQuery code to modify the paragraphs by their classes instead of their IDs:

$(function () {
  $("#myButton").click(function () {
    // the button was clicked, do something cool here
      $(".firstParagraph").append(" With jQuery we can even dynamically add text anywhere we want!");
      $(".secondParagraph").append(" jQuery is fun once you get the hang of it!");
  });
});

The difference here can be very hard to catch, but what’s happening is that we’ve replaced the pound (#) with a period (.)

So this means that when you want to select by class, you just use a period before the name of the class you want to select.

So this means that if we changed our code above to use $("#firstParagraph") (with the pound sign), then this would be selecting an element with ID equal to firstParagraph, which in our example above doesn’t exist, so it wouldn’t select anything. But when we use the period symbol $(".firstParagraph") this means we’re selecting any elements with the class firstParagraph attached to it.

Selecting Multiple Elements with jQuery

When selecting elements, sometimes you want to perform an action on MANY elements at the same time.

This can be done by choosing a selector that applies to many elements.

If we want to select all the paragraph elements in our example above, we can just use the paragraph selector like so:

$(function () {
  $("#myButton").click(function () {
    // the button was clicked, do something cool here

      // select elements by a CSS class
      $(".firstParagraph").append(" With jQuery we can even dynamically add text anywhere we want!");
      $(".secondParagraph").append(" jQuery is fun once you get the hang of it!");
      
      // select all 

elements with this selector. $("p").css("font-size", "1.5em"); }); });

In order to select all the paragraph elements on the page, we can use the $("p") selector.

In our example above, we’re selecting <p> elements and we are setting the font size of all paragraphs to be 1.5em.

The consequence of using this paragraph selector is that we’re actually selecting more than one element at a time and we are dynamically changing ALL these selected elements at the same time.

Very handy for large “sweeping” changes that need to be made on the fly with JavaScript.

You can even COMBINE selectors to perform sweeping actions on many more elements simultaneously:

$(function () {
  $("#myButton").click(function () {
    // the button was clicked, do something cool here

      // select elements by a CSS class
      $(".firstParagraph").append(" With jQuery we can even dynamically add text anywhere we want!");
      $(".secondParagraph").append(" jQuery is fun once you get the hang of it!");
      
      // select all 

elements with this selector. $("p").css("font-size", "1.5em"); // select all

and

elements with this selector $("p, h1").css("margin-left", "1em"); }); });

Adding and Removing Classes with jQuery

Another helpful aspect of using jQuery is the ability to add and remove classes from elements.

A real world example of this is when working with Bootstrap and needing to show and hide elements.

The Bootstrap framework uses class called hidden that can be applied to elements to hide them from the page.

So if you want to hide an element on an HTML page with Bootstrap, you just add “hidden” to your element’s list of classes. Conversely, if you want to un-hide an element, you just remove this class.

Let’s assume that we have a paragraph of text that we want to show/hide and a button that we can click on to show/hide said paragraph:

Here’s what the HTML would look like:

Here's a paragraph that can be hidden by clicking on the button below

And here’s the what the jQuery code would look like:

$("#showHideBtn").click(function () {
  if ($("#hideableParagraph").hasClass("hidden"))
  {
    $("#hideableParagraph").removeClass("hidden");
    $("#showHideBtn").text("Hide");
  }
  else
  {
    $("#hideableParagraph").addClass("hidden");
    $("#showHideBtn").text("Show");
  }        
});

You’ll notice a few new things here.

  1. We’ve used a hasClass() method to determine if a specific element actually has a certain class assigned to it or not
  2. The removeClass() and addClass() methods were used to add/remove the hidden class on an element
  3. We changed the actual words that our showHideBtn button displayed by using the text() method

Here’s the complete example if you’d like to run the code yourself.

Note: I had to include the appropriate code to bring in the Bootstrap library files.

<html>  
  <head>  
    <title>My First jQuery Example</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <script type="text/javascript">    

    $(function () {
    $("#myButton").click(function () {
        // the button was clicked, do something cool here
        
        // select elements by a CSS class
        $(".firstParagraph").append(" With jQuery we can even dynamically add text anywhere we want!");
        $(".secondParagraph").append(" jQuery is fun once you get the hang of it!");
        
        // select all <p> elements with this selector.
        $("p").css("font-size", "1.5em");
        
        // select all <p> and <h1> elements with this selector
        $("p, h1").css("margin-left", "1em");
      });
      
      $("#showHideBtn").click(function () {
        if ($("#hideableParagraph").hasClass("hidden"))
        {
          $("#hideableParagraph").removeClass("hidden");
          $("#showHideBtn").text("Hide");
        }
        else
        {
          $("#hideableParagraph").addClass("hidden");
          $("#showHideBtn").text("Show");
        }
          
      });
    });
    </script>
    <style>  
      .firstParagraph {  
        color: blue;  
      }  
      .secondParagraph {  
        color: grey;  
      }  
    </style>  
  </head>  
  <body>  
    <h1>Welcome to Our jQuery Example</h1>  
    <p id="paragraph1" class="firstParagraph">There's a whole bunch of cool stuff that you can do with jQuery.</p>  
    <p id="paragraph2" class="secondParagraph">It's all in the name of making your HTML more dynamic and function universally across all browsers</p>  
    <button id="myButton">Click Me</button>  <br/>
    <p id="hideableParagraph">Here's a paragraph that can be hidden by clicking on the button below</p>
    <button id="showHideBtn">Hide</button>
  </body>  
</html>  

What .each() is, and how to use it

This section will take a closer look at .each() and teach you how to use it, how it works and provide some code samples for you to learn from.

.each() is jQuery’s version of a for-each loop. This type of loop iterates over the array or object, depending on the use, and gives you one value or key-value at a time to work with.

On integer indexed collections like standard arrays, one often uses the for(var i = 0; i < array.length; i++){} loop, but they won't work on key-value based collections like associative arrays, dictionaries and objects, so let's take a look at what jQuery brings to the table.

The syntax

The .each() function of jQuery was added to the framework before Javascript itself was given similar functionality, it is arguably one of the most important and most widely used functions of the framework, and actually comes in two different variants, giving you two different syntaxes to choose from.

Using $(selector).each()

The first syntax is when you are using it on an jQuery object directly by calling it as a method. The following code shows a simple example of this:

$('a').each(function(index, item){
    console.log(item);
});

If you are familiar with jQuery at all, then this syntax should be quite understandable to you, but let’s go over it step by step. First we have the jQuery $('a') object constructor, which takes as its input, or parameter if you like, the selector for the type of element to search for in the web page. This is written in the same form as CSS selectors, so if you know how to apply CSS styles, then you know how to select page elements in jQuery.

In this instance we are looking for all anchor tags, and jQuery supplies us with a jQuery object containing a list of all those tags. This object responds to the .each() method call, and it takes as it's parameter the function, or callback, you want jQuery to use on each of the items in the list. jQuery will supply the callback with the item and the index.

We chose to supply .each() directly with an anonymous function, the most common way to call .each(), but you can also supply named functions like so: .each(nameOfFunction). Inside the function we simply output the item to the console, but this is where you will make the magic happen.

Using $.each()

The other syntax is really a utility helper on the jQuery object itself and is used like this:

// array
var arr = ["a","b","c"];
$.each(arr, function(index, value){
    console.log(item);
});

//object
var obj = {
    "name":"Peter Pan",
    "address":"Neverland"
};
$.each(obj, function(key, value){
    console.log(key + " : " + value);
});

The most important difference between the two examples above is that one takes in an object, while the other takes an array, and that the callback gets handed either an index and value for the array, or a key-value pair for the object. Beware though, that because of the inner workings of the $.each() variant, passing in objects with a .length property will have undesired effects.

In both syntax variants, the item or value passed into the callback can also be accessed through the this keyword, as jQuery calls the function in the context of the element iterated over. Accessing it in that way will always give you an object, even if it is originally a simple type. In the case of using the $(selector).each() variant, you will only get raw HTML-elements, and to be able to use jQuery functions on them you will need to wrap them in a jQuery constructor like so: $(element).

Breaking or continuing the loop

Normally in control structures provided by the language itself, i.e. for, while, do while, switch and foreach, you have access to the break and continue keywords for ending the current iteration or the entire iteration prematurely. Not so much in the jQuery variants.

Let’s explore this with some more code:

// Do heavy lifting only on parts of the array
var arr = ["red", "apple", "green", "blue"];
$.each(arr,function(index, item){
    if(item == "apple"){
        return true;
    }
    // imagine this is heavy processing...
    console.log(item);
});

In the code above you see an example of aborting only the current iteration, the same way one would use the continue statement. The loop processes only the items which is not "apple", and we can save ourselves from wasteful processing by skipping the heavy part, and rather than putting the entire processing inside a huge if-statement, we cleanly exit the current iteration in an understandable way.

The next example looks into searching a collection for a specific object, which might need a custom comparator to find the right object.

//find and print object with id = 3
var objects = [
    {id:1,name:"object1"},
    {id:2,name:"object2"},
    {id:3,name:"object3"},
    {id:4,name:"object4"},
];
$.each(objects,function(index,item){

    // Check if the object had ID == 3
    if(item.id == 3){

        // Print the object
        console.log(item);

        // Abort the rest of the iteration
        return false;
    }
});

In the code above you see we first declare an array of objects with two properties, id and name. In the loop we then check for the right id, and if we find it, we print it out and skip the rest of the iterations, saving us, again, from wasteful processing.

Summary

In this section we have gone through a few aspects of jQuery’s .each() function, showing you two different ways to use it, and when to use which version. We also discussed some pit-falls regarding objects with a .length property.

In addition we covered accessing the items or objects fed to the callback using the this keyword, as well as showing you how to exit or skip iterations in the same manner as language native control structures does with the break and continue keywords.

Avoiding Conflicts with Other Libraries or Frameworks

As you have seen so far, jQuery uses the shorthand syntax $ to allow you to write shorter, more concise code that's easier to reason about. The $ stands out in the code, making it easier to read, and spot where the jQuery objects or utility functions are being used.

In this section we are going to take a closer look at how you can avoid conflicts with other libraries and frameworks that also uses $ as a shorthand. We will discuss the problem a bit and give you some examples in code that you can use if you want to avoid this problem, regardless of if you just want to be safe, or if you already have encountered this issue.

Non-conflict mode

jQuery has a function allowing you to set it in a so-called "non-conflict" mode, where the shorthand is renamed to something else. You get to pick the new shorthand, but you must be sure to do this immediately after you load jQuery. You also have to make sure you do it before you make any calls to jQuery.

Time for an example I think. In the following code you will see how to put jQuery in "non-conflict" mode right after loading it.

<script src="jquery.js"></script>
<script>
	var $j = jQuery.noConflict();
</script>

As you see, we assign jQuery to the variable $j, and doing so sets $j as the new shorthand do be used, and you can use what ever shorthand suits you. Just replace $ with $j where ever you normally would use $ in your code o use the new shorthand. We'll see more examples of this later.

If you don't want to assign a new name to the shorthand, and you want to use $ for jQuery, and still not override the other framework or library's shorthand globally, you can do so on a local scope by passing in $ to the .ready() method. Remember to still call the .noConflict() method first.

<script src="jquery.js"></script>
<script>
	jQuery.noConflict();

	jQuery(document).load(function($){
		$("#someDiv").hide();
	});
</script>

This technique is nice to have if you already have a block of code using the normal shorthand, and you don't need the hassle of rewriting it. One side-effect is that you will of course not be able to use the other framework's definition of $ to evoke methods or functions.

Don't forget that the jQuery(document).ready(...) method also has a shorthand. Using this will make your code even more short and concise, which is good, since you are giving up the $ for something else. Let's build on our example above where we do not define a new shorthand.

<script src="jquery.js"></script>
<script>
	jQuery.noConflict();

	jQuery(function($){
		$("#someDiv").hide();
	});
</script>

$ begone!

If you dont care about a shorthand at all and using the full name of the object, jQuery, then you don't have to set jQuery in non-conflict mode. You just need to make sure you load your jQuery before you load the other libraries or frameworks.

<script src="jquery.js"></script>
<script src="other-framework.js"></script>
<script>
	jQuery("#someDiv").hide();
</script>

"There is only one $, and It's name is jQuery!"

If you lean more toward having $ stay set for jQuery, and only jQuery, then you can override other uses of your favorite shorthand. You just have to make sure you load jQuery after any other framework or library that uses the shorthand. Do not use .noConflict(), and jQuery will steal the $.

<script src="other-framework.js"></script>
<script src="jquery.js"></script> <<-- Notice this line
<script>
	$("#someDiv").hide();  <<-- This is now jQuery
</script>

Summary

As we have seen in this section, there can come situations where jQuery and another library or framework come in conflict with regards to their shorthands overwriting each other. We took a look at a few techniques for handling this, either by ignoring it, giving up the $ or trying to find a middle ground where you can still use $ for jQuery, but in a limited way.

One last shortcut I want to leave you with is a self-executing function. This is a Javascript feature, so this time it's not jQuery doing the heavy lifting, but you still get a non-conflicted jQuery, where you can use your $ in the local scope.

<script src="jquery.js"></script>
<script src="other-framework.js"></script>
<script>
	(function($){
		$("#someDiv").show();
	})(jQuery);
</script>

Here we simply fed the jQuery object into the function as an argument, which essentially renames the jQuery object to $ for the local scope inside the function declaration. If you are writing plugins for jQuery, or depend on it at least, then this is the normal way to load jQuery into your module. This way you won't have to care about who owns the $.

Manipulating HTML Attributes and Element Content

In this section we are going to take a look at some of jQuery's most used and most useful methods. A big part of what makes jQuery such a great tool for working with HTML is the fact that it makes your repetitive tasks so much easier. It's not unusual to set, remove or change the content of one of the <div> tags hundreds of times in a moderately complex web-app. And that is just updating content. Changing look and feel is just as common.

Every character you can save writing, or write in a more concise way, is a good thing. Readable and understandable code is alfa and omega, the one ring to rule them all, a pillar of creation or which ever metaphore you preferr. Without that you will not be able to manage your code, and other will not be able to help you or take over your projects. I can't press that enough, and I hope jQuery can be one of many tools to help you do this.

Getting and setting text content

Let's start with .text(). .text() will get the text content of the targeted element, and all children. This is important to note, the returned value will consist of the combined text of all children, not just the one you are targeting. Let's take a look at some code to understand this.

...
<div id="container">
	<h1>Some heading</h1>
	<p>This is a paragraph</p>
</div>
...

Selecting the text from the top container here using $("#container").text() will result in the string Some heading This is a paragraph. This can be both useful, and a little "gothca", depending on the situation. Knowing about it let's you work with it, rather than against it.

Another thing to remember is that .text() will not get the content of input elements. There you will need to use .val(), which we'll cover a bit later.

Setting the text of an element is pretty straight forward as well. You just select an element as usual and invoke .text(string) supplying the new text which is to become the new content like so: $("#someElement").text("This is the new content");

There is a few things to be aware of here. Using .text(string) to set the text content of an element, replaces ALL the content of that element, including all children. Let's see that code again:

...
<div id="container">
	<h1>Some heading</h1>
	<p>This is a paragraph</p>
</div>
...

Using .text(string) on the top container here will result in replacing the header and paragraph inside it. $("#container").text("This is the new content"); produces:

...
<div id="container">This is the new content</div>
...

Another thing to take note of is that the string passed to .text(string) will be encoded behind the scenes so that any HTML content will be escaped, converting <p>This is a paragraph</p> into &lt;p&gt;This is a paragraph&lt;/p&gt; which makes the text on the web page appear as <p>This is a paragraph</p> rather than This is a paragraph, as one might expect. See below:

...
<div id="container">
	<p>This is a paragraph</p>
</div>
...
<div id="container">
	&lt;p&gt;This is a paragraph&lt;/p&gt;
</div>
...

The last thing we should take a look at before leaving .text() is passing in anonymous functions, rather than a string. This allows you to supply a function to be executed for each of the children, permitting some flexibility to the content without using .forEach() or other looping variants to set the text.

Using something like the following:

$("#content p").text(function(index){
	return "Paragraph " + (index + 1);
});

on this HTML:

<div id="content">
	<p>A</p>
	<p>B</p>
	<p>C</p>
</div>

produces the following result in the DOM:

<div id="content">
	<p>Paragraph 1</p>
	<p>Paragraph 2</p>
	<p>Paragraph 3</p>
</div>

Getting and setting HTML content

Phew! That was a lot of info on .text(). It is time to switch gears a bit and jump over to .html().

Warning!

Remember that bit about .text() encoding special characters so that supplying HTML would end up displaying the HTML rathert than enter it into the DOM? Well, with .html() the safety net is gone. You are on your own, and need to make aboslutely sure that what ever HTML you supply to the function, is of your own creation. Do not trust any other source, not even your database.

The HTML inserted into the page WILL execute, as with all other HTML you have, only at a later time. Text entered into a form, supplied in the URL, fetched from an API you cannot say with certain is safe, or any other kind of third-party involvement, is inherently unsafe, dirty and hazardous. If you use the wrong method for inserting the text into your page, you are opening yourself and your users for the risk of Cross-Site Scripting, or XSS for short.

Delving into details about XSS is far beyond the scope of this article, but if you are interested in learning about web security, which you should be, I recommend visiting OWASP Top 10. A newer list is in the works, but it's still very much relevant.

Now that you know how .text() works, and what the most important thing about .html() to remember is, learning the rest of .html() is super easy. They basically behave exaclty the same, but there are a few small differences, except for the escaping of HTML. With that in mind, I'll just disclose the differences below, rather than repeating everything.

.html() will only work on HTML documents, while .text() can be used on XML documents as well. In addition you can't get the content of the <script> tag since it does not contain HTML. For that you will have to use the .text() method.

Getting and setting the values of form elements

When you want to work with form elements, using .text() or .html() won't help you any more. To access the stored values, or set them, using jQuery you will nedd to use .val() instead. It works much as you'd expect after learning about .text() and .html(). It has the same method signatures, which means you can use .val(), .val(value) or .val(function).

There are of course some finer points to this method. The first of which is that using .val() to retrieve values on a collection, will return only the first elements value. If that element is a <select multiple="multiple">...</select>, a multi-select element, the method will return an array of all the selected options. As of jQuery 3, it will return an empty array if no options are selected, as opposed to previous versions which returns null.

Note: There is currently an issue in some browsers when getting the value of a textarea, where the carriage return \r is stripped from the value, resulting in only newlines \n, where one would expect \r\n. If this is an issue for you, you can read more on this issue in the official docs here: .val() | jQuery API documentation

// Getting the values from a multi-select, pre jQuery 3
var options = $("select").val() || [];

// Getting the values from a multi-select, as of jQuery 3
var options = $("select").val();

// Getting the value from a text-input
var username = $("#username").val();

// Getting the value from a checkbox
var userAcceptsTerms = $("#agreeToTerms").val();

Setting the values of text-inputs and textareas is pretty simple, as you are supplying the text-value to be inserted. For the other form elements however there is a slight difference. .val(value) accepts arrays of values for use with radio-groups, checkboxes and selects. The value or values you supply will not make the actual value of the elements change, but the element with a value that matches the supplied value, will be selected or checked.

Let's see some code:

<input type="checkbox" name="settings" value="subscribeToNewsletter"> Subscribe to newsletter<br>
<input type="checkbox" name="settings" value="publicProfile"> Make profile public<br>
<input type="checkbox" name="settings" value="showPhoto"> Show Photo in profile<br>

<input type="radio" name="gender" value="male" checked="checked"> Male<br>
<input type="radio" name="gender" value="female"> Female<br>
<input type="radio" name="gender" value="other"> Other<br>

<select name="options" multiple="multiple" size="5">
	<option>Flowers</option>
	<option>Drapes</option>
	<option>Table cloths</option>
	<option>Carpets</option>
	<option>Banners</option>
</select>

This HTML will display:

Subscribe to newsletter
Make profile public
Show Photo in profile

Male
Female
Other

Running the following code:

$("input").val(["publicProfile","showPhoto", "female"]);

$("select").val(["Drapes", "Carpets"]);	

Changes that to:

Subscribe to newsletter
Make profile public
Show Photo in profile

Male
Female
Other

Working with attributes

As with the other methods we have discussed in this section, .attr() behaves somewhat as expected with regards to returning the value of the attribute if you provide no value to set, and setting it with the same method and syntax, while providing the desired value. See some simple examples of this below.

<img id="sun" src="sun_and_clouds.jpg" alt="Sunny skies">
//alerts: Sunny skies
alert( $('#sun').attr('alt') );

//Alters the "alt" to: Clouds and Sun
$("#sun").attr("alt", "Clouds and Sun");

//alerts: Clouds and Sun
alert( $('#sun').attr('alt') );

Caveats

Just about any HTML attribute can be manipulated this way, but depending on the attribute or your jQuery version, there are some caveats you need to be aware of.

Before version 1.6 ( version < 1.6) the attribute checked would return a boolean of true or false for the checkbox's checked state. This boolean would represent the actual state of the checkbox, not just the initial state.

At version 1.6 (version == 1.6), the .attr("checked") method would return the string checked, rather than true. However, the state would not affect the returned value. It would keep returning the initial state from when the page was loaded or the element was added to the DOM.

From version 1.6.1 (version >= 1.6.1), the .attr("checked") method still returns the string checked if the checkbox is checked, but from this point on, the state of the checkbox also updates the returned value.

From version 1.6 and up, the value returned if an attribute is not present, is undefined. This will also apply to the checkbox, and since the HTML specification states that the checked="checked" attribute is a boolean type, it must be considered to be true, or checked, as long as the attribute is present, regardless of what the attribute's value is. This is true even for setting the value to an empty string.

This makes the code for checking the state a bit more cumbersome, but thankfully there are some other ways to do this, that keeps our code nice and clean. Both .props() and .is() can be used to extract a boolean value for us.

<input id="myCheckbox" type="checkbox" checked="checked">
$("#myCheckbox").attr("checked");				//"checked"
$("#myCheckbox").prop("checked");				//true
$("#myCheckbox").is(":checked");				//true
document.getElementById("myCheckbox").checked;	//true

.prop() vs. .attr()

We can't talk about .attr() without mentioning a bit about .prop(), but we won't dig deep into the latter. It's better that you get a short introduction so we can spot the differences between them, and if you find yourself needing a bit more advanced use of it, you can always read the very well written API documentation over at Mozilla. .prop() specifically can be found here.

The attributes of an element and the properties of an elemenet object can be confusing and easy to mix together. Prior to version 1.6 you could use .attr() to fetch the properties as well, but not without some consitency issues in some cases. As of version 1.6 the two methods cannot touch eachother's area of control, giving a clean separation in code.

selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, and defaultSelected are all properties that needs to be accessed with .prop(). If you look closely at them you can see that they are all pure properties, as they do no have an equivalent HTML counterpart.

Warning! In browsers like IE8 and older, an exeption will be thrown if you attempt to change the type of an input thats already in the DOM or created by HTML. This is regardless of if it's the attribute or property type that's being maipulated.

Common for both .attr() and .prop() is that you can pass multiple attributes or properties to be changes at the same time using a simple Javascript object. You can also pass in a function to compute what the attribute or property will be set to.

.is()

This next section will focus on the .is() function, which is a filter function that returns true if the element or elements you are pointing .is() to matches the arguments passed into .is().

This all sounds more complicated than it really is, as you will see in the examples. The function comes in four flavours with different argument types. You can pass in a jQuery selector, like .is("#mySuperElement") or .is(".myButtonClass"). A function for advanced or custom matching, like .is(myCustomMatcher), can also be passed in.

The third variant is passing in what they call a selection, which is a normal jQuery object containing one or more elements. This is typically the result of using a selector to match elements, and by far the most common. The fourth is passing in an element not wrapped in a jQuery object.

Time for some code:

<ul>
	<li>One</li>
	<li class="red"><i>Two</i></li>
	<li><b>Three</b></li>
</ul>
$("li").click(function(event){
	if( $(event.target).is("li") ){
		alert("is li");
	}

	var target = $(event.target)[0];
	if( $(target).parents().is("li")){
		alert("is a child of li");
	}
	
});

Ok, first we have a simple, unordered list with some text in each item. One item is italic and one is bold. Pay attention to how the <i> and <b> are wrapped inside the <li> and around the text.

We have attached a click-event to the list items, <li>, and in the handler function we have two if-statements checking some aspect of the event's target, using .is(). The first if uses .is() to see if the event's target is an element of type <li>. If it is, an alert is displayed.

Clicking on the first list item fires the handler and when the first if is evaluated, .is() returns true, because the jQuery object we created with $(event.target) contains one element, which is the list item we clicked on. It will not evaluate to true in the second if, because the <li> does not have a parent that is a <li>.

Clicking on the second one fires the handler as expected, but this time the first if is not triggered. Why is that? You clicked the list item, just like before when it worked?!? Remember I told you to pay attention to the italic and bold tags? This is why.

When you click on something, the event is propagated from the innermost element to the outermost. It bubbles up the DOM, from the element closest to the click, all the way up to the html tag at the topmost level. When you clicked on the italic list item, you actually didn't click directly on the <li>, but on the <i>. The same would happen if you click on the third item, only that you would hit the <b> instead.

This means that in the case of our example, just checking .is("li") on the $(event.target) won't cut it. We need to also check if the target has a parent that is a <li> if we want the .is("li") logic to cover all our cases. If you want the event to fire only if the target actually is a <li>, meaning that you only want it to trigger if you hit the element directly, and not one of the children, then $(event.target).is("li") is all you need.

Rewriting the if to cover both in a single test, you get something along these lines:

$("li").click(function(event){
	var target = $(event.target)[0];
	if( $(target).is("li") || $(target).parents().is("li") ){
		alert("is li");
	}
});

Or even simpler, disregarding where the click actually happened all together:

$("li").click(function(event){
	if( $(this).is("li") ){
		alert("is li");
	}
});

Now, these two last examples will always trigger the alert, since we are checking if the event attached to all <li> elements, has a target that is a <li>, or is a descendant of one. A more interesting check would be:

$("li").click(function(event){
	if( $(this).is(".red") ){
		alert("is red");
	}
});

Ok, I think we'll leave .is() at that, but remember to check the API documentation whenever you need more details, going into the deep end and trying more advanced stuff. Also remember that using the jQuery selectors, you can achieve great power with little code. Multiple selectors at once is a great example of that. ".tableHeader,.paragraphHeader,h1" will select all elements with the classes .tableHeader and .paragraphHeader, as well as all H1 elements. This can make it quite easy to check if something is one of your header types for instance.

Simple AJAX

So! It's time for a new section and a new topic. I thought it was time to start thinking about how to get dynamic or static data from a server, without reloading the entire page. You have all seen this many times in action, but you might not have thought about what or how at the moment.

Think about when you are on a profile page, making a change. When you hit save, you will experience one of basically two things. The first, and original, is that the page submits the entire form to the server, loading the entire page from scratch, drawing everything up again.

Usually it is pretty fast, and you'll only notice a flicker, but some pages takes longer and you'll face the blank screen for a few seconds. If you are creating a webpage, you'll want to reduce the amount of waiting and blank screens the user's experience on your site.

Which leads us to the second experience. This actually takes different forms, but generally and most common, is that a message appears on the screen, notifying you that the save was successful, without loading the page again. Some pages have even removed the save-button all together, saving automatically when you click out of the text fields.

A brief flashback

This second experience is what this section is all about. What's happening behind the scenes is something called AJAX, "asynchronous JavaScript and XML", and has been around since the late 90's when the team at Microsoft responsible for the Outlook Web App project, created the XMLHTTP scripting object.

This shipped with Internet Explorer 5, and as of Internet Explorer 7 is called XMLHttpRequest. The other browsers quickly followed suit, and Microsoft's XMLHttpRequest became the defacto standard. Work began in 2006 to standardize it in the World Wide Web Consortium (W3C).

In 2005 the term "Ajax" was used in an article to describe some techniques that Google used in GMail and Google Maps for loading data asynchronously. From there there have been a steady increase in the usage of Ajax for different purposes on web pages, and it, alongside something called Websockets, are what enables much of the dynamic web we see today.

$.get()

Well, it's time to look at some code. jQuery has multiple helper functions for making Ajax-calls easier. The main jQuery method for Ajax-calls is $.ajax(), which wraps the XMLHttpRequest object in a very convenient way. However, it is still a tad cumbersome to use for simple things, so it has been wrapped in functions for more specific types of Ajax-calls. $.get() is one of them.

$.get("/some/data/endpoint")
.done( function(data){		// Success handler
	alert("It worked!");
})
.fail( function(error){		// Error handler
	alert("Something went wrong");
})
.always(function(){			// This is always called
	alert("I always fire, regardless of success");
});

Now, as you can see in the code above, there are some moving parts, but it is not difficult to get the hang of this. First you see the $.get("/some/data/endpoint") statement. Notice the lack of a semi-colon. This is because we, on the next line, chain another method on to the result of the first.

.done() is used for triggering callbacks for when the data was fetched successfully. Pass it a callback or an anonymous function that accepts a parameter for the data fetched, and this function will get the data to do as it pleases. .fail() is the function you pass your error handler into, and .always() is good to have if you have something to do after the other methods are finished, for example some clean up.

Now imagine that you have a page with a table. The table is filled with some data that's dynamically generated from a database. Let's pretend this data is a list of high-scores, showing the top 3 players of some game. The data consists of the players rank, screen name and score.

Rank Nick Score
1. OmgIWon 999.458
2. *FaiaDude* 888.456
3. _MrIce_ 777.789
<table>
	<tr>
		<th>Rank</th>
		<th>Nick</th>
		<th>Score</th>
	</tr>
	<tr>
		<td>1.</td>
		<td>OmgIWon</td>
		<td>999.458</td>
	</tr>
	<tr>
		<td>2.</td>
		<td>*FaiaDude*</td>
		<td>888.456</td>
	</tr>
	<tr>
		<td>3.</td>
		<td>_MrIce_</td>
		<td>777.789</td>
	</tr>
</table>

Now imagine that you have a refresh-button on this table. Each time you click that button, the page makes a new call to the server to get some fresh data, or so you think. There is a built-in cache that caches the data from an URL, so you can save some bandwidth and time. In this case however, we want the data to be fetched each time, so we have to add some unique junk data to the request to defeat the cache.

// Add the click-handler to the button.
$("#refreshButton").on("click",refreshHighScores);	

function refreshHighScores(){
	// The junk data
	var junk = { "unique":new Date().getTime() };	

	// Send data like so for GET requests
	$.get("/highscores",junk)						
	.done(function(data){
		// Log to console for debug
		console.log(data);							
		
		// Call the function to refresh the DOM
		refreshTable(data);							
	});
}

function refreshTable(data){
	// Do some smart things to update the table here
}

As you can see, I'm not digging into the particulars of rendering the table, as that is covered in other sections. What you can notice is the use of the junk data. I'm using the current time and date in milliseconds. That value will effectively always be unique because it increments 1000 times per second.

The $.get() function takes data to be sent to the server as its second argument. Behind the scenes, jQuery takes this data, and puts it in the URL as part of the query string. Because of this, it will be wise to take care naming the junk-data with something that the server does not care about.

The actual reason for being able to send data this way using $.get(), is that sometimes the server needs some ID, a search term or other piece of information to be able to locate the correct data for you.

Data manipulation

Ok, so we saw a way to send some data to the server in the example with the junk data being used to defeat the cache for Ajax-calls. In many cases that will be the correct way to send your data to the server, but in other cases it will be wrong. This has to do with a few things.

Semantics

The first argument against sending data to the server for storage, alteration or deletion of objects using HTTP GET, which $.get() uses in the background, is that it is semantically wrong. HTTP GET is for retrieving data, it's a read-only operation for fetching some type of information, data, image or other content. You also have POST, PUT and DELETE that are used for these operations.

In a world of API's, REST in particular, there has to be some standards as to how to do certain things, or else everything descends into chaos, or at least development hell. Not having some basics that everyone agrees upon, makes developing an API, og working with some software to use an API, plain harder. If everyone knows and agrees how an API is supposed to operate, one will only have to worry about how the API is designed in terms of endpoints and parameters.

Typically you divide the main operations of a system in four categories, or types, based on the type of data manipulation being performed towards the back-end or the database, depending on your architecture. You will most likely have seen the abbreviation for this around the web: CRUD, Create, Read, Update, Delete.

When you think about it it really does boil down to just these four categories. You either produce or create som kind of new data by filling out forms, measuring something, fetching some data from a remote API or any other kind of operation that results in you saving some new piece of data in your storage.

Usually you want to display this data in some way, and then you need to get the data from the storage, or rather, read it. A lot of data also need maintenance. An example here is user profiles, addresses, preferences and any other kind of data that changes over time. When you manipulate this data and save the changes, you update the existing data with a new state.

Finally, there are data that is no longer of interest, is stale, you no longer have permission to store, or for some other reason needs to be removed. Then you need to perform a delete operation. These four operations have been mapped to the HTTP methods (called VERBS) mentioned earlier. GET performs Read operations, POST performs Create operations, PUT performs Update operations and DELETE is self explanatory. Sometimes you might come across PATCH being used in stead of PUT, but this HTTP method has traditionally had limited support by web servers, even though it semantically is a better verb to use.

Technicalities

The second argument against using GET for sending data is that there are some technical aspects as to why using GET to send large or complex data to the server for storage is problematic. The two most important aspects are URL-length and handling binary data. The length of an URL is limited in how many characters you can supply. The length differs in the browsers and web servers, but the current best practise is to keep the URL under 2000 characters long. And having different practises based on data size quickly becomes cumbersome to use and to maintain.

Sure, you can encode binary data as Base-64 so it's URL friendly, and sometimes you would do that for some of the other verbs like POST or PUT, but that actually adds about 30% to the size of the data. Uploading a picture is an example of this kind of data, and the best way to do this is to use POST and the browser's form handling logic.

The browser has built in support for uploading files to web servers in binary form, and it's usually done using the web forms you are used to, picking the file you want to upload etc. This must however be sent with a verb that supports a so called 'body'. Think of the request like an e-mail, with an address and a message. The address is the URL, and the message is the body. Some verbs, like GET, does not support sending the 'message' or 'body' part.

$.post()

Let's take a look at how to actually send some data to the server for storage. This will be the 'Create' in 'CRUD', as opposed to the previous example using $.get() as the 'Read' operation.

var userData = {
	"username":"bob",
	"e-mail":"bob@example.com"
};

$.post("/api/users", userData, function(resposeData){
	console.log("You have data:");
	console.log(resposeData);
});

In this example we first have an object with some user data. We'll keep it very simplistic for the sake of clarity, but usually there would be a lot more data like dates for creation and last update, password hash, password salt, addresses, phone numbers, names etc. We'll also pretend that this data is generated or provided in a meaningful way, without going into the details just yet.

As you can see from the actual method-call, it is basically identical with $.get(). You supply the URL, the optional data, and the optional success-handler. There is also an optional parameter for the expected data type of the returned data, but it is rarely used. The intelligent guessing it automatically does is pretty good at detecting and distinguishing between XML, text, HMTL, JSON or script.

As I stated above, one of the optional parameters is the success-handler. In the example below you can see an alternative way of supplying that, along with how you would handle errors. There is also an option to supply handlers that's always called, regardless of the success or failure of the request.

$.post("/api/vehicles", $("#newCarForm").serialize())
.done(function(data){
	// do something clever with the returned data
	console.log("Success!");
	console.log(data);
})
.fail(function(jqxhr, status, error){
	console.log("Error occurred:");
	console.log(status);
	console.log(error);
})
.always(function(){
	console.log("this prints either way");
});

One thing you need to notice here is the lack of semi-colons ; at the end of the lines before the lines starting with a dot. This way of splitting the big complex statement is the industry standard practice for achieving better readability.

This is sometimes called method chaining, and works because each part uses the so-called "promise pattern" by returning itself as an object. In this instance that means that each of the methods, including $.post(), returns the jQuery XML HTTP Request object, or jqXHR object.

The 3 chained methods, .done(), .fail() and .always() are all backed by a queue mechanism when you register the handlers. This means that you can register several handlers, and they will be executed in the registered order.

You should also notice the $("#newCarForm").serialize() that I used as the data input. We'll not dig deep into that at this moment, but basically what it does, is take an entire form, and generate an object with the key-value pairs you'd otherwise have to manually type.

$.getJSON()

Another useful method to know about, which is also a shortcut wrapper around the more verbose $.ajax() call, is $.getJSON(). This let's you fetch data from a server and it automatically tells the server that it only accepts the JSON-format. This way you know that if the request is successful, you actually have valid JSON in the data-parameter of the callback.

I'm also pretty sure you will see the pattern emerging as to how these functions are called, and the function signatures, but I will of course guide you through it.

// Example JSON data
{
	"userid":111,
	"nickname":"Professor X",
	"friends": [
		{
			"userid":222,
			"nickname":"Wolverine"
		},
		{
			"userid":333,
			"nickname":"Cyclops"
		},
		{
			"userid":444,
			"nickname":"The Beast"
		}
	],
	"foes":[
		{
			"userid":555,
			"nickname":"Magneto"
		},
		{
			"userid":666,
			"nickname":"Apocalypse"
		},
		{
			"userid":777,
			"nickname":"Dark Phoenix"
		}
	]
}

$.getJSON("/api/users/111", function(data){
	// Process the JSON
	
	//log all of the friends to console.
	$.each(data.friends, function(index, friend){
		console.log( "Friend number " + (index + 1) + ": " + friend.nickname); 
	});

	//log all of the enemies to console.
	$.each(data.foes, function(index, foe){
		console.log( "Enemy number " + (index + 1) + ": " + foe.nickname); 
	});
});

For brevity's sake I've not included error handling, but it works exactly as demonstrated earlier, you'd use .fail() either on the object returned by $.getJSON() or chained on the method-call: $.getJSON().fail(). And even if I haven't demonstrated it above, this method, like all the others, accepts data to be sent to the server in a parameter between the URL and the callback.

First in this example you will see a small JSON-object with some attributes, objects and arrays. The data is an overly simplistic example of one user's social graph data, or how he or she connects to other users. From this example data you can see the relationship between this user, his friends and his adversaries. I thought perhaps this was a slightly more fun example than using Twitter or Facebook data as an example.

The data shown is supplied by a server in various formats, but in this case we like JSON rather that XML or CSV, so the method in question is a perfect fit for our needs. The server detects that we only accept JSON, and honours that requirement. When we get the data into our callback, we can start processing it, and in this case we print the friends and foes to the console.

Let's take a REST

If you take a closer look at the URL we used to get the data, you will see that the number "111" is the same as the fetched user's userid. You will also see that the URL contains the word "users". This way of building URL's and endpoints is a part of building RESTful APIs, and it is an alternative way of passing request-data to the server. In this instance we are telling the server to fetch the user identified uniquely by "111".

The way the server can understand this is with some common practises, using the concept of an RESTful API, and having documented for consumers how the API works. Using the HTTP verbs we discussed earlier, GET, POST, PUT and DELETE, we tell the server which operation we want performed. In this case GET tells the server to fetch some data for us. Giving the server the URL of "/api/users/111" tells the server that we want to access the API to fetch some user data.

Had we only used "/api/users" as the URL, the expected behaviour would be that the server had returned ALL users, rather than one specific users. This is part of the common practises and rules of RESTful services. Supplying the number "111" as well, tells the server to only return that specific object. Often you might also see RESTful services call with query string parameters as well as the RESTful URL, "/api/users?friends=222,333". This would be expected to return all users who are friends with both Wolverine and Cyclops.

$.getScript()

This method is really similar to all the others, as expected, so we'll jump straight to the example.

// Example script to be loaded - example.js
function doSomething(){
	alert("It's alive!!!");
}

function alertSomething(msg){
	alert(msg);
}


// And our method doing the loading of the above script file
$.getScript("example.js", function(){
	// Now its loaded and ready
	doSomething();

	alertSomething("Hello!");
});

Here you see the script hosted in a separate file being loaded by the $.getScript() method. When the callback is called, the script is already loaded and ready. If the script contains self-executing functions, then those have already been executed as well.

The script is, again for brevity, kept overly simple and useless, but I hope it can give you some ideas on how to use it. Personally, I would likely use it for larger applications where the code can be separated in different files for different areas of the site. Not all users will use all the parts, and loading code thats never used is wasteful.

One example for such a use case can be an application where users have access to different modules or features. This could be a tiered access to features based on level of subscription, or having access to admin features. If you don't have access to something, theres no need to load that code.

.load()

Imagine a simple web site with just a couple of pages: Home, About and Contact. Also imagine that the site has the ability to show articles of some sort. Now, one could do it the traditional way with static linking and loading of the pages and articles, but we are going to do it more dynamically.

...
<div id="leftMenu">
	<ul>
		<li><a href="#" id="home">Home</a></li>
		<li><a href="#" id="about">About</a></li>
		<li><a href="#" id="contact">Contact</a></li>
	</ul>
</div>
<div id="mainContent">
	<!-- Main content loaded here -->
</div>
...
(function (){
	$("#leftMenu a").on("click", function(){
		var page = $(this).attr("id") + ".html";
		$("#mainContent").load("/pages/" + page);
	});
}());

First here we have parts of the HTML on the site relating to the left menu and the main content area. The menu consists of a <div> with an id, and a CSS styled unordered list containing some links.

Then we have some Javascript in a self-executing function which initializes the menu. This code selects all the links in the menu and adds an eventlistener to them, listening for clicks. The clicks trigger a callback that dynamically loads the content of the 3 static files: home.html, about.html and contact.html.

One reason to do something like this is if you are creating a single page application, which is the rage these days, where you load up all the logic in the front-end, and the back-end is mostly worried about storage and sessions.

You do of course need to have some business logic and data validation checks on the back-end as well, but buttons, navigation, viewing and displaying data, as well as generating dynamic layouts and content, and all other such things, are kept in the browser.

We touched another reason a bit earlier with regards to loading scripts. You load the content, data, logic or other resources on demand, rather than all up front. Doing it this way, as opposed to full page load from the server, saves some bandwidth and waiting time for the users.

$.ajax()

Well, it's time to take a closer look at the guy behind the scenes, the one pulling the strings, the puppeteer: $.ajax(). This is the method we have been using indirectly in all the examples about this topic. All the other methods have been convenience wrappers around this flexible method.

$.ajax() has a lot of settings and stuff you can play with, but keeping with the theme of easy and simple, for now at least, we'll only take a look a few of those choices. I'm gonna start by taking the examples from earlier, and converting them to use $.ajax(), rather than the utility or wrapper methods.

$.get("/some/url", function(data){
	....
});

The above is exactly the same as the more verbose below.

$.ajax({
	url:"/some/url",
	success: function(data){
			....
	}
});

We see here that we pass a configuration object to the $.ajax() method. To replicate the behaviour of the $.get() method, we only need to specify the success callback handler as well as the URL. The HTTP verb GET is the default, so you will need to implement the method property for all the other verbs.

One thing that the $.ajax() function makes easier for us than using the wrappers, is disabling the cache. Passing cache: false in the configuration object tells $.ajax() to automatically add the random junk to the URL for us, saving us the trouble.

$.ajax({
	url: "/highscores",
	cache: false,
	success: function(data){
		...
	}
});

Also remember that you can use the chaining variant with $.ajax() as well. This works because the object returned by $.ajax() is the same object returned by the wrappers, or rather, the wrappers return the jqXHR object returned by $.ajax().

$.ajax({
	url: "/some/url",
	cache: false
})
.done(function(data){
	...
})
.fail(function(error){
	...
});

Let's take a look at how you use other HTTP verbs supplying the method property.

$.ajax({
	url: "/some/url",
	cache: false,
	method: "POST",
	data: {
		one:1,
		two:2,
		three:3
	}
})
.done(function(data){
	...
});

As you can see it's pretty straight forward, like with most things jQuery. Remember to add some data to the $.ajax() call, if you want to send some data.

You are most likely going to need to specify your expected data type at some point. dataType is the correct property to use in that case. If you, on the other hand, need to tell the server what type of data you are sending, you will need to use the contentType.

$.ajax({
	url: "/some/url",
	method: "POST",
	data: {
		a:1,
		b:2,
		c:3
	},
	dataType: "json",
	contentType: "application/json"
});

The dataType property can be "xml", "json", "html", "script", "jsonp" and "text";

Now, as you see, the configuration object can become a bit large and complex. Splitting it up in smaller parts can be a good way to remedy this. Yes, it will cost you more lines, variables and assignments, but it will, hopefully be easier to read, understand and maintain. It also makes it a lot more simple to include computed values.

As you can see in the example below, you probably are already doing this for other, similar cases, and possibly for parts of the configuration object as well, but I felt it was needed to spell it out because one does not always see the simplest solution to a potential problem when learning something new, as I've experienced myself many times before.

And, yes, the example below is the other extreme. A middle ground that fits your particular case best is always the way to go. Don't get "religious" about coding styles or practises. Be smart about it.

var ajaxConfig = {};
ajaxConfig.data = {
	a:1,
	b:2,
	c:3
};

ajaxConfig.url = "/some/url";
ajaxConfig.method = "POST";
ajaxConfig.dataType = "json";
ajaxConfig.contentType = "application/json";
ajaxConfig.success = function(data){
	console.log("It worked!");
	console.log(data);
};

var jqXHR = $.ajax(ajaxConfig);

AJAX summary

I figure it's about time to change the subject again, now that you have a solid foundation of interacting with other systems via HTTP using some of what jQuery has to offer in it's AJAX portfolio. What we have gone through so far will cover most of the daily simple tasks where you just access simple REST based or other APIs.

You also have an understanding of how to read files from the server to load static content of different kinds. This can be JSON or XML data files generated and dumped every once in a while, partial HTML files to be loaded as part of the page, extra CSS or even JavaScript.

There is of course a lot more to it if you need more advanced features like manipulating or accessing HTTP headers before sending the request or after receiving the response. We will visit AJAX again at a later time, as well as use it in examples and demonstrations.

DOM Manipulation

There are many ways to manipulate the DOM using jQuery. Some methods will wrap new content around existing content, while others will remove them. This is also true for prepending or appending inside and element, adding elements before or after other elements and a few more. Let's begin!

A word of warning!
Many of these methods accepts raw HTML, just like the .html() method we looked at earlier. The same warnings and precautions has to be made with these methods.

DO NOT load code from untrusted sources like form input, URL parameters, cookies or dynamic databases where users, or external sites, can alter the content.

This is what causes XSS and a whole lot of pain for your users. If you DO have to load dynamic content into one of these, and you can't use .text(), then you need to understand what you are doing, and escape and remove all unwanted content, before posting anything to the page.

.append() and .prepend()

First we will look at two of the most used methods. .append() and .prepend() are heavily used when building menus, lists, tables and such structured constructs. I'll show an example below of a common way to build list-based menus using .append(), and then an example using .prepend() to add to the menu, once logged in.

// I'll also demonstrate different styles to do this, 
// so the code is a mix of several styles and techniques.
// Pick your poison, and stick with it as long as it fits.

var $ul = $("<ul></ul>");
$ul.attr("id","menu");

var $li1 = $("<li></li>");
$li1.addClass("navItem");
$li1.append('<a href="page1.html">Page 1</a>');

$ul.append($li1);

$ul.append(
	$("<li></li>")
	.addClass("navItem")
	.append(
		$("<a></a>")
		.attr('href',"page2.html")
		.text("Page 2")
	)
);

$("#menuContainer").html($ul);

// And now for .prepend(). Imagine the same menu as above, 
// only now the user has logged in, and the menu needs to 
// add a menu item. This triggers the following function:

function didLogIn(){
	$("#menu").prepend(
		$("<li></li>")
		.addClass("navItem")		
		.html($("<b>Logged in</b>"))
	);
}

You also have .appendTo([selection]) and .prependTo([selection]) which takes the selection target and appends or prepends it to all the targets in the selection parameter. The example below shows adding the text "NEW!" to all the elements with a "title" class, that's a subelement of one with "newInStock".

$("<b>NEW! </b>").prependTo(".newInStock .title");

.wrap() and .unwrap()

Sometimes you want to be able to put the selected element into another element, creating a new parent. Removing the parent of an element, effectively moving it and any siblings up the DOM tree, is also needed. And sure, there are many ways to do this, but few so simple as with .wrap() and .unwrap().

// Add another div-tag around this element.
$("#someElement").wrap("<div></div>");

// Remove all bold-tags from the page.
$("b > *").unwrap();

.after() and .before()

Next up is adding elements before or after an element. These differ from .prepend() and .append() in that they produce siblings, rather than children.

// Add a div with new content 
$("#someDiv").after(
	$("<div></div>")
	.text("Some new content")
);

// Add line number
$("span .line").before( function(index) => {
	return "<span>" + index + ".</span>";
})

The last example with the line numbers is similar to techniques used to add line-numbers to code views, like the one you are looking at. This would be after all lines are wrapped in span-tags and given classes to select against.

.before() and .after() also have a reversed form, where the selection target is the object being inserted, rather than receiving elements in some way. .insertBefore() and .insertAfter() works like you would expect after learning about .appendTo().

$("<div>Test</div>").insertBefore("p");

That example simply inserted a <div> element before all paragraphs.

.empty()

A short and sweet one. This method is as simple and self explanatory as they come. Calling it on an object will empty that object, which means that all the children will be removed and deleted. The following example shows a manual deletion of a status log displayed somewhere.

$("#someButton").click(function(){
	$("#statusLog").empty();
});

.remove() and .detach()

These to are almost identical, in that they both delete the set of matched elements from the DOM, children and all, but .remove() erases everything about the elements, while .detach() saves all jQuery information, data, triggers, events etc. Saving that is useful if you plan on inserting the elements again at a later time.

$(".alert").remove();

$(".message").remove(".warning");

Here we just witnessed all alerts being removed, while only the messages tagged as warnings were removed.

var $menu = $("#menu").detach();

// Some time later, the menu is to come back
$("#menuContainer").append($menu);

.replaceWith() and .replaceAll()

Our final duo for this time. It's quite similar to what you have already been through, so we'll save some time.

// Replace all occurrences of "b" with "strong" in the DOM,
// though removing all children, including the content text.
$("b").replaceWith("<strong>");

// Delete .someOtherClass and replace with your own class.
$(".someClass").replaceAll(".someOtherClass");

Summary

Well, that was a lot of info in a short time. We have covered just about evvery DOM manipulation method jQuery has. There is of course more to many of these methods, but I'll leave that up to you to discover.

Static Blog Example

Right now I think it's time for a practical recap of a few of the things we have been through so far. This section will be all about building a small application using Javascript and jQuery, as well as HTML and CSS naturally. The application will be a blogging platform with a twist.

The platform will not use a normal database for loading the content, but rather load it from various HTML-files, as well as reading the site's structure and list of page files from a JSON-document on the server. The platform will NOT have the ability to edit the files, only to read them, but budding developers like yourselves aren't afraid of writing some simple HTML markup.

To be fair, some of the features and functions are included, not because they are the best solution, nor a normal way to do things, but rather to demonstrate some aspects. Showing these features in more normal settings would not be feasible in this setting. Oh, and full disclosure before I forget. I am not a designer and I mostly do backend work. In other words, this isn't going to be pretty, but functional.

I have a working sample of the project up on GitHub. I also enabled GitHub Pages on it, so you can try it out. The live sample can be seen here, and the finished source code can be found here.

Basic structure

Well, with that out of the way, it's time to start this guide. The first thing we need to establish is the basic structure and organisation of the project. As this is a simple application, I'm not going to use npm or similar to initialize the project. Below you can see the directory structure we're building.

/
|- files/
|--  Here the HMTL files will be stored
|- resources/
|--  Here the CSS, Javascript and JSON will be stored
index.html

Start by crating the two folders, files, and resources, as well as the index.html file at the project root. Inside the index.html you can paste the following HTML to give us a starting skeleton. Notice the HTML comments indicating where to insert the rest of the code as we go along.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>My Static Blog Articles</title>
	<!-- Insert head code here --> 
</head>
<body>
<!-- Insert body code here --> 
</body>
</html>

As you can see the skeleton is very simple, with only some character set config, a page title and the HTML5 DOCTYPE. Next we are going to add the missing bits of the head.

Finishing the head

We are gong to load the jQuery files from a CDN in this example, but you might want to consider downloading it as it might be closer to your users, or if you use webpack or similar tools to build your application, you need it in your project.

We are also going to load a CSS-file and the heart of this application, the Blog.js file which we will create just a bit later. First, let's take a look at the rest of the markup to go in the head.

...
<script src="//code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="resources/Blog.js"></script>
<link rel="stylesheet" href="resources/style.css">
<script>
	$(function(){
		var blog = new Blog("resources/files.json");
	})
</script>
...

Two things to notice here:

  1. The jQuery URL is missing http: and https:.

    This is done so that the browser can use the same protocol for loading the remote resource as the page is displayed with. If you set this, and this is different from what the page is displayed with, the users might get security warnings, blocked content and have trouble using your site.

  2. No document.ready()?

    Well, not quite. The $(function(){}) is jQuery's shorthand syntax for the classic document.ready(). This code will wait to execute until the entire page has loaded and the DOM is ready, even if it's defined up at the top.

You can also see that we are loading the style.css and the Blog.js from the resources/ folder. Inside the resources/ folder you can now create those two files and fill style.css with the following, or just download it from GitHub.

html, body {
	width: 100%;
	min-height: 100%;
	padding: 0px;
	margin: 0px;
	box-sizing: border-box;
}

body {
	font-family: sans-serif;
	font-size: 16px;
	background-color: #302f2b;
	min-height: 100%;

}

h1, 
h2, 
h3, 
h4,
h5,
h6 {
	margin-left: 30px;
	margin-top:30px;
}

p {
	margin-left: 30px;
}

a {
	text-decoration: none;
	color: #31302c;
}

a:hover {
	text-decoration: underline;
}

.container h1, 
.container h2,
.container h3,
.container h4,
.container h5,
.container h6 {
	margin-top: 0px;
}

.centered {
	width: 100%;
	text-align: center;
}

.v-spaced {
	padding: 15px 0px;
}

.nav {
	margin: 0px;
	padding: 0px;
	list-style: none;
	background-color: #dbdae0;
	color: #31302c;
}

h3.nav-section-header {
	margin-top:20px;
	margin-bottom: 0px;
	padding-left:15px;
	margin-left:0px;
	padding-bottom:10px;
	border-bottom: 1px solid #b8b7b3;
}

#homeButton {
	margin:0px;
}
.nav-sub {
	display:none;
}

.nav-section-header {
	cursor: pointer;
}

.nav-section-header:hover {
	text-decoration: underline;
}

.nav-left {
	text-align: left;
	width: 170px;
	line-height: 0.8em;
	font-size: 0.8em;
	font-variant: small-caps;
	max-height: 600px;
	overflow-y: scroll;
}

.nav-left li {
	border-bottom: 1px solid #b8b7b3;
	padding: 10px 15px;
	max-width: 100%;
	box-sizing: border-box;
}

.nav-left .nav-sub li {
	padding-left:20px;
}

code {
	padding-left: 5px;
	padding-right: 2px;
	padding-top: 1px;
	padding-bottom: 1px;
	background-color: e8e8e8;
	font-family: Courier New, Courier, monospace;
}

pre[name="code"] {
	background-color: #e8e8e8;
	font-family: Courier New, Courier, monospace;
	padding: 10px;
	margin-left: 30px;
	display: inline-block;
	width: 620px;
	overflow: scroll;
	tab-size: 4;
	box-sizing: border-box;
}

blockquote {
	background-color: #eeeeee;
	padding: 20px;
}

.header {
	text-align: center;
	margin-bottom: 30px;
}

.header h1 {
	font-size: 3em;
}

.container {
	margin: auto;
	display: inline-block;
	vertical-align:top;
}

.container-left {
		width: 170px;
		height: 100%;
		min-height: 1em;
		display: inline-block;
	}

#mainContainer {
	min-width: 860px;
	max-width: 900px;
	display: block;
	height: 100%;
	background-color: #f5f9ff;
	padding: 30px;
	padding-bottom: 60px;
	box-shadow: 0px 0px 5px 2px rgba(0,0,0,1);
	min-height: 780px;
}

#mainContent {
	width: 650px;
	margin-left: 0px;
	box-sizing: border-box;

}

#leftMenu {
	box-shadow:  1px 1px 3px 1px rgba(0, 0, 0, 0.4);
	background-color: #dbdae0;
	position: relative;
	top: 0px;
}
		

I'm not going to go into any details regardring the CSS, as that falls out of scope here. You can just copy paste it into the file. We'll be coming back for the Blog.js-file, so for now you can just add the line that imports it.

The script inside the DOM-ready callback is really quite simple. All it does is create and assign a new instance of the Blog object.

Putting together the body

Now for the body you can use the following code. It has a few things going on worth mentioning as it's built up of a few components.

...
<div class="container" id="mainContainer">
	<div class="header" id="header">
		<h1>Blog Articles</h1>
	</div>
	<div class="container container-left">
		<div id="leftMenu">
			<ul class="nav nav-left">
				<li class="nav-item nav-page-item"><a href="#"><h3 id="homeButton">Home</h3></a></li>
			</ul>
			<div class="centered v-spaced"><b>Word count: </b><span id="count"></span></div>
		</div>
	</div>
	<div class="container" id="mainContent"></div>					
</div>
...

First you will see that it has a root container component called mainContainer. This contains the header, the menu to the left and the area for showing the content of the HTML-files. The menu will be built dynamically by the Blog object, but it is pre-configured with a "home"-button, as well as a word-counter at the bottom.

Prototype all the things

Building more complex objects in Javascript is a strange and colorful experience compared to the typical Object Oriented languages like Java and C#. This is partly because Javascript really isn't Object Oriented, but it does have laguage features which allows you to obtain parts of it, in a way. It is also partly because there are multiple ways to create objects or object like structures.

var a = {
	"b" : 0,
	"c" : "C",
	"d" : function(){
		console.log("A function");
	}
};

Using the JSON-like object closure is one way of doing it, and it can possibly be more maintainable, specially if the object is simple, but it has some performance issues compared to other ways of doing it. It is also not an object really, and it can't be created using new, as it is not a constructor.

In the code example before this, you can see me use a named function as a class. It contains properties and references its own instance using this. This is the constructor, the method called when you use the new keyword. You could also use an anonymous function stored in a named variable, var a = function(){...}, but this has its pitfalls as well.

This alone does however make for a boring object don't you think? It's got no methods, no real usefulness other than perhaps storing some values never to to be changed. We need to expand it with more functions. To do this, we need to use .prototype to hook into the base of the object, the "class", rather than an instance of it.

Blog.prototype.setArticleListFile = function(file){
	this.articleListFile = file;
	this.loadArticleList();
};

This function is really just a "setter"-method as it's called. It only sets the filename for the list of files to build the menu from. It also triggers the loading of the list in the view. What we do here is access Blog's prototype and set the anonymous function on the property named setArticleListFile. This makes the property become the funtion, turning it into a method for all to use.

One of the cool things here, is that since we are accessing the prototype of the class, we are altering the basis of ALL objects of the same class, giving all of the existing instances of that object the same new method.

Say you want to create a custom sorting algorothm for your use of Arrays in you application. Just take the prototype of Array and add, remove or alter things, but be careful not to break existing things depending on stuff you remove or alter.

Loading articles and lists

Well, it's about time to start loading up on some content. First we'll load the list of articles from the file passed in to the constructor. A simple $.getJSON(...) will work here. We'll load the data into the Blog-instance, and call the method rendering the articles menu.

Blog.prototype.loadArticleList = function(){
	$.getJSON(this.articleListFile ,function(data){
		blog.articles = data;
		blog.renderArticleMenu();
	});
};

For our next act well need to define some safety measures, or safe guards, and then load the given file name. Well define the prototypial method as usual, and then do a lot of checks, fetch the article name from the hash, check for missing filename and presenting the index, if there is no filename given. Lastly we will use a simple $.get(...) to get the content from the file, and then post it to the webpage.

Blog.prototype.loadArticle = function(){
	
	var hash = document.location.hash;
	var url = "";
	
	if(hash && hash.length > 1){
		url = hash.substring(1);
	}
	if(url.indexOf("//")>=0){
		url = url.split("//")[1];
	}
	if(!url){
		url = "files/home.html";
	}

	$.get(url,{"_":new Date().getTime()},function(data){
		blog.content.html(data);
		var count = $(blog.content).text().trim().split(/\s+/).length;
		$(blog.count).text(count);
	});
};

As you can see on the webpage, we also have a word counter at the bottom the left menu. This gets updated along side the article being loaded. You can see the algorithm I'm using to calculate this in the example above. Basically we take the content that the page has loaded as text, trim it to get rid of any leading or trailing spaces before we finally split it based on white space positions.

You should also take a note of the way the safe guards and default values are handled.

Please wait, rendering...

Remember the last method call in .loadArticleList() for rendering the menu, renderArticleMenu()? Now we are going to start picking that one apart. It is actually split into helper methods for maintainability.

Blog.prototype.renderArticleMenu = function(){
	var articles = this.articles;
	for(var i = 0; i < articles.length; i++){
		var section = blog.renderArticleMenuSection(articles[i]);
		$(blog.menu).append(section);
	}
};

Now that wasn't so bad, loadArticle() was a lot worse than this. First we set the local variable articles to be the same as the instance's this.articles. Purely cosmetic and personal taste, but it allows me to not use the this keyword, making my loop a bit prettier and easier to read.

The next this is the loop going over each and every item in the articles list, calling blog.renderArticleMenuSection() on each article item. If you remember the data structure in the JSON file with the URLs, you will see that these sections are the topics that hold the individual articles as children.

The result is stored in a local variable, again for readability, and then we use some jQuery to append the section to the blogs menu element. Now, if this is going to have a lot of topics, there will be much better performance in updating the DOM only once when the menu is done rendering.

This can be done by creating a copy of the already rendered menu, appending all the sections to that copy, and then replacing the old menu element with the updated copy. It has become common practice keeping a copy of the DOM, or parts of it, in memory, but not rendered on page. You then use that for all the manipulations before doing one big refresh, as the updating of a single rendered HTML element causes the browser to re-render the entire page.

Sections!

Let us keep going down the rabbit hole, following the white rabbit, or rather the method calls. .renderArticleMenuSection() is the next step to look at, and as you'll see, we are going to get a lot more jQuery and HTML this time.

Blog.prototype.renderArticleMenuSection = function(section){

	var submenu = $("<section>");

	var heading = $("<h3>").text(section.topic_title);
	heading.addClass("nav-section-header");
	heading.click( function(){
		$(this).parent().children("ul").toggle()
	});
	submenu.append(heading);

	var ul = $("<ul>");
	ul.addClass("nav nav-sub");
	for(var i = 0; i < section.articles.length; i++){
		ul.append(blog.renderArticleMenuItem(section.articles[i]));
	}

	submenu.append(ul);

	return submenu;
};

First we use jQuery to create and store a new section element, and call it submenu. We do the same with a h3 element, but add the content using method chaining at the same time. We then add a CSS-class to the header, as well as a click-handler targeting the headers ul sibling. Finally the heading is appended to the submenu, or section element.

Note: The click-handler assignment here can be done more efficiently using a CSS-selector called an "Adjacent Sibling Selector". This would allow us to select all the ul elements which are the first sibling of any element with the nav-section-header, outside the loop. Like so: $(".nav-section-header + ul"). I've opted to not do this here to illustrate how one in a general sense can assign handlers in loops like this. The CSS-selectors might not always work for every case.

Next, we create yet another element. This ul element is to be the list that hold all our links, like a traditional navigation widget does these days. We add a couple of classes before entering the loop where we iterate over each of the topics' children, the articles themselves. We append the result of another helper method to the list before adding the list to the submenu section element and returning it.

À la carte

Ok, it's time for Neo to follow the white rabbit again, but I promise, this one leads us to the red pill, the complete and functioning app. The final piece to fall into place to get off Shutter Island, is .renderArticleMenuItem().

Blog.prototype.renderArticleMenuItem = function(article){
	var a = $("<a>");
	a.attr("href","#"+article.url);
	a.text(article.title);
	
	var li = $("<li>");
	li.append(a);

	return li;
};

This one is really simple and straight forward, but I do want to point out some things, so we'll do it step by step. First we create the anchor element for the link, a. We then set the URL, or HREF value, for the link, pointing to the correct article. We add the "hash" to the url here as well. We then set the link text to be the articles title.

Finally we create the list item to hold the link, append the link, return the link item up the stack, et voilà, we're done!

Summing it all up

In this section we have built ourselves a blogging engine, entirely in Javascript, HTML and CSS. No servers have been harmed in the making of this blog engine, though you might want to use one to serve the app, rather than using the files locally from your filesystem.

We have seen a few different uses of jQuery doing DOM manipulation and AJAX for loading resources from files, which is basically identical to consuming a public REST API backed by a database. Swap the HTML-files and the JSON-datafile for REST API endpoints and you're set. Then you can add a more dynamic nature to the app if you want.

I hope this section was to your liking, and I hope you explore the example fully on GitHub if you are unable to make it work, or if hosting is an issue. With regards to hosing development projects in a simple way, I can recommend using Docker with Kitematic locally on your computer. You can then download web servers, databases or other stuff you need, mount your local files into the containers and have a powerful development environment set up in an easy way.

Manipulating CSS

Well, now that you are beginning to get a good grasp of how to remove or add new stuff to the page, as well as how to manipulate their attributes, I feel it's about time we covered some CSS manipulation.

Now I know, manipulating CSS manually is most likely something you will not be doing a lot of in your code. There are a lot of libraries of ready made components out there that does this for you, but it is really useful whenever you are creating your own components, or you just need a quick effect as a reaction to an event.

In this section we are going to explore some ways to manipulate the styles of an element directly, as well as adding, removing and toggling classes. We'll keep the pace nice and slow like before, with example code and a detailed explanation of the code. I'm certain you have spotted the high quality of the jQuery API in that it is highly consistent in how it is used with regards to parameters, returns and behaviours, but we will take it step by step, rather than start jumping ahead on assumptions.

.css()

Let us start with .css(). This method will let you directly manipulate the elements style-attribute. It provides a lot of small improvements over the native way to interact with the elements styles. One of these are the ability to use the property names as they are defined in both CSS and DOM.

CSS defines its properties in all lower case, using hyphens or dashes to separate words, for example background-color, border-top-radius, text-decoration. The DOM specification uses what is known as camel case, where there is no delimiter between the words, but each word, except the first, starts with an upper case letter, for example backgroundColor, borderTopRadius, textDecoration.

As usual in jQuery, the same method is used as both setter and getter, where the passed in parameters, or absence thereof, determines if you are setting or getting the underlying property. One important thing to remember is that the getter-variant of this method will return the computed styles, which might be different than what you though you assigned. This also means that the style might come from a stylesheet, rather than the style attribute.

CSS has some rules in place to decide which conflicting rules win, called the order of specificity. The rule of thumb here is that the closer to the element the selector is able to get, or the more specific the selector is, the higher order it has. The highest order style, wins and gets used. This allows you to set generic styles on the body, and still use a different value for the same style on paragraphs or headers.

<div id="div1" style="border-width: 1px;">1</div>
var div1 = {};
div1.borderWidth = {
	top:$("#div1").css("border-top-width"),
	right:$("#div1").css("border-right-width"),
	left:$("#div1").css("border-left-width"),
	bottom:$("#div1").css("border-bottom-width")
};
console.log("div1",div1);

Here you can see that we are using the getter variant, since we are not supplying other parameters other than the one identifying which style we want to get. You will notice that the HTML-markup uses the shorthand version to set all the 4 sides to 1 pixel width, but in the Javascript code there is no shorthand properties. This is important to note, as jQuery will likely throw an error because the browsers does not support getting the styles using shorthand syntax.

As you can see from the code, the first and only parameter for the getter is the property name. This is however a truth with modifications, as you will see in the next code example.

var div1 = {};
div1.borderWidth = $("#div1").css([
	'border-top-width',
	'border-right-width',
	'border-left-width',
	'border-bottom-width'
]);
console.log("div1",div1);

In this example we are doing exactly the same thing as before, only this time the property names are passed in as an array. This returns an object of property-value pairs, like the one we made ourselves in the previous example. Next, let's try to set some properties.

<div id="div1" style="border-width: 1px;">1</div>
// Variant 1
$("#div1").css("border-top-width",2);

// Variant 2
$("#div1").css("border-top-width",function(index, value){
	return parseInt(value) + 1;
});

// Variant 3
$("#div1").css({
	width:100,
	height:100
});

Ok, starting with variant 1 we see the expected key-value, or property-value pair being passed in. Variant 3 is an object of property-value pairs, like the one returned from the getter when you pass in an array of properties to get. Variant 2 is a bit more interesting, as it takes in a function as an argument.

The function passed in to the setter will be passed the index of the element in the matched set as defined by the selector as well as the old value of the property. This function is applied to all elements matched, so you can also use it to manipulate the css based on the index in the set. The function needs to return either a string or a number which is a valid property value.

.addClass(), .removeClass()

These two methods are pretty self explanatory, but we will take a closer look to ensure we understand them fully. .addClass() takes as argument the class, or space separated list of classes, you want to add. It does not validate anything for you, so you might add the same class multiple times if you are not aware of that. It can also take a function as an argument, which is supplied with the elements index in the selection set, and the current value of the class attribute.

.removeClass() works opposite, and will remove any given class or classes. This does also support passing in a function to calculate the returned list of space separated classes to remove.

<div id="div1" class="bold italic underline">1</div>
$("#div1").addClass("bgRed").removeClass("underline italic");

In this simple example we see that the div has already set some classes. In our Javascript we then add the class bgRed to the element, before removing the underline and italic classes. Since this is jQuery, method chaining is always enabled, and the function you pass in as an argument behaves exactly as planned.

.toggleClass()

In its simplest form .toggleClass(className) will add or remove the given class depending on if the element already has the class or not.

<div id="div1" class="bold italic underline">1</div>
$("#div1").on("click", function(){
	$(this).toggleClass("underline");
});

The example above shows a very simple implementation that switches the underline class on and off when the user clicks on the div. The method also has a version where you pass in an additional boolean to tell the function to add or remove, allowing you to use it as a shorthand for .removeClass() and .addClass() when you have a computed boolean which determines the state of the view component.

Well, as always, there are of course more details to be had about the inner workings of these methods, but that's what the developer forums and documentation is for. We did cover how to do simple CSS manipulation using .css(), .addClass and toggle().

Simple Events

Ok, up until now you have basically only been exposed to .click and $(document).ready() as far as events go. There are a lot more events to explore, some more interesting than others, some more complex than most, and some that are as simple as that.

We are not going to go through everey single event that exists in modern browsers, as that would quickly be a book on its own. Instead we are going to focus on the most common, and try to avoid unneccesary complexity.

.blur() and .focus()

As usual in jQuery these are both setters and getters, or rather emitters and receivers, triggers and targets or publishers and subscribers, as the terms are in event handling and messaging. This means that you can both get data out of the methods, or rather have the methods give you data when something happens, as well as causing them to trigger without the event actually happening.

In some cases you can define your own events to listen for, as well as defining your own system of emitting notifications to trigger the event handlers. Mostly though, you don't. The main bulk of the work with events, revolves around forms, AJAX and navigation.

Often you will find that you want to be notified when a form field updates, a button is clicked, the menu is used to select new content for the page or a part of the page, or some new piece of data is returned fron an AJAX call or websocket. Sometimes you might also be interested in listening for changes to CSS orsome of the document or window properties.

What ever your use case will be, using events is a powerful tool, and using jQuery to assist in handling them makes it quite a bit easier to do so. Let's start by looking at .blur() and .focus() to get our feet wet.

...
<input type="text" id="username" name="username" 
	placeholder="Username">
...

What you see here is a simple text field for entering your username. This is usually seen in two places, login screen, and signup forms. The two event-methods we are discussing now are useful in both scenarios. Let's start with the login screen variant. One of the single most user friendly features you can have in a login form, is automatically placing the caret or focus in the field, so the user can just start typing when the page loads.

This sounds obvius, and is almost stupid simple to do, but it is sadly often neglected. Sure, some sites might have special use cases that prohibit this behaviour, but I'd say the norm should be that it is implemented in some form. In it's simplest form, it's almost a one-liner. In fact, in ES6, the next version of Javascript, it will become a one-liner with the new syntax for functions. I'll post both version below as a comparison, and as a teaser.

// The normal syntax
$(function(){
	$("#username").focus();
});

// ES6 syntax
$(()=>$("#username").focus());

Now I'm not going to go into the details about arrow functions here, but I can recommend reading Mozillas take on it here. ES6 will bring a lot of new nice features to the table when it is widely supported in the browsers. As of now, it is most widely used for server-side programming in Node.js as well as internal sites, pages and tools where you can know that the users have a browser that supports it. Another usecase is using transcoders to translate from ES6 to an older variant.

Now, this code does only one thing really, and that is to tell the text-field to trigger its eventhandlers in addition to moving the focus on the page to the text-field. If you want to listen to this event yourself, you just pass in a callback like so:

// The normal syntax
$(function(){
	$("#username").focus(myCallback);
});

function myCallback(event){
	// Here you can do some cool stuff whenever the text-field recieves focus.
}

.blur() is the opposite of .focus() and is triggered when the element looses focus. You can also use this to make the element loose its focus. Listening for this event can be useful if you want to do some automatic validation as soon as the user moves the caret to somewhere else.

.change()

This event is triggered when an input element, a textarea or a select has its value changed by the user. Other than for select boxes, radio buttons and checkboxes, the event does not trigger until the element looses focus, so it won't trigger for every key-stroke while you type.

Common use cases for this event is triggering some UI change, a navigation or an AJAX call to a server. Another thing you can do is have the e-mail validator, password matcher or other input validation mechanism you might be using, run when this event is fired.

Consider the following HTML code:

<input type="radio" id="light-switch-on" value="1"> On<br>
<input type="radio" id="light-switch-off" value="0" checked> Off<br>
<div style="width:100px; height:100px; background-color:black;"></div>

And the following Javascript:

$("input[id^='light-switch']").change(function(){
	$("#bulb").css("background-color",$(this).val()=="1"?"white":"black");
});

When you operate the light switch by pressing On or Off, you trigger the event and the light bulb, <div id="bulb"...></div>, toggles its background color between black and white. Of course, this particular example would also be solved with a simple checkbox monitoring the checked attribute, rather than the two radio buttons here.

Sure, the light switch and bulb is a bit constructed, but it is a great placeholder for making toggled changes with multiple values on a page. Examples of this can be changing the theme, switching language, toggling layers on a map and many other situations where a push button or switch is useful.

The exact same thing holds true if you want to watch for changes in the textfields and textareas and work upon that. Just attach a handler like above, and do your text processing when the text changes. You might of course want to use another selector, like $("input[type='text']") or the id of your field.

.select()

Alright! Let's move on to detecting when text is selected in a textarea or a textfield.

The act of selecting text with your mouse or some keyboard combination will fire the event and let you know that the source of the event has had all or some of its text selected.

Note: Getting the actual selection is different between the browsers, and the jQuery framework maintainers feel that this use case falls outside the purpose of jQuery, but there are a lot of tools and jQuery plugins out there to help with the cross browser problem if you need to support older browsers. For modern browsers I'll demonstrate below.

Ok, now take a look at the following paragraphs of code:

<form>
	<input type="text" id="my-text" value="You can select this text">
	<textarea id="my-big-text" cols="20" rows="5">Even more text to select</textarea>
</form>
$("form > *").select(function(){
	// Get the Selection object from the Window object
	// then convert to string with .toString()
	alert(window.getSelection().toString());
});

Here you can see two examples of text inputs where you can select the text and have the event trigger. The selector is quite specific here, to ensure that only children of the form are reacted upon. You can also set the the .select() event handler on the body if you want to react to all text inputs on the page with the same handler.

In the javascript you can see that we simply alert the selected text, using the modern approach with the Selection API supported in newer browsers. Take a look at Can I Use to see the browser support.

.submit()

When you are working with forms, you will a lot of times want to pick up then the user hits "Submit" or presses enter to submit the form. Attach your handler to the event raised by using .submit().

One of the most common use cases for handling this event is validating the form before allowing it to submit. You can cancel the submission by returning false from your handler. A simple handler that only returns false is a common way to stop forms from submitting with a subsequent page load, when you would rather use AJAX to handle the data transfer.

<form>
	<input type="text" name="username" placeholder="Username"><br>
	<input type="password" name="password" placeholder="Password"><br>
	<input type="submit" value="Login">
</form>
// Do validation before submit
$("form").submit(function(event){
	if( !myFormIsValid($("form")) ){
		return false;
	}
});

// Block all sumbits
$("form").submit(function(){
	return false;
});

Here you see a simple example of both scenarios. Given the login form above, the Javascript code will attach the handler to the form, and in the first case, check for errors in the form using a custom form validator (not supplied here). If it finds errors, it returns false, and the submission is stopped. If no errors are found, then the submission goes through.

The second example blocks all traditional form submits, but allows for a neat and semantic organisation of your code. Of course, as with all else, there are other ways to achieve this effect as well, and one such case is to just set the HTML attribute onsubmit to false: <form onsubmit="return false"$gt;.

This concludes our look into the event specific methods for setting handlers, even though we have only touched a brief few. We have also only looked at how to set the handlers, not how to remove them, nor how to trigger them manually. We'll cover removal in the next section, as well as setting and triggering in detail, but generally, you trigger an event by calling the event specific methods without any arguments, by using .trigger(eventType), or one of its variants (read more here).

.on() and .off()

I think you are well versed and familiar enough with the shortcut methods for setting up event handlers, that we can take a step back, dig deeper and take a peek under the proverbial hood. All of the methods you have seen so far are in reality wrappers around .on(), giving you an easier to remember and a shorter, more concise API to work with in the most common use cases.

The syntax for setting simple handlers are: .on("event to listen for", handler) Let us say we are setting up a click handler, and we want to use the more verbose variant, perhaps because we have made our own wrapper for dynamically adding handlers. Then you simply use .on("click",myHandler), where myHandler is the method you supply to handle the click event.

Similarly, to remove a handler when you don't want to listen for more events, you use .off("event no longer interesting", myHandler). Let's see a short example setting and removing a click handler.

// Let's do this the ES6 way as you already know the other way
$( $("#myButton").on("click", event => alert(event.target.innerHTML) ) );

// If you want to have a reference to the handler for later use, save it first
const clickHandler = event => alert(event.target.innerHTML);
$( $("#myButton").on("click", clickHandler ) );

// Stop listening for all clicks when a hypothetic form is submitted
$("#myForm").on("submit", event => $("#myButton").off("click"));

// Stop listening for only the handler saved
$("#myForm").on("submit", event => $("#myButton").off("click",clickHandler));

First we see the ES6 variant using the anonymous arrow function syntax for setting the handler inside the jQuery document ready shortcut. The handler itself, event => alert(event.target.innerHTML), only alerts the HTML content of the element triggering the event. In this case the element is quite given, but in some cases one attaches to the body and listens for bubbled events. We'll see an example of that later when we discuss selectors and namespaces.

The second example shows the same anonymous handler saved as a block scoped constant. Saving it like this, as a normal variable or even defining it as a named function, myHandler(...){...}, in the global or local scope, will allow you to use the function reference to remove only that specific handler. This is useful if you do not want to remove all handlers, just the one you set. We'll discuss this in more detail in a bit, but let's finish with the code first.

The third snippet show removing all listeners for click on myButton, regardless of who or what set the listener. This is, as you see, done when myForm is submitted. The last snippet shows how to use the function reference to remove only the specific handler that you set in snippet number 2.

Namespacing

When using or writing plugins, components or modules for applications you need to take extra care not to stomp all over other parts of the application that might have handlers registered. One aspect to consider is only removing the exact handlers you set, like we saw above, but something called "namespacing" is also useful.

Namespacing will let you set listeners on events with custom signatures that allow you to remove listeners that you set, without supplying the function reference. This also means that you can remove or trigger any and all listeners that you set, without fear of touching other listeners.

$("#myButton").on("click.myModule.boo",event => alert("Boo!"));
$("#myButton").on("click.myModule.log",event => console.log(event));
$("#myButton").on("click.myModule.submit",event => $(event.target).parent().submit());

Here you have 3 lines all setting click handlers that does different things. You'll also notice that the event name contains .myModule as well as .boo, .log and .submit in addition to the expected click. This means that all these listener have the namespace .myModule in common, while they have unique namespaces as well. These namespaces are not hierarchical, which means that they can be set in any order, just like CSS class selectors.

If you want to remove the alert triggered on a click you simply use $("#myButton").off("click.boo"). If you have other listeners on the same element listening for different events, but all use the alert handler namespace, you can remove them all in one fell swoop using $("#myButton").off(".boo") without fear of touching any other listener.

Similarly you can use the same technique to remove listeners using the .myModule namespace: $("#myButton").off("click.myModule") for only the click listeners, and $("#myButton").off(".myModule") for all listeners on the button using that namespace.

As you see, the namespace variant allows for a rich set of different listeners and granular control over them. This is extra handy when using delegated listeners, where many things can register to the same object and event. Delegated listeners will be discussed when we talk about using selectors when registering your listeners, but suffice it to say that it's a technique for registering listeners higher up the event bubbling hierarchy.

Selectors and delegated listeners

Registering listeners with .on("event", handler), regardless of using namespaces, requires that the target is already in the DOM. This can be a challenge if you are building your DOM dynamically, and you are not sure when the elements will be loaded with regards to the script setting the listeners. Using delegated listeners solves this by allowing you to register the listener to a high level element that is guaranteed to be done loading when your script runs.

This element can be a container that's a fixed content on the page, like the content container or menu container we loaded our articles and menu into in the Static Blog example, or one of the highest level elements like body or document. You will likely see one huge problem using $("body").on("click.myModule",myHandler). How do you tell one click from another?

Well, sometimes you can inspect the event.target to tell them apart, but you will get the clicks from all elements that emits click-events below the attached-to element in the hierarchy. I'll demonstrate an edge case below that makes event.target blow up.

Using directed listeners you are able to make use of the event.currentTarget to identify the element that triggers the handler, rather than the element which triggered the event, as with event.target, but not so much with delegated listeners. Attaching to the body makes the body be the event.currentTarget. Thankfully jQuery can help us with this as well by filtering out the noise using selectors. Time for some code:

<div>
	<button id="myButton"><b>My Button</b></button>
</div>
<div>
	<form id="myForm">
		<h2>Text form</h2>
		<input type="text" placeholder="Enter your text">
		<input type="submit" value="Submit your text">
	</form>
</div>
$("body").on( "click.myModule.myAlertTest", "#myButton", event => alert("Clicked: " + $(event.target).attr("id")) );

$("body").on( "submit.myModule.myFormSubmit", "#myForm", event => alert("Submitted: " + $(event.target).attr("id")) );

Here we have two examples where we attach the listener to the body and use a selector to identify the element we're targeting. Now, if you run the code provided, you will probably be surprised when you click on the "My Button" button. You would expect this code to alert you with "Clicked: myButton", but in reality, it is alerting "Clicked: undefined".

This is a perfect example of how inspecting event.target falls on its face when the handler is not attached to the first element in the event chain. As you can see the <button> element contains a <b> element as well. This means that when you click the button, the event.target isn't the button, but the <b>l; inside it.

Normally, setting listeners on elements or controls that can contain elements, lets you use the event.currentTarget, but like we discussed earlier, this won't work on delegated listeners, as the event.currentTarget is always the element that triggers the handler.

jQuery to the rescue! Using the selector argument allows jQuery to set the event.currentTarget to the expected value, even if it is a delegated listener. Altering the code above to use the correct property, $("body").on( "submit.myModule.myFormSubmit", "#myForm", event => alert("Submitted: " + $(event.currentTarget).attr("id")) ), makes the alert display as expected.

Well, that was a pretty deep dive into the wonderful world of Javascript events, but it really is just the tip of the iceberg. There are numerous APIs and event types, all with their own quirks, that you should dive into, but that is outside the scope of this guide and relates more to plain Javascript, than to jQuery. We will finish this chapter with another example mini-project.

Login and Signup example

In this section we are going to take a look at possibly the most common page on the entire internet, the login page. Most of these pages would be incomplete without being paired with a signup page with a registration form, so we'll include that as well, mostly because that's where the interesting things happen.

When we get to it, I'll supply the needed code for you to copy and paste. You can also jump here to see a full working example of what we are going to build, as well as visiting the repository on GitHub, if you want to fork the project, or just browse the code as you code it up.

Let us break this up and organize the mini-project a bit before we jump into the code. First, we have to define the scope, the user story, the desired features or what your preferred flavour of project terms are. The point is to determine up-front what is to be built so we can make informed decisions when we plan our code, and it gives us a specific scope and feature set we can work on, check out and be done with.

The two main consepts have already been mentioned: login and signup. Starting with the easiest one, the login page, we need to decide what input we need, how to validate it, where to send it and how things are going to look. Time for a list!

Login

Input / Data

Here we need to figure out what data we need to complete the login transaction. We will keep it simple and skip advanced features like Multi Factor Authentication (MFA), CAPTCHAs, reCAPTCHAs or similar. We'll just use some ID and a secret to verify that the person entering the ID has access to that account, as well as an option to store the ID for future pre-loading.

Data fields
  • E-mail
  • Password
  • Remember me

Validation

Here we need to decide how to do the validation of the ID and secret. Since this is a jQuery guide and not a generic Javascript guide, we'll make this as simple as possible as well, and keeping in line with using modern features, HTML5 will do the heavy lifting for us.

The new <input type="email"> input type has built in validation on form submit. The validation adheres to the RFC specification, which can result in green-lighting some e-mail addresses that you would expect to be blocked.

This is really not an issue since you should always use validation on the server to accept the e-mail address or not, while using validation on the client as a useability helper for the users, pointing them in the right direction when they mistype or when a user without technical knowhow tries to game the system.

Target / Receiver

For this project, we will actually not be sending the form anywhere. We will just implement an alert for when the form is submitted, in place of an actual submit handler that would do your AJAX magic or actual submission.

Design

We'll cut some corners here as well. This is not a design or CSS guide, so you will be provided with a finished CSS file to use, but most of the styles are borrowed from a Bootstrap 4 form example. We will actually use Bootstrap 4 to style everything, except local adjustments and custom components, but we won't explain the actual styling in this guide.

Since the login form will use the built-in HTML5 validation of the e-mail, and since the submission event will just trigger an alert, we have the descriptions, or user stories, we need to build the login form. Since we are going to need a way to show the signup page, we will add a button to switch forms as well.

Signup

The next thing to plan out is the signup form. Here we will have a lot more fun doing some cool things. As with the login form, we need to plan out the inputs, validations, the submit actions and such. The design will naturally be the same to keep with the principle of a consistent, predictable user interface.

Input / Data

As with the login form, we will need the ID and the secret. Here there is no need to "remember me", but we must make sure that the user has no typo in the secret field, as this field is masked from showing the actual text. We'll do this the traditional way, bu making the user type the secret twice. This reduces the chance for typos a lot, as the user is unlikely to repeat the same typo.

Data fields
  • E-mail
  • Password
  • Repeat password

Validation

The e-mail validation will also here be handled by HTML5, but the password will be a combination of custom validation, and HTML5 validation. This is because HTML5 is limited in what it is able to automatically validate for you, like repeated passwords, or determining the strength of a password.

Data validation
  • The e-mail will be handled by the HTML5 built-in functionality like in the login form.
  • The password validation consists of two parts. First we need to validate complexity rules, and secondly we need to make sure both passwords match. Password complexity rules are the rules that make you have to use a mix of upper and lower case letters, numbers and symbols. We'll skip the symbols to keep the pattern simple.
  • As a bonus, we will also include a password strength meter with some tips as to how to make your password better, if it scores low. This will not be linked into the submission handler in this demo, but that would be one of the best places to hook it in if you were to use it as a check for allowing only good passords.

Target / Receiver

We'll cut the corners again with this form, displaying only an alert on submission, as before.

Design

As stated above, we'll keep this identical in look and feel to the login form.

Ok, now that we have a high level game plan, we can start setting up our code.

Files

Ok, we are going to create some files, and download some files. We are using some third party libraries for this, so we can start pulling those down. We'll also download the images and the stylesheet. I've linked directly to the raw GitHub files below, so be sure to right-click or control-click to save the files.

This will be a very small project, so I've not bothered with folders. Just collect the files in the root directory of the project folder you will create to hold the files we will use for the demo. We will also create two blank files, also in the root folder:

  1. index.html
  2. app.js

Skeleton HTML

First we will fill the HTML-file with some basic markup to hold our code, link in the libraries and set up the header. Just copy paste the code below into the index.html file.

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<meta name="description" content="Example login / signup page">
		<meta name="author" content="Morten Olsrud">
		<link rel="icon" href="favicon.ico">

		<title>Example login / signup page</title>
		<link href="bootstrap.min.css" rel="stylesheet">
		<script src="jquery-3.2.1.min.js"></script>
		<script src="zxcvbn.js"></script>

		<!-- Some custom CSS to pull it all together -->
		<link href="signin.css" rel="stylesheet">

		<!-- Our Javascript goes in here -->
		<script src="app.js"></script>
	</head>

	<body class="text-center">
	
	<!-- CONTENT COMING HERE -->
	
	</body>
</html>

Most of this is pretty standard skeleton setup stuff setting view port dimensions, SEO description, author and setting up the favorites icon. In addition to this, you can see we have set at title for the page, added the CSS files, added the JS libraries and the app.js file we are creating.

The rest of the HTML will go into the body tag where the <!-- CONTENT COMING HERE --> comment resides.

Login

Let's start with the login form, as that has the least bells and whistles attached. Add the first form tag to the body.

<body class="text-center">
	<form class="form-signin" id="formSignIn">
		<!-- CONTENT COMING HERE -->
	</form>
	<!-- SIGNUP COMING HERE -->
</body>

Add a title and the logo:

<img class="mb-4" src="logo.png" alt="logo">
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>

Still not much to describe, so we'll just continue with the inputs and the checkbox. The inputs have labels in the markup that you will not see on the page. They are styled to only be "visible" for screen readers, and are not meant to be seen, only heard.

<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required>
<div class="checkbox mb-3">
	<label>
		<input type="checkbox" value="remember-me"> Remember me
	</label>
</div>

Ok, that was a bigger chunk. As you can see, two of the label tags have the class sr-only attached, to hide them from all but screen readers. Next you can see that we have three input tags. One is of type "email", one is "password" and one is "checkbox". The two text-inputs have the normal placeholders, IDs and a class for styling them as form-controls.

In addition, they have the boolean attribute required. This is where the HTML5 magic kicks in. Just by including this attribute like this, tells the browser to demand the user to fill the input with something. It does not tell the browser what to fill it with, so this could be anything other than a blank string.

You can also see that the e-mail field has the attribute for autofocus. This just tells the browser to put the cursor in that field when the page loads. In the past, you would do that manually in Javascript.

Now, just below the previous block, enter the following to finish our form.

<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<div class="registerSection">
	<p class="mt-5 mb-3">Don't have an account?</p>
	<a href="#formSignup" class="btn btn-lg btn-primary btn-block btnToggleForm">Register now</a>
</div>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>

Right! Here you first see the button that submits the form, before a section with a paragraph and an anchor tag. Lastly a simple footer paragraph. The one to notice here is of course the anchor tag. Like we did in the "Static Blog Example" part, we are going to use the hash of the URL to determine which form to show.

Looking at the page now should allow you a peek at the finished product, though not fully functional. Next we will cover the registration form, where all the bells and whistles are.

Register

Since a lot of the code for the registration form is very similar to the one we have already seen, I'll just post the entire block below, and we'll talk about the differences.

<form class="form-signup" id="formSignup">
	<img class="mb-4" src="logo.png" alt="Logo">
	<h1 class="h3 mb-3 font-weight-normal">Please register below</h1>
	<label for="inputEmailSignUp" class="sr-only">Email address</label>
	<input type="email" id="inputEmailSignUp" class="form-control" placeholder="Email address" required autofocus>
	<label for="inputPasswordSignUp" class="sr-only">Password</label>
	<div id="pwdContainer">
		<div id="passwordInfo">
			The password requires numbers, upper and lower case letters as well as a minimum length of 8 characters.
			<meter id="pwdStrengthMeter" max="4" min="0" low="1" high="2" optimum="4"></meter>
			<p id="pwdStrengthText"></p>
			<p id="pwdStrengthTextHelper"></p>
		</div>
		<input type="password" id="inputPasswordSignUp" class="form-control" placeholder="Password" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" required>
		<label for="inputPasswordSignUpRepeat" class="sr-only">Password again</label>
		<input type="password" id="inputPasswordSignUpRepeat" class="form-control" placeholder="Confirm password" required>
	</div>
	<button class="btn btn-lg btn-primary btn-block" type="submit">Register</button>
	<label>
		<p class="mt-5 mb-3">Already have an account?</p>
		<a href="#formSignIn" class="btn btn-lg btn-primary btn-block btnToggleForm">Sign in</a>
	</label>
	<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
</form>

As you can see, the first part of the form is the same, showing the logo, a few labels, some text and the e-mail field. The interesting parts start with the <div id="pwdContainer">. Inside the div you will see another div. That inner div will float beside the password fields, showing information about the password you are entering.

The password info float will only appear when the password field has focus. It contains some text, a meter element and a couple of empty p tags. The next thing to notice is the password fields.

The main password field has a pattern attribute which holds a RegEx for enforcing password complexity, pattern, composition or what ever you want. The given RegEx, (?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}, uses a special grouping feature called positive lookahead, which allows you to define complex rules which otherwise might be impossible.

This particular one enforces that you use at least one digit, (?=.*\d), one lowercase letter, (?=.*[a-z]), one uppercase letter, (?=.*[A-Z]) and a minimum of 8 characters, .{8,}. I can recommend looking up positive and negative lookahead and lookbehind if you want to gain a new dimension to your regular expression game.

The next password field is the one you repeat the password entered in, to make sure you are not setting a password with a typo. This is to ensure that you do not lock yourself out of your newly created account.

The "Register" button is the next element you will see in the code. There is not much to it, other than it being a button element with a type of "submit", rather than a traditional <input type="submit">. It's regarded best practice, at least when using Bootstrap 3, to use button, as there are rendering differences in different browsers.

Other important differences are that button, which is not a self-closing element, supports HTML content, images and aria attributes for accessibility.

Next up comes a label wrapping HTML content for easier styling and grouping. Inside it is some text and the button-styled link which switches between the forms.

Finally there is a copyright-footer to finish off the form. Now, before we move on to the Javascript code, I want to talk a bit more about the password info float, and its role.

Password Info Float

The password info float will be show when the main password field gets focus, as mentioned above. It will also hide when the main password field looses its focus. This will be achieved with event listeners reacting to the blur and focus events.

The text describes the password complexity rules implemented in the RegEx, and is crucial for the user to see, or else they will likely not enter a correctly composed password.

The meter element is new in HTML5, and is intended for progress bars and similar visualisations of ranges, scales and fullness. It has a max and a min attribute for defining the beginning and end of the range. It also has attributes for the thresholds where the color changes, as well as an attribute for setting the optimum value.

The meter will be used for indicating the strength of the password in the main password field. This will be calculated using a 3. party library developed by DropBox called "zxcvbn". The name plays on the pattern matching it does to detect keyboard mashing, tracing and a list of the most common passwords in english. Since we are supplying it with our passwords, it is important to have full control of the library, using only known safe versions, hosting the file with our other static files.

The library takes the password as input, and return a value from 0 to 4, where higher is better. This is reflected in the attributes on the meter, where the min is 0, the max and optimum is 4, and low and high thresholds as set to 1 and 2 respectively.

Another thing the library gives us is a text message to show the user, hinting at what needs to be improved in the password to make it stronger. This message will be displayed in one of the empty paragraphs. The other empty paragraph will display a textual representation of the strength, rather than showing a number no-one understands.

And now, it is finally time for some Javacript code.

Adding the Funk in functionality

Open your app.js file in your editor and start by filling it with the self-executing on-load function we've seen a few times now. We'll add the content in steps, explaining each piece of code as we go along. After adding the code below, I'll assume that you are inserting the rest of the code we are going to discuss, into that function.

$(()=>{
	// Add content here...
});

Ok, the first thing we are going to add is the functionality to switch between the forms. The buttons we added to the forms for going from login to signup, or vice versa, are missing their event handlers.

$(".btnToggleForm").on("click.formNavHandler",()=>{
	$("form").toggle();
});

That's it! As you see, we are using some ES6 to keep it short, but if you are aiming for the broad audience with the older browsers, you might need to settle for the long form, or see if you can use a polyfill to add the missing support. Another option is to use a build pipeline with systems like webpack with babel that can automatically convert your code from ES6 to an older version.

First, the selector we are using is a CSS-class that we have only on these two buttons. That is used to get the two forms, and set the same handler on both of them. The handler we are setting is the expected click handler, and we are setting it namespaced, just to help form good habits.

The action it performs is simply to call toggle() on both forms at the same time. Since one form is default hidden, and one is default shown, this makes them inverse their states. This means that the visible form becomes invisible, and the invisible form becomes visible.

Had this been a larger site with more forms, you would have to use a more specific selector that form to select the form to toggle. One suggestion would be to latch on to the identical parts of their unique classes. form[class^='form-sign'] is an elegant solution to that, given the classes used in the example.

Next we are going to add the functionality that makes the password info float fade in and out.

$("#inputPasswordSignUp").on("focus.pwdInfo",()=>{
	$("#passwordInfo").fadeIn();
});

$("#inputPasswordSignUp").on("blur.pwdInfo",()=>{
	$("#passwordInfo").fadeOut();
});

Here you can see that the inputPasswordSignUp password field, our main password field, is given two event handlers. The event focus is triggered when the password field is given the cursor. Clicking inside it, tabbing to it or triggering the focus() function will all do this.

The other event handler is the inverse, blur. This is triggered when you click outside, tab away, when the blur() function is called, or when focus() is called elswhere.

The action performed is simply to have the info box fade in or out using jQuerys fadeIn() and fadeOut() functions.

Next we simply have a dummy event handler for displaying an alert when either form submits. This would naturally be substituted by an AJAX-call to the back-end or a full page-reloading form submit.

$("form").on("submit.submissionHandler",()=>{
	alert("Submit!");
});

The next part, we need to split up a bit, as it is a bit long. I've opted not to refactor it into separate functions as is normal for lengthy functions, because I wanted to keep the code relating to this handler in only one place. As you will see, the code is pretty simple, mostly an if statement, it just takes up some space when it is properly formatted.

$("#inputPasswordSignUp").on("input.pwdStrength", ()=>{
	var strength = {
		0: "Worst",
		1: "Bad",
		2: "Weak",
		3: "Good",
		4: "Strong"
	};

	var val = $("#inputPasswordSignUp").val();
	var result = zxcvbn(val);

	// Update the password strength meter
	$("#pwdStrengthMeter").val(result.score);

	/*
	* Insert next part here
	*/
});

Here we are adding another event handler to the main password field. The oninput event is fired when the content of an <input> or <textarea> is changed. The difference between oninput and onchange is that oninput is fired for every change, immediately, while onchange is triggered only when the element looses focus.

Up next is a simple value map, translating the values we will receive from zxcvbn, the JavaScript library we are using to gauge the strength of the password. Then we get and store the value of the main password field, before we feed the value to zxcvbn and store the result.

The final thing we do before pasting in the next part, is setting the meters value to be the score of the password strength test. This makes the bar in the meter adjust its coverage area to indicate the numerical value.

The next part you are to insert where the comment indicates it, inside the function.

// Update the text indicator
if (val !== "") {
	$("#pwdStrengthText")
		.text( "Strength: " + strength[result.score] )
		.show(); 

	if(result.score <= 2){
		var msg = result.feedback.suggestions.join("<br>\n");
		$("#pwdStrengthTextHelper")
			.html(msg)
			.show(); 
	}
	else {
		$("#pwdStrengthTextHelper")
			.text("")
			.hide();
	}

} else {
	$("#pwdStrengthText")
		.text("")
		.hide();

	$("#pwdStrengthTextHelper")
		.text("")
		.hide();
}

As you can see, this is really just a big if-statement. First make sure that the value is not a blank string, i.e. empty field. If it is not, then set the text in the pwdStrengthText element to display the string "Strength: " combined with the textual representation of the score, looked up in the value map, and then show the element.

If the score is less than or equal to two, we will also display the feedback from the zxcvbn-library that gives tips on what to improve in the entered password. If the score is higher than two, just make sure the element does not contain old text, and hide it.

If the value of the password field is a blank string, there is no strength to show, nor any helper message. Just hide the elements. That concludes this function. The next piece of code is a separate function, but still a part of the self-executing outer function.

$("#inputPasswordSignUpRepeat").on("input.pwdValidator", ()=>{
	var $pwdRepeat = $("#inputPasswordSignUpRepeat");

	if( $("#inputPasswordSignUp").val() !== $pwdRepeat.val() ){
		$pwdRepeat[0].setCustomValidity("Your passwords do not match.");
	}
	else {
		$pwdRepeat[0].setCustomValidity("");
	}
});

This final piece of functionality focuses on making sure that the password and the repeated password matches. There are probably as many ways to check this as there are developers in the world, but I wanted to yet again demonstrate some HTML5 functionality.

The event we are hooking into, is yet again the oninput event, but this time on the password repeat field. I also want to point out that this demo is not made to cover all edge cases that a user might throw at you. Simply filling in the password field in reverse order, tends to throw a wrench in most sites password check machinery. Also another reason to always validate the data on the server.

The interesting part here is the setCustomValidity() part. If the passwords does not match, we call the setCustomValidity() function with the message you want to be displayed. This is then displayed in a native browser information pop-over next to the repeat password field, but only when the form is submitted.

Please note that the setCustomValidity() function is a method on the HTML5 element, not the jQuery object, thus the $pwdRepeat[0] bit to access the raw element that the jQuery-object represents.

One quirk I've seen with this approach, is that after the form submission is attempted and fails, the browser displays each time we set it, and remove it when the passwords match.

The end is nigh

I hope you were able to keep up and make the sample work as expected, but if you did not, I recommend that you download the full code from GitHub and compare it to your code. I'll see you in the next part.

Authenticating with AJAX and JWT

Now it is time to take a look at how one can use all we have learned so far, to do some complex authentication. It will involve the $.ajax() method from jQuery, since we will need to edit the HTTP-headers we are sending to the server.

We will also be taking a quick look at some useful libraries that will help you encode, encrypt and sign data for safe transfer over the ever more hostile internet. Now, the sources for this project are somewhat big and complex, including a server side part written in NodeJS, and we will not cover everything in detail, as there are many things that are outside the scope of this guide.

To save some time and explanation, I have based the example on the previous login and signup example, using that project as a basis for further learning about authentication in an async world. I will also provide the server script, and tell you how to run it, but I will not step through that code, as it does not contain any jQuery, though I might a later date write a separate post going through that code.

Feel free to look at the server code, use it and learn from it, but be aware that it is by no means production ready. I have taken some shortcuts and skipped A LOT of error checking and handling. I have also completely skipped over unit testing, build tools and using the package.json correctly.

As usual, I have created a repository you can visit to get the full, working code here. Now, as I said, I have based it on the Login / SignUp example, but there are changes made to the code, so I would recommend that you create a new project folder to host this one in.

To set up and run everything, we are going to need NodeJS and NPM installed. If you are unsure if you have them or not you can run the following in your terminal to see.

	node -v
	npm -v

If you need to install the software you can go to their homepage to get the binaries or find instruction on how to install from a package manager. Visit them here. Once you have a recent version installed, you can continue with the example.

The setup

To get started you need to download some files. Start by creating or navigating to the folder you will use as the project root folder, and download the ZIP-archive here. Unzip the archive into your project root folder using your favourite unarchiver. The following should be what your filestructure looks like now:

project root/
	templates/
		account.html
		index.html
		login.html
		settings.html
	
	www/
		jquery-3.2.1.min.js
		bootstrap.min.css
		favicon.ico
		logo.png
		zxcvbn.js
		signin.css
		sha256.min.js
		Base64.js
	
	server.js

The last thing to do before we start creating the last files, is installing some dependencies for the server using npm, the package manager for NodeJS. Standing in the root of the project folder in your terminal, run the following commands in your terminal to fetch these files.

	npm init

The above will start a wizard asking you some questions about the project. Just answer to the best of your abilities. The default answer can very often be used.

	npm install crypto-js express body-parser --save

And this is the command that installs the dependencies for the server. Notice the --save at the end. This tells NPM to add entries for each in the package.json file you now have in your root folder. Like I mentioned earlier, I have not used the package.json file to its full abilities in this example, and also I wanted to allow you to create and populate it yourself.

The last thing you need to do before we start writing some code, is creating two blank files inside the www folder. Authenticator.js and app.js must be the name of them, as the other code points to those names.

These files will be filled with a lot of code, some more interesting to examine than other, but as usual, we will take it step by step for the most part. Some of the code we are putting into app.js is code we have already written in the previous login example, so that is one part we are going to gloss over.

Another thing to notice is that we are only going to work with the login part of the process. We will not be enabling the backend functionality to have the signup form function in this example.

The lay of the land

Now that we have our files set up, we need to go over the game plan, so we know what our goal is in this example.

We are going to use the server.js as our webserver in this example. This file has been set up to server the static files in the www folder just like a regular static webserver. It also serves an API-endpoint at /api/token where we will do the authentication from our webpage.

Looking at your file structure you also see a templates folder. This is the folder where the server.js loads the HTML-fragments it serves you when you navigate the page. This would typically be files using some sort of templating engine like moustache, where the server loads the template, fills it with relevant data regarding you and your current context. For the sake of simplicity, I've let them just be plain HTML-fragments.

I have also made some changes to the code from the previous example on which we are basing this one. The forms that were located directly in the index.html file have been moved to a template file (login.html) and as we'll see later, the app.js file is refactored a bit to accommodate the now logic. This leaves the index.html file as a simple skeleton file containing the projects headers and body tags.

The functionality of the app is tailored towards a type of app that is based on authenticated access only. This can be an app that resides in a sub-domain of a company site, some sort of Software-as-a-Service (SaaS) app or similar, where the actual app is behind a login, while the information about the company, app or service resides elsewhere. This approach was chosen to keep the example small, and is also a typical way to separate "functionality" from "marketing".

With this in mind, you can expect the app to do one of two things when it is loaded:

  1. Show the user a form to login or sign up if the user is not currently signed in
  2. Directly take the user to the page that logging in will take you to, skipping the login, if the user is in possession of a valid token

The app is set up to be a hybrid between the classical server-generated pages, and the modern Single Page Application. It uses both REST API style fetching from the server, as well as session based AJAX page loading using the token. As always, there are almost as many ways to do things as there are developers in the world, and creating examples like these often requires some short-cuts, so please, use the methods demonstrated as guidelines rather than rules.

One thing that will not be demonstrated at this time, is how to use these tokens to sign data passed in REST calls, but it is very similar to the way we sign the data in the login, as you will see later.

The files Authenticator.js and app.js are the ones we will be working with the most, as that is where the magic lies.

Talk to me

Our front-end Javascript code is going to communicate with our back-end using XML HTTP Requests, all nicely wrapped in our friend $.ajax(). We are going to use this function as we need to manipulate the HTTP-headers that the browser is sending to the server, so we can include our tokens, authentication payload and signatures.

The front-end is simply loaded by visiting the root of the site /. Depending on your session state, that is, if you have a valid token or not, a page will be loaded for your viewing pleasure. The page is loaded by ajax-calls to the appropriate endpoints on the back-end, /login or /account. I've also inlcuded a mock page for "settings" so that you can play with the navigation between two pages when logged in.

For the server to be able to tell if you are logged in or not, we are going to include or omit an HTTP-header in our ajax-calls, which will contain the information the server needs to validate our session. We will also set the content type and character encoding of the HTTP requests, as well as what content we accept in return.

This all might sound advanced and hard to do when we talk about it in terms like these, but you will see in the code we use, that it really is not that difficult. When you start making things like this on your own, you just neet to keep a cool head, and be ready to revisit the code numerous times to make adjustments and corrections. There is always an edge-case waiting to happen, and that is just the way these things are.

Well, now that we have a broad understanding of the files, some of the changes from last example and a 10.000 foot overview of the direction we are going, I feel like diving into some code.

The new app.js

First of all we can insert most of the code we wrote for the last example. There is a small change in that it now needs to be inside a function we can call when we are loading the form, and the handler for the form submission has some new content. I'll show you below the wrapper and handler first, so you can understand how it has changed, before I give you a full dump of the wrapped code. Copy and paste the full dump rather than the first block of code.

function loadLogin(){
	.....
	$("#formSignIn").on("submit.submissionHandler", (event) => {
		event.preventDefault();
		var auth = new Authenticator();
		auth.setURI("http://localhost:8081/api/token");
		auth.setUsername($("#inputEmail").val());
		auth.setPassword($("#inputPassword").val());
		auth.authenticate((isAuthenticated) => {
			if (isAuthenticated) {
				globalHeaders["Authorize"] = "Bearer " + auth.getToken();
				saveToken(auth.getToken());
				navigate("/account");
			}
			else {
				displayError("Authentication failed.");
			}
		});
	});
	.....
}

We're just wrapping it in a simple function. We're not even attaching it to an object or anything this time around. Inside that function is where the old code will live, and the function will be called when the user navigates to the login page.

Now the handler is quite exiting. First we stop the normal form submission from reloading the page bu preventing the default action. Then we instantiate a new Authenticator object. We will dive into the code of that after we finish app.js, but you can see the outline of it in use here.

The Authenticator object then gets the username and password from the form before we pass in a callback into the authenticate() method. The callback will get a boolean value for whether the login is successful, and if it is, we add a header Authorize: Bearer [your token here] into the global header object. Then we save the token and navigate to the /account page.

The functions saveToken() and navigate() will be covered soon. Also notice that in the event of isAuthenticated being false, we call displayError().

For now, just copy and paste the code below into the app.js you created earlier.

function loadLogin() {
	$(".btnToggleForm").on("click.formNavHandler", () => {
		$("form").toggle();
	});

	$("#inputPasswordSignUp").on("focus.pwdInfo", () => {
		$("#passwordInfo").fadeIn();
	});

	$("#inputPasswordSignUp").on("blur.pwdInfo", () => {
		$("#passwordInfo").fadeOut();
	});

	$("#formSignIn").on("submit.submissionHandler", (event) => {
		event.preventDefault();
		var auth = new Authenticator();
		auth.setURI("http://localhost:8081/api/token");
		auth.setUsername($("#inputEmail").val());
		auth.setPassword($("#inputPassword").val());
		auth.authenticate((isAuthenticated) => {
			console.log(isAuthenticated);
			if (isAuthenticated) {
				globalHeaders["Authorize"] = "Bearer " + auth.getToken();
				saveToken(auth.getToken());
				navigate("/account");
			}
			else {
				displayError("Authentication failed.");
			}
		});
	});

	$("#formSignUp").on("submit.submissionHandler", () => {
		alert("Sign Up Submitted!");
	});

	$("#inputPasswordSignUp").on("input.pwdStrength", () => {
		var strength = {
			0: "Worst",
			1: "Bad",
			2: "Weak",
			3: "Good",
			4: "Strong"
		};
		var val = $("#inputPasswordSignUp").val();
		var result = zxcvbn(val);
		// Update the password strength meter
		$("#pwdStrengthMeter").val(result.score);
		// Update the text indicator
		if (val !== "") {
			$("#pwdStrengthText")
				.text("Strength: " + strength[result.score])
				.show();
			if (result.score <= 2) {
				var msg = result.feedback.suggestions.join("
\n"); $("#pwdStrengthTextHelper") .html(msg) .show(); } else { $("#pwdStrengthTextHelper") .text("") .hide(); } } else { $("#pwdStrengthText") .text("") .hide(); $("#pwdStrengthTextHelper") .text("") .hide(); } }); $("#inputPasswordSignUpRepeat").on("input.pwdValidator", () => { var $pwdRepeat = $("#inputPasswordSignUpRepeat"); if ($("#inputPasswordSignUp").val() !== $pwdRepeat.val()) { $pwdRepeat[0].setCustomValidity("Your passwords do not match."); } else { $pwdRepeat[0].setCustomValidity(""); } }); }

Wow, that was a lot of code that we wrote in the last example. Good thing we can adhere to a version of the DRY principle, Don't Repeat Yourself.

Moving on, we are going to start fleshing out this application. First we have to set up a global object to hold some headers. Because we, for simplicity's sake, won't wrap our application inside its own namespace nor create a class-like structure like we did in the Static Blog example, every variable declared outside a function is global and under the hood attached to the window object.

var globalHeaders = {
	"Accepts": "application/json"
};		

Nothing much to note here really. It's just an object holding HTTP-headers using the header name as the key. This object will be passed into AJAX-calls when we are doing server communication. It will also get more headers dynamically as we log in.

When we get to the login logic, you will see that we are going to store the token we get from the server, and to do that we are going to use the browsers built-in storage API. To demonstrate support for older browsers, we are however going to include a fallback mechanism for using cookies in place of the modern Local Storage.

function setCookie(cname, cvalue, exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires="+ d.toUTCString();
    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

function getCookie(cname) {
    var name = cname + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for(var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

Both these functions are pretty well documented on the web, as they are a pretty standard way to handle cookies, and cookies are a small writeup in their own, but suffice it to say that cookies are stored by the browser as small text-files per domain that are sent to the server for each request. The cookies are comprised of several key-value pairs containing information about the cookie name, expiration, path and data, all concatenated into a long string.

The document object gives you access to the cookies as that one long string, so one needs to split and parse the string manually. Whenever you need to work with cookies, just copy and paste these pre-written helper functions to make your life a whole lot easier.

Next we need some error-handling, but for this example, this boils down to a simple alert. Inside the following function, you would write some logic to display the error in a pretty way in your GUI for the user to see. This would also be where you have the logic to "de-techiefy" the error messages that sometimes can be quite technical. Your users like to see errors like "We're sorry, there seems to be no hamsters in their wheels at the moment. Please try your request again." or some other slightly humorous message.

function displayError(error){
	// Normally display this in a modal or
	// other UI element on the page.
	alert("Error:\n\n"+error);
}

I told you that we are going to store our tokens in the browser. To do so we need a way to set, get and delete the tokens. We will use functionality detection to determine if the browser supports Local Storage, and if not, we will use the cookie-helpers we glossed over earlier. These methods are very similar, so I'll just show them all together.

function deleteToken(){
	if( typeof(Storage) !== "undefined"){
		localStorage.removeItem("jwtToken");
	}
	else {
		setCookie("jwtToken","",-1);
	}
}

function saveToken(token){
	if( typeof(Storage) !== "undefined"){
		console.log("setting token in localStorage");
		localStorage.setItem("jwtToken", token);
	}
	else {
		console.log("setting token in cookie");
		setCookie("jwtToken",token,30);
	}
}

function getToken(){
	if( typeof(Storage) !== "undefined"){
		var value = localStorage.getItem("jwtToken");
		if(value !== null){
			return value;
		}
		return "";
	}
	else {
		return getCookie("jwtToken");
	}

}

As you can see, all the functions start with the feature detection to see if the browser has the object Storage. If it does, then the browser will also have the localStorage object, which we will use. It is a simple key-value store, delivering on the shortcomings of the cookies.

If we start with the simplest one, deleteToken(), you can see that a simple call to localStorage.removeItem("name_of_item") will delete the pair. Similarly in saveToken() you see that localStorage.setItem("name_of_item","value") stores a pair, creating it if it does not exist, updating it if it does.

Getting the item is similarly simple, but here we might run into trouble as the value could be null if the item does not exist. A simple check for this, returning a blank string in its place if it is indeed null, saves us some potential grief.

Notice the Cookie helper functions used if the check for the functionality fails. In the deleteToken() function you can see that we are setting the cookie to have no data and a negative expiration. This is what deletes cookies.

function logout(){
	delete globalHeaders["Authorize"];
	deleteToken();

	navigate("/");
}

Logging out is pretty simple though. Just delete the token, the header and navigate to the front page.

function navigate(dest, callback){
	// Normally do some sort of navigation
	$.ajax({
		url: dest,
		headers: globalHeaders
	})
	.done( (data, status, xhr) => {
		console.log(data);
		$("#body").html(data);
		if(typeof(callback) !== "undefined" && callback !== null){
			callback(data);
		}
	})
	.fail( (xhr, status, error) => {
		console.log(error);
	});
}

Navigating is done simply by loading content over AJAX. Notice here that we use the globalHeaders object as a part of the $.ajax()-options object. When we are logged in, this means that the token is sent along with each navigation request. If we are not logged in, no token in sent. The data we get back from the server is then loaded into the page as HTML data.

Remember to be careful using .html() for loading stuff into your page, as that might get you in trouble if you can't 100% trust the data you get. All data from users, stored in a database, accessed over a REST API or something, is potentially harmful. Hackers are very creative in ways to get you to display and run their code in your visitors browsers.

And finally, the last piece in this puzzle, the function running when the DOM is ready.

$(()=>{
	var token = getToken();
	console.log("token",token);
	if(token !== ""){
		globalHeaders["Authorize"] = "Bearer " + token;
		navigate("/account");
	}
	else {
		navigate("/login",loadLogin);
	}
});

This is also pretty simple stuff, now that you have seen the rest of the code. First get the token. If that is not blank, we add the token to the headers and navigate to the /account page which requires the user to be logged in.

If the token is blank we just navigate to the /login page, while supplying the callback to run when the page is loaded and the new parts of the DOM is ready. In this case, that is the code for setting up the login form.

This pretty much covers the entire experience and functionality, but since we are going to go a bit deeper into JSON Web Tokens, we are also going to peek under the hood of Authenticate.js.

Authenticator.js

The Authenticator.js object is really not so special. It's just an object with prototypes declared, as we've seen before. I've as usual written it using some of the ES6 functionality, which solves some small annoyances in our use case. Let's start by digging into the constructor.

var Authenticator = function(){

	var _username = "";
	var _password = "";
	var _token = "";
	var _uri = "";
	var _isAuthenticated = false;

	return this;
};

Nothing special going on there. Just some variables for holding state later on. As you can see, I've opted to name my variables with a leading underscore ("_"). This is a convention used by many, in many languages, to indicate that the variable is internal and should only be touched by the appropriate functions or method on the object. There are some hoops you can jump through to get truly private variables, but that's outside the scope of this example.

Seeing as we have a lot of "private" variables in the constructor, we need some way to access them, and that means getters and/or setters for the variables that are to be accessible.

Authenticator.prototype.setUsername = function(username) {
	this._username = username;
};

Authenticator.prototype.setPassword = function(password) {
	this._password = password;
};

Authenticator.prototype.setURI = function(uri) {
	this._uri = uri;
};

Authenticator.prototype.getToken = function() {
	return this._token;
};

Authenticator.prototype.isAuthenticated = function() {
	return this._isAuthenticated;
};

As you can see, we actually won't need getters and setters for all the variables. We need to be able to set the username and password, as well as the address for the JWT API we are authenticating to. If you remember in the App.js file, we used .getToken() to retrieve the token from the Authenticator object, as well as .isAuthenticated() to check login status.

Salt 'n Pepa!

Now the next thing we are going to take a look at is the salt generator. A salt is typically a random string of characters, and it is used together with the password to create the password hash. If you don't use a salt or other means to help mask the password, the same password will become the same hash when it is hashed with the same algorithm.

What this means is that if I take the 10.000 most common passwords in the world, and hash them on my computer using the same hashing algorithm that you use, I can recognize the password of your users if I eaves-drop on your communication or if I hack your site and steal your database. I can also try to use all 10.000 hashes against your site, unless you block users after 5 failed attempts or other similar safe-guards against password guessing.

In real life, hackers have made millions of pre-hashed passwords that they store and use in attacks. This is referred to as Rainbow Tables, and one of the best ways of defeating this method of attack, is using salts as a part of your passwords. You store the salt and the hash in your database, not the password.

In this example we have taken a small short-cut in the server code by hard-coding a sample user with a plain text password, as the full method of hashing and storing in a database is out of scope. A quick search on Google should reveal a few thousand, if not million, hits on the subject of hashing with salts and storing in the database.

Now that we have covered what a salt is, let's see how one can generate one.

Authenticator.prototype.generateSalt = function(size) {
	let choices = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_";
	let buffer = [];
	while(size--){
		buffer.push(choices[Math.floor(Math.random()*choices.length)]);
	}
	return buffer.join('');
};

generateSalt takes one parameter that indicates the length of the salt you want to have generated. Inside the function you can see that we have a long string with all the valid characters we allow. They are a variant of the base64 character set, using all upper and lower case ASCII alphanumerical characters, as well as "-" and "_", which makes for 64 characters.

Then we just loop the specified number of times, each time picking a random character from the string, and pushing it into the buffer array we declared before the loop. Finally we just return the resulting string that we get when we join the buffer array together with no delimiter.

Time for some token generation.

Authenticator.prototype.generateJWT = function(username, password) {
	var header = {
		"alg" : "HS256",
		"typ" : "JWT"
	};

	var encodedHeader = Base64.encode(JSON.stringify(header));

	var payload = {
		"sub" : username,
		"salt" : this.generateSalt(10)
	};

	var encodedPayload = Base64.encode(JSON.stringify(payload));

	var signature = Base64.encode(sha256.hmac(
		payload.salt + password, 
		encodedHeader + "." +
		encodedPayload
	));

	return [encodedHeader,encodedPayload,signature].join('.');
};

Ok, that looks like a lot, but there is not much going on. We are only constructing two Base64 encoded objects and a Base64 encoded hashed signature. The first object is the header in which we define the hashing algorithm to be used, as well as the token type. Then we simply use the Base64-library we included in our HTML-headers to encode a JSON representation of that header.

The next bit is doing the same with the payload. That is the data we want to transfer to the server. In this case, that is the username and the salt we are generating. Often you will need to ask the server for the stored salt, as that has been combined with the password before hashing, which means you cannot recreate the same hash without the correct salt.

The signature is where we do our hashing, and the js-sha256-library comes to our rescue here. We are using the .hmac(...) method which takes the secret to be used as the key for hashing, as well as the data to be hashed. The secret is a string concatenation of the salt and the password. Finally we just return the encoded header and payload along with the signature in the JWT string format, separating them with dots, ".".

The crux of the matter

And it's time for the grand finale of the Authenticator.js!

Authenticator.prototype.authenticate = function(callback) {
	var data = this.generateJWT(this._username, this._password);

	$.ajax({
		url: this._uri,
		method: "POST",
		headers: {
			Accepts: "application/json"
		},
		data : data,
		processData: false,
		contentType: "application/jwt; charset=UTF8"
	})
	.done( (data, status, xhr) => {
		this._token = data;
		callback(true);
	})
	.fail( (xhr, status, error) => {
		callback(false);
	});
};

As you can see, there really isn't much magic to this either. We generate the data to send by generating the token, using the generateJWT method, which we just covered. We supply that with the username and password and store it in a variable.

Then we just call $.ajax(...) with the data, the URL of the authentication server and a few other settings. We add a header to indicate what type of data we accept in the response, as well as the content type we are sending to the server. The content type is application/jwt, as that is set up on our server to ensure correct body-parsing. For the body to not be adjusted or processed we also include the setting processData: false.

When the AJAX call is done, we store the token we get back, as that is the server generated token that corresponds to our "session", and that we will pass to the server with each subsequent request. We then call the callback with true as the parameter to indicate that we are indeed logged in.

Should there be a problem and an error is returned, we indicate this by calling the callback with false as the parameter.

Summa summarum

In this part we have seen some more advanced techniques in how we communicate with the server, as well as some more advances concepts and patterns of web development and Javascript. JSON Web Tokens are but one token scheme, and as you see in our run through here, there will always be some variations as to how to use the token itself, as this is not written in the JWT spec.

Full authentication schemes like OAuth2 specify in detail how the flow of data should go, how it should look, and is much more than just a token scheme like JWT. It's a protocol in it's own right. The JWT token generation spec does bring a lot of value, as it creates a standard in how one can generate the tokens, but leaves it up to the developer how he or she will use the tokens.

AJAX Form submission

I touched the function .serialize() during an example demonstrating $.post(), and now we will take a closer look at it. It was originally created during a time when the FormData API was either non-existant or very poorly supported. It was a great way to easily gather up all the data from a form in a time when you needed to support older browsers than IE10.

The reality today is that you have a vanilla Javascript alternative in the FormData API, which for some use cases actually is better and has more functionality. However, when you are committed to jQuery, and you have normal, simple forms you need to work with, .serialize() is still a great tool. Just don't load up jQuery for only that feature.

I didn't have a difficult use case, and being a jQuery guide, I have updated our ongoing project to complete our sign-up form. The server code has been enhanced to naively accept signup requests, adding new users to the in-memory object storing the users. Server-restarts deletes all new users, leaving only the user@example.com that's hard-coded.

The starter code is the finished working code from the last section, found here. The complete working code can be found here. A working live example of the entire finished project, including the server, can be seen hosted on my account at Glitch.com, here.

In our app.js have edited the submission-handler and added a function to do the actual submission.

$("#formSignUp").on("submit.submissionHandler", function(event){
	submitAjaxForm(event, (data)=>{
		alert("Sucess! Please log in below now!");
		$("form").toggle();
		console.log(data);
	}, (data)=>{
		alert("An error ocurred. Please try again.");
		console.log(data);
	})
});

As you can see, the handler basically only calls the submission-function, and I could have easily combined the two of them into one block of code, but I wanted to create the submission-function in a more reusable way, and leave the possiblility open to use it for submitting other forms.

This particular demo project will not have a need for that, but small things like this makes your systems much easier to expand later, and thus more maintainable. Now it is important to not fall into the other extreme of over-optimizing and over-architecting your system. Then you will spend all your time performing premature optimization, and not enough time getting the features out the door.

Another thing to notice is that I let the submission-handler deal with the code that gets triggered on successful or erroneous submissions and sign-ups. Let's take a look at the function sending the form.

function submitAjaxForm(event, success, error){

	let url = $(event.target).attr('action');
	let data = $(event.target).serialize();

	$.ajax({
		type: "POST",
		url: url,
		data: data,
		contentType: "application/x-www-form-urlencoded; charset=utf-8",
		success:success,
		error:error
	});

	event.preventDefault();
}

Here you can see that the function accepts three parameters, event, success and error. We give it the event object so that it can dynamically discover which form it needs to work on. We also give it the two callbacks we defined in our handler.

First you can see that we take the $(event.target) object's action attribute and store it in a variable. The form's action attribute tells us what the URL we need to send the form to.

Next up we use the .serialize() method to have our form data extracted and compiled into an URL-encoded querystring. The string will look something like field1=value1&field2=value2.... It's important to remember that the .serialize() function only recognizes form-fields that have the name attribute set. If it is missing, then the method skips the field.

Another thing to note, is that it does not handle files being uploaded, at least not without some hoops being hopped through. IF you need to upload files, and don't have to support really ancient browsers like IE9 or below, you should use the FormData API to handle your form.

In our $.ajax() call we set type to be "POST", define the URL, append the data we serialized and we set the header for defining the content type to signal that we are sending x-www-form-urlencoded data. Add the callbacks, and finally tell the event not to perform the default action of posting the form with a page reload.

The server will now take this data, parse it, check to see if the user exists and react properly. If the user exists, it will return a "HTTP 409 Conflict" status code, indicating a conflict. If the user does not exist, it adds the user to memory and returns a "HTTP 200 OK" status code. You will then be redirected to the login-form to log in. Doing so with the new credentials will send you to the mock account page.

Rounding up AJAX

We have now completed the AJAX project, demonstrating a simplified, yet still real-world-ish example of a page with a login-flow and some security features like JWT. There are many things to consider in the actual code you put into production, and I certainly haven't covered all of them here, but what little I did manage to display, I hope you will find value in some time.

It's the end of the world as we know it

I would like to thank you for following along, reading our tips, tricks and rants throughout this guide. We started on a very basic level, first covering the 10.000 foot picture of jQuery before we dove into many of its useful functions and features. We finished off with some more complete examples and projects showing a bit more than the distilled jQuery part that covered only one function.

There are many powerful frameworks out there, doing a lot of good for a lot of people. jQuery is one of the largest still, even facing fierce competition from the ultra-popular frameworks like React, Angular, Meteor and Vue. In fact, jQuery can be a companion for many frameworks, and sometimes the frameworks themselves use jQuery under the hood.

I really hope this guide could be of some help, inspiration and guidance. I know we have really enjoyed our time together and I hope to see you again in another.

{ 4 comments… add one }
  • Victor G. February 17, 2018, 8:17 am

    hi Trev, you have been so resourceful in my journey of learning how to program. Thanks big for your nice way of breaking down concepts!

  • Victor G. February 17, 2018, 8:59 am

    Hi Trev. Thanks much for your generous way of teaching. I have learnt a lot about programming through your posts. Live long and keep up the good work!!

  • Victor February 17, 2018, 10:59 am

    Thanks Trev!!!!

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.