jQuery

Begin Programming with JavaScript jQuery

Text Version

A library is a set of custom functions or objects written and shared by other programmers. You can connect a library to your code like a plugin, and use it to make your life easier as a programmer.

In this chapter, we’ll look at how to use a very popular library called jQuery. It can simplify our JavaScript code.

Installation

Make a new copy of the chapter-8 folder, and rename it to chapter-9:

chapter-8
chapter-9

We’ll build on top of the HTML program from the previous chapter.

To install the jQuery library, add a new script element right before the existing one:

...
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="main.js"></script>
...

unpack:

If you visit the link in a browser, you should see a page full of JavaScript code.

The new script element has to come before the main.js script element because the code in main.js will depend on jQuery.

This new script element connects to the URL and downloads the code into our HTML page, then the jQuery code will be available to use in main.js.

And that’s all the installation we need.

the $ function

Now we can use jQuery to get an element without using document.getElementById.

Before
let output = document.getElementById("output");
let textbox = document.getElementById("textbox");
let submitButton = document.getElementById("submitButton");
After
let output = $("#output");
let textbox = $("#textbox");
let submitButton = $("#submitButton");

unpack:

The $ is the name of the main jQuery function. And $ is a valid variable name.

The # sign is telling jQuery that we are referring to an element by id, There are other ways to get an element without using id, as we will see in a bit.

The objects returned from the $ function is different from the original object we got from getElementById. These new object come with different methods, such as on, val, and html. We will have to modify the code to use the new methods.

↓ We have to make three changes. Instead of using addEventListener, we have to use on to add an event handler.

// CHANGE 1
submitButton.on("click", function(){
  ...
});

↓ And instead of using the value property and the innerHTML property, we have to use the val() method and the html() method.

submitButton.on("click", function(){
  let userInput = textbox.val(); // CHANGE 2
  let inputItems = userInput.split(' ');

  let sum = 0;

  for(let i = 0; i < inputItems.length; i++){
    if(!isNaN(inputItems[i])){
      sum = sum + parseInt(inputItems[i]);
    }
  }
  output.html("The sum is " + sum); // CHANGE 3
});

CSS and Animate

So far jQuery has only been helping us to write shorter method names. It can do much more than that.

For instance, we can add animation effects to an element to make it fade in and fade out. We can hide the output element first, and fade in when the user clicks the submit button.

First, we have to make the output element invisible by default. We can use CSS for that. CSS stands for Cascading Style Sheets. It’s a language used for making HTML user interface more presentable.

<!DOCTYPE html>
<html>
  <head>
    <style>
      #output {
        display: none;
      }
    </style>
  </head>
  <body>
    ...
  </body>
</html>

unpack:

We’re using a style element inside the new head element.

↓ The head element is for non-visual elements. When you put an element in the head, it will not show up in the web page. The style element and the script element are among some of the non-visual elements.

right

↑ The body element on the other hand is for visual elements like button and textbox. There are exceptions, such as the script element can be used inside the body element.

right

The selector refers to the element that we want to add style to. A CSS rule describes how an element should look like, and it’s made up of a property and a value.

The # sign is used in both JavaScript and CSS for selecting an element by ID.

right

display is a CSS property that controls the visibility of an element. Setting display to none will hide the element.

Next, we can show the hidden element with a fade-in animation inside the submitButton’s handler. So the output element will be visible only when it’s updated with new content.

submitButton.on("click", function(){
  ...
  output.html( "The sum is " + sum );
  output.fadeIn(); // NEW
});

unpack:

fadeIn is another method from a jQuery element object.

There are many other CSS properties we can use to decorate the output message. Here are some of the common ones:

#output {
  display: none;
  color: red;
  background-color: yellow;
  font-family: arial;
  font-size: 24pt;
  font-weight: bold;
  width: 200px;
  height: 200px;
}

unpack:

color - controls the text color of an element

background-color - controls the background color

font-family - controls the text font

font-size - controls the text size

font-weight - controls the boldness

width - controls the width of an element

height - controls the height of an element

Here’s what the output element should look like:

right

This should give you a general idea of how CSS works. But because CSS is an entire different subject on its own, it will not be our focus here.

External CSS

Just like the JavaScript file, we can extract the CSS code to a separate file:

Create a new file called main.css.

chapter-9
main.css

And then, move the CSS code to the new file.

#output {
  display: none;
  color: red;
  background-color: yellow;
  font-family: arial;
  font-size: 24pt;
  font-weight: bold;
  width: 200px;
  height: 200px;
}

And finally, connect to the new file using the link element:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="main.css">
  </head>
  <body>
    ...
  </body>
</html>

unpack:

The style element is no longer needed.

The link element doesn’t have a closing tag.

Class

A class is another common way to identify an element, but a class doesn’t have to be unique like an id.

right

We can give the same class to multiple elements, and this can be useful for manipulating multiple similar elements all at once.

For example, if we want to fade in all the input elements when the program starts, we can set the class attribute on the two input elements with the same name.

index.html
...
<input type="text" class="input" id="textbox">
<input type="button" class="input" id="submitButton" value="submit">
...

unpack:

The name we give to the two elements is input.

↓ And then use the class name as the selector in the CSS. This will hide the input elements by default.

main.css
...
#output {
  display: none;
}

/* NEW */
.input {
  display: none;
}
...

And finally use the fadeIn method.

main.js
let output = $("#output");
let textbox = $("#textbox");
let submitButton = $("#submitButton");
$(".input").fadeIn(); // NEW
...

unpack:

We’re using the fadeIn method on the return value directly without creating a new variable, because we’re using this return value only once.

We’re using . instead of # for selecting elements by class name.

right

The Div element

div is a very important element in website programming. It wasn’t introduced the previous chapter because we didn’t have a use case for it.

div is an empty box for grouping multiple elements together.

right

If we put the two input elements in a div element, we can use fadeIn just on the div element.

HTML
...
<div id="input-group">
  <input type="text" class="input" id="textbox">
  <input type="button" class="input" id="submitButton" value="submit">
</div>
...

↓ And we have to change .input to #input-group

CSS
...
<style>
  #output {
    display: none;
  }

  /* CHANGE */
  #input-group {
    display: none;
  }
</style>
...
JavaScript
let output = $("#output");
let textbox = $("#textbox");
let submitButton = $("#submitButton");
$("#input-group").fadeIn(); // CHANGE
...

On the surface, using div doesn’t seem to make much difference, but this is more efficient setup. Perviously we were using fadeIn on multiple elements, and now we’re only using it on one div element.

the Main Function

We can put all the JavaScript code in a function. This makes the code easier to manage.

function main(){
  let output = $("#output");
  let textbox = $("#textbox");
  let submitButton = $("#submitButton");

  $("#input-group").fadeIn();

  submitButton.on("click", function(){
    let userInput = textbox.val();
    let inputItems = userInput.split(" ");

    let sum = 0;

    for(let i = 0; i < inputItems.length; i++){
      if(!isNaN(inputItems[i])){
        sum = sum + parseInt(inputItems[i]);
      }
    }
    output.html( "The sum is " + sum );
    output.fadeIn();
  });
}

main(); // call the function

unpack:

Because the code is now inside a function, we have to call the function to run the code.

↓ Instead of calling the main function directly, a more common technique is to set the main function as an event handler to the window object. The main function will be called automatically when the page is done with loading.

Before
main();
After
$(window).on('load', main);

unpack:

window is the main object of the entire web page.

The load event will be triggered when all the page contents are loaded.

Execution Flow

As a side benefit, by setting the main function as an event handler, now the script element connecting to main.js doesn’t have to locate at the bottom of the body element. We can move both of these script elements to the head, just right below the link element.

...
<head>
  <link ref="stylesheet" type="text/css" href="main.css">
  <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
  <script src="main.js"></script>
</head>
...

This is more organized because all the external file connections are gathered in the same place.

Because the JavaScript code is only defining a function and setting it as an event handler, We don’t have to wait for all the elements to get loaded before running the JavaScript code. Both of these actions don’t require any elements to be available.

Although the code inside the main function do require the elements, they are only needed when the function is actually running.

Recap

index.html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="main.css">
    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
    <script src="main.js"></script>
  </head>
  <body>
    <div id="input-group">
      <input type="text" class="input" id="textbox">
      <input type="button" class="input" id="submitButton" value="submit">
    </div>
    <p id="output"></p>
  </body>
</html>
main.css
#output {
  display: none;
}

#input-group {
  display: none;
}
main.js
function main(){
  let output = $("#output");
  let textbox = $("#textbox");
  let submitButton = $("#submitButton");

  $("#input-group").fadeIn();

  submitButton.on("click", function(){
    let userInput = textbox.val();
    let inputItems = userInput.split(" ");

    let sum = 0;

    for(let i = 0; i < inputItems.length; i++){
      if(!isNaN(inputItems[i])){
        sum = sum + parseInt(inputItems[i]);
      }
    }
    output.html( "The sum is " + sum );
    output.fadeIn();
  });
}

$(window).on('load', main);
  • We added a new script tag to import the jQuery library.
  • Use the $ function to import the elements.
  • Use the jQuery methods: on, val and html.
  • Use CSS to make an element hidden by default, and show it with fade-in animation effect.
  • Use the div element to group multiple elements together.
  • Put all the JavaScript code in a main function, and set it as an event handler.

Exercise

The main function is getting too big, try to create a new function and extract the event handling code to the new function.

submitButton.on("click", function(){
  let userInput = textbox.val();
  let inputItems = userInput.split(" ");

  let sum = 0;

  for(let i = 0; i < inputItems.length; i++){
    if(!isNaN(inputItems[i])){
      sum = sum + parseInt(inputItems[i]);
    }
  }
  output.html( "The sum is " + sum );
  output.fadeIn();
});

unpack:

The event handling code

The new function should be used like this:

function main(){
  let output = $("#output");
  let textbox = $("#textbox");
  let submitButton = $("#submitButton");

  $(".input-group").fadeIn();

  // THIS ↓
  addEventHandlers(output, textbox, submitButton);
}

unpack:

The new function will take all three elements as parameters.

And it will return nothing.

Solution

function addEventHandlers(output, textbox, submitButton){

  submitButton.on("click", function(){
    let input = textbox.val();
    let inputItems = userInput.split(" ");

    let sum = 0;

    for(let i = 0; i < inputItems.length; i++){
      if(!isNaN(inputItems[i])){
        sum = sum + parseInt(inputItems[i]);
      }
    }
    output.html( "The sum is " + sum );
    output.fadeIn();
  });
}