Introduction to JavaScript

Les Pinter


Introduction | Editing and Testing | The Document Object Model | Validating Input | Keywords | jQuery | AJAX | Conclusion

Introduction

JavaScript is a programming language that runs inside your browser. It has gone through many consecutively numbered enhancements - the latest is called ES6 (for ECMA Script - Google it). It can operate on the elements in your web page - change their appearance, show or hide them, and even add more content dynamically.

JaveScript responds to events, such as changes in the content of a textbox or dropdown list, a button click, or any other of dozens of events. It does so by "listening" for a particular event on a particular element. And you can do just about anything with JavaScript that you've ever seen a program do.

There are a few restrictions on what JavaScript is allowed to do: You can't access the file system of the computer where the browser is running, for obvious reasons; you can't run executable programs from a browser; you can't change the browser history, or change the displayed URL. These restrictions are necessary to stop Russian hackers (unless there is no such thing as Russian hackers...) Other than that, knock yourself out.

In this short course, you'll learn the basic syntax and usage of JavaScript, how to write and test code, and how to incorporate it in your web pages. As always, there are a boatload of excellent examples at W3SCHOOLS.COM.

How to use JavaScript

JavaScript functions are defined within an HTML page, either in the Head or the Body section. Code can either be declared within event handlers on individual elements, in scripts that can either be included in the page's HTML or linked from external .js files using <script src="http://..."async/defer) /> . It generally doesn't matter where scripts are placed, since they're "hoisted" to the top of the code when the page is loaded. Once linked, you can call the named functions in your scripts. (Note that some purists insist that you should always write your JavaScript functions in external files with a ".js" extension.)

You can write your own JavaScript libraries, but you can also link to others available all over the web. Some available libraries are massive, with fantastic capabilities. Once you master their documentation, you'll be amazed at what you can do.

The "src" parameter of the script tag is a URL (Uniform Resource Locator), and can either be a location relative to the web page's folder on your server (e.g. <script src="./mylib.js" />), or a url (e.g. <script src="http://jquery.com/jquery-1.12.1.js" />) anywhere on the web.

Traditionally, named functions are defined within <script> tags, and then called in your HTML tags using a listener (event handler), typically using on<event> (e.g. onclick, onload, etc.) followed by the name of a function:

<Body onload="highlightButton()">

  <button onclick="showList()">Customer List</button>

  <script>
  function highlightButtons() {
    document.querySelector("button").style.Color = "Red";
  }
  function showList() {
    document.location = "./CustList.html";
  }
  </script>

</Body>

You can use the AddListener method to attach an event handler to any object, including the body of your web page.

  <body onload="document.getElementById('btn').addEventListener('click',changeColor)">
  <button id="btn">Change color</button>
  <script>
    function changeColor() { document.body.style.backgroundColor = "red"; }
  </script>
</body>

You can also put code directly into the onclick declaration:

  <button onclick="document.body.style.backgroundColor = 'red';">Color me red</button>

How to Edit and Test JavaScript

All you need to write and test JavaScript is a text editor. NotePad.exe on your Windows computer is one such editor, and it will indeed work. Type the following into a text file:

A simple JavaScript script

<!doctype html>
<html>
  <head>
    <script>
      function SayHi() {
        alert('Hello there...');
      }
    </script>
  </head>
  <body>
    <h1>JavaScript Test</h1>
    <button onclick="SayHi()">Say Hello</button>
  </body>
</html>

Save the file as C:\Users\{your userid}\Desktop\First.html". It will magically appear on your desktop. Double-click on it. Since the extension is "html", your default browser will read and render the file. Click on the "Say Hello" button and you'll get a little message from your first JavaScript program. Mazel tov.

However, there are many editors that have features built in that make the experience a lot more enjoyable. In particular, Visual Studio Code - not the Integrated Development Environment (although you'll eventually need to download the free version), but rather the free and open-source editor from Microsoft. It has intellisense, automatic indenting, and a ton of other features.

VS Code is extensible. There are around five hundred free extensions that you can download and hook into VS Code to enhance the way it works. For example, one extension lets you use Alt+B to launch the browser and display your page. Another color-codes and highlights matching parentheses and curly braces, which will drive you nuts if you ever get them out of sync. Or, you can write your own if you're so inclined. Once you get used to them, you'll wonder how you ever got along without them.

There are also several online tools to write and test JavaScript, all of which avoid the jump from HTML editor to StyleSheet editor to JavaScript editor to web browser required to test your code. Here are a few of them:

All three work in a very similar fashion: You build a web page (.html), a stylesheet (.css) and a JavaScript (.js) file, and then launch the .html file in a browser, using the Run button found in each environment. Links to the style sheet and script file are implied, so you don't have to explicitly include those two lines of code. But if you copy and paste the contest of the three editors to your computer, you'll need to name the .css and .js files and add a <link> and a <script> reference to them in your .html file.

Here's what CodePen looks like:

Fig. 1 - CodePen at work

You might like one of these environments so much that you'll be tempted to use it instead of Visual Studio Code. Not a good idea. But they're great for learning.

The Document Object Model (DOM)

An HTML page is an outline. <html> is the outermost element, the document. The <head> and <body> elements are actually document.head and document.body, respectively, as the line of code above that assigned a red background color to the entire page(<button onclick="document.body.style.backgroundColor = 'red';">) shows.

In JavaScript you often need to refer to a particular sentence, paragraph, or other element. You can assign them to a variable using the classic var declaration, or the newer let and const declarations.

One way to do this is by selecting an element, or a collection of elements, by class, Id or tag type, using one of three built-in functions:

It's best to assign a particular Id to only one element, e.g.

<div id="target1">

So document.getElementById('target1') would return a single element, the <div> shown above.

However, y and z above would typically be collections of objects. So after assigning them to a variable, you would have to iterate through them, using a for loop:

  <!DOCTYPE html>

  <html lang="en">

  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Show input fields</title>
    <style>
      .inputField { visibility: hidden; }
    </style>
  </head>

  <body>

  <script type="text/javascript">
      function showInputFields() {
      var y = document.getElementsByClassName('inputField');
      let i = 0;
      for ( i = 0; i<y.length; i++ )
        { y[i].style.visibility = 'visible'; }
      document.getElementById('controlInputs').innerHTML = "Hide input fields";
      }
    </script>

    <button id="controlInputs" onclick="showInputFields()" >Show input fields</button>

    <table>
      <tr><td>First:</td><td><input class="inputField" id="firstName" width="200" /></td></tr>
      <tr><td>Last</td><td><input class="inputField" id="lastName" width="200" /></td></tr>
      <tr><td>Phone</td><td><input class="inputField" id="Phone" width="100" /></td></tr>
    </table>

  </body>

  </html>

Validating input

Making sure that your users filled in all required fields and supplied valid values before submitting a form used to be the most common requirement that moved web developers to learn JavaScript. HTML 5 has added some built-in features that allow you to do many validations without JavaScript. Here's an example (SaveData.aspx could be a web page that reads the content of the input fields and stores the data, presumably in a database. Not included.):

  <b>Validation using HTML/CSS (no JavaScript)</b>

  <!DOCTYPE html>

  <html lang="en">

  <head>
    <title>Sample HTML 5 validation</title>
    <style>
      input { padding: 3px; }
      input:invalid { border: 2px dashed red; }
      input:valid { border: 2px solid black; }
      input[type=text] {
        width:100%;
        height:40px;
        padding:5px;
        margin-bottom:25px;
        margin-top:5px;
        border:2px solid #ccc;
        color:#4f4f4f;
        font-size:16px;
        border-radius:5px
      }
  </style>
  </head>

  <body>

  <form method="post" action="./SaveData.aspx" >

  <div  style="margin: 20px;">

    <label for="firstName">First name:</label>
  <input name="firstName" width=200px required  />

  <br /><br />
  <label style="margin-top: 30px;" for="lastName">Last name:</label>
  <input name="lastName" width=200px required />

  <br /><br />
  <label style="margin-top: 10px;" for="Children">Children:</label>
  <input name="Children" min=0 max=12 type=number required />

  <br /><br />
  <label style="margin-top: 10px;" for="email">E-mail:</label>
  <input type="email" name="email" width=200px />

  <br /><br />
  <button>Submit</button>

  </div>

  </form>

  </body>

  </html>

However, there are cases where you want to do something fancier, like look up a zip code and fill in the city and state fields. Zippopotam.us (sic) is free. This is the JavaScript:

<script type="text/javascript">
  var client = new XMLHttpRequest();
  client.open("GET", "http://api.zippopotam.us/us/90210", true);
  client.onreadystatechange = function()
  { if(client.readyState == 4) {alert(client.responseText);}; };
  client.send();
</script>

and this is what you get back:

{ "post code": "90210",
  "country": "United States",
  "country abbreviation": "US",
  "places": [
  { "place name": "Beverly Hills",
    "state": "California",
    "state abbreviation": "CA", }
            ]
}

So you have to build the string containing your user's ZIP code before calling the function, and you have to unpack the JSON that comes back. But it's relatively simple, and your users will appreciate it.

Keywords

JavaScript has a number of keywords that have special purposes:

General observations:

Variables begin with a letter, and can contain letters, numbers, and most special characters - but no blanks.

Lines are terminated with a semicolon; they can continue beyond a single line until terminated by a semicolon.

Lines that start with "//" are comments, and are not executed.

Variable declarations:

Variables hold values. Let and const are preferred these days. Const means you're not going to change the value. Variables are either of type numeric, string, or date. Here are a few examples:

var i = 0;
let name = "Les";
const DOB = "03/15/1993";

A "do-loop" continues until a condition is satisfied:

<script>
    let i = 1; do { document.writeln(i); i++; } while (i < 5);
</script>

For...loops are very commonly used:

<body>
  <script>
    const names = [ "Les", "Allen", "Gracie", "Mark", "Elena" ];
    for (i=0; i < names.length; i++)
    {if (names[i] == 'Mark')  break; }
    document.write('Found Mark at position ' + (i + 1));
  </script>
</body>

The break statement exits the loop immediately - as soon as 'Mark' is found in this case. Note that arrays in JavaScript are zero-based, so when I display at what position the name 'Mark' was found, I had to add one to the index value. You can also use return to completely leave the function, instead of dropping out of the loop and continuing with the code that follows it. continue goes back to the top of the loop, increments the index, and, well, continues.

if (condition) { do this } else { do that }

If I return the system date and print it, like this:

var td = new Date();
document.writeln(td);

I get this: Sun Aug 12 2018 20:54:45 GMT-0700 (Pacific Daylight Time)

So I have to extract month, day and year. If a single digit is returned, I prefix it with a zero. That's where the if statements come in:

var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();

if(dd < 10) { dd = '0'+dd }
if(mm < 10) { mm = '0'+mm }

today = mm + '/' + dd + '/' + yyyy;
document.writeln(today);

which gives me 08/12/2018.

Switch (var):

Switch lets you specify conditions for taking action. The "===" ("strict" comparison - exact match, same type) is used. You can specify multiple "var" values.

switch (new Date().getDay()) {
  case 5:
      text = "The weekend is coming!";
      break;
  case 0:
  case 6:
      text = "It is the weekend";
      break;
  default:
      text = "Looking forward to the weekend";
}

Function declaration

In all of the above cases, the code runs as soon as the page has finished loading. However, many if not most JavaScript functions are to be run when something occurs - a mouse click, selection of a value from a dropdown list, or leaving an input field. These functions are generally given names, and then attached to an event using either an "on..." attribute or an attachEventHandler() invocation:

<script>
  function highlightText() {
    document.getElementById('thisIsIt').style.backgroundColor = "Yellow";
  }
</script>

<input type="button" onclick="highlightText()" value="Highlight text" />

You can also declare an anonymous function, reasonable if you're going to do something only once in only one place:

<input
  type="button"
  onClick="document.getElementById('thisIsIt2').style.backgroundColor = 'Red';"
  value="Red text" />

You can also use addEventListener():

<button id='btn2' type=button>Say Hello World</button>
<p style="background-color: Yellow; width: 100px;" id="abc"></p>

<script>
  document.getElementById('btn2').addEventListener("click", function(){
    document.getElementById("abc").innerHTML = "Hello World";
});
</script>

Functions can be defined in either the head or the body. It generally doesn't matter where scripts are placed, since they're "hoisted" to the top of the code when the page is loaded.

<body>
  <script>
    function fullName(first,last) {
    return first + " " + last;
  }
    document.writeln('The name is ' + fullName('Les','Pinter'));
  </script>
</body>
The name is Les Pinter

You can also define objects that contain methods, which are the same as functions:

var person = {
  firstName: "John",
  lastName : "Doe",
  id       : 5566,
  fullName : function() {
      return this.firstName + " " + this.lastName;
  }
};
document.write(person.fullName());
Note that if you leave off the "()" at the end of
the function name, it will return the function definition,
which isn't too useful.

try...catch

If you're not sure what's going to happen, you can use this. Try..Catch tries to execute the code between try and catch. If it fails, it continues on the line after catch.

try {
    tryCode - code to try
}
catch(err) {
    catchCode - code to handle errors
}
finally {
    finallyCode - code to be executed ALWAYS
}

debugger;

To stop the program and let you step through one line at at time (by pressing F11), add the single line

debugger;

If you're running Chrome and have selected More Tools, Developer Tools from the context menu that appears when you click the three little vertical dots at the upper right hand corner of the screen, you'll see a pretty complete debugging environment. Press F5 to start the page, and it will stop on the debugger; line. Press F11 to step through the code one line at a time. You can inspect the contents of variables, and quickly be reminded that collections are zero-indexed, or whatever trivial mistake you've made for the thousandth time.

<rant> Someone once asked me what I did for a living. "I write
code with bugs, and then I find them and fix them." "Why don't you
just write the code with no bugs to begin with?", she innocently asked.
Dumbass...</rant>

W3SCHOOLS.com has tons of examples. Some of the ones you've seen here were lifted verbatim from their website. Do likewise. In our business, piracy is the sincerest form of flattery.

jQuery

jQuery was originally created in January 2006 at BarCamp NYC by John Resig and was influenced by Dean Edwards' earlier cssQuery library. It is currently maintained by a team of developers led by Timmy Willison and Richard Gibson.

jQuery lets you add all manner of special effects and UI enhancements to your web pages by simply adding a few script and link statements, and then adding simple jQuery code in your scripts. jQuery.com has links to the main files to download. You'll want jQuery-3.3.1.js (or jQuery-3.3.1.min.js, the "minified" version), and optionally jQueryUI-1.12.1, which adds a dozen "widgets" such as an accordion, datepicker, menu, spinner, and others. Here's the datepicker:

  jQuery UI DatePicker

  <!doctype html>
  <html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>jQuery UI Datepicker - Default functionality</title>
    <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <link   rel="stylesheet"
     href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script>
    $( function() {
      $( "#datepicker" ).datepicker();
    } );
    </script>
  </head>
  <body>

  <p>Date: <input type="text" id="datepicker"></p>

  </body>
  </html>
Fig. 2 - The jQuery UI DatePicker

Beats typing in numbers and slashes, doesn't it?

  Note: In order to use jQuery and jQueryUI, you'll need to include references to the three jQuery files at the jQuery.com
  website. This will cause your page to take about 15 seconds to load. That's why we're going to learn how to use React.js to build
  Single-Page Applications (SPAs) that only load the scripts once. If your users have to wait 15 seconds or more every time
  they click on a button, they're going to lose interest real quick.

jQuery uses selectors, which provide a shorthand for assigning events to elements.

1. Example: When a user clicks on the "btnHide" button, all <p> elements will be hidden:

  $(document).ready(function(){
      $("btnHide").click(function(){
          $("p").hide();
      });
  });

2. When a user clicks on a button, the element with id="test" will be hidden:

  $(document).ready(function(){
      $("button").click(function(){
          $("#test").hide();      /* # means "id = 'test'" */
      });
  });

3. When a user clicks on a button, the element with class="test" will be hidden:

  $(document).ready(function(){
      $("button").click(function(){
          $(".test").hide();      /* . means "className = 'test'" */
      });
  });

jQuery also has tons of cool effects, like slide-up, slide-down, fade-out and fade-in, and lots of others, all assignable with two or three lines of code.

Adding or removing HTML elements or CSS classes is just as easy, as is inserting text loaded from a file or from a web api. This is called "AJAX", the acronym for Asynchronous JavaScript And XML. Even when there's no XML involved...

The following code sets up a function to load a file called demo_test.txt into a div with the id "div1" when a button is clicked:

$("button").click(function(){
$("#div1").load("demo_test.txt", function(responseTxt, statusTxt, xhr){
  if(statusTxt == "success")
      alert("External content loaded successfully!");
  if(statusTxt == "error")
      alert("Error: " + xhr.status + ": " + xhr.statusText);
  });
});

There is a lot more to jQuery and jQueryUI. You owe it to yourself to go through the many examples on the jQuery website

AJAX

The ability to populate only a part of a web page has huge implications for web development. For one thing, any and all script and style sheet files have to be reloaded if you post as the result of clicking on a link or a button.

The mechanism for loading external content into a web page is called Asynchronous JavaScript And XML, or AJAX. The main mechanism is the XMLHttpRequest.

Say you have a web page with a dropdown combo containing the letters A thru Z, and a <P id="demo" />. I'll also need a script containing a function called loadDoc() that builds a <table> containing all names where the last name starts with the letter selected in the comboBox above. When an XMLHttpRequest finishes (asynchronously, obviously), the text string that it produced completely replaces the selected element - the paragraph with id=demo, in this case. Got that? Here's the web page, index.html:

  <!DOCTYPE html>
  <html>

  <body onload="Start()">

    <h2>The XMLHttpRequest Object</h2>

    Show last names starting with
    <select runat= name="letter" id="letter" onchange="loadDoc()">
      <option>A</option>
      <option>B</option>
      ...
      <option>Z</option>
    </select>

    <!-- A data table will replace this element -->
    <p id="demo"></p>

    <script>
      function Start() { loadDoc(); }	/*load the "A" list*/

      function loadDoc() {
        var e = document.getElementById("letter");
        if (e.selectedIndex < 0) return;
        var ltr = e.options[e.selectedIndex].value;

        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function () {
          if (this.readyState == 4 && this.status == 200) {
            document.getElementById("demo").innerHTML = this.responseText;
          }
        };
        xhttp.open("GET", "GetData.aspx?startLetter=" + ltr, true);
        xhttp.send();
        e.focus();
      }
    </script>

    <hr />

  </body>

  </html>

If we're going to return data, we'll need a table in the TEST database. How about this one?

  CREATE TABLE [dbo].[Clients](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[FirstName] [varchar](max) NULL,
	[LastName] [varchar](max) NULL,
	[Address] [varchar](max) NULL,
	[City] [varchar](max) NULL,
	[State] [varchar](max) NULL,
	[ZIP] [varchar](max) NULL,
	[Phone] [varchar](max) NULL,
	[FullName]  AS (([FirstName]+' ')+[LastName]),
 CONSTRAINT [PK_Clients] PRIMARY KEY CLUSTERED
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

That computed column FullName is what will be displayed.

Now, since we're going to be using XMLHttpRequest to call a web page, the web page needs to run under the control of a server process. Since aspx pages run under a mini-iis started inside Visual Studio when you Run, we can build a website project, create an aspx page to serve the data, and then add index.html and make it the Start Page for the website.

First, add an ADO object from the Add, New Item dialog. Select the Test database, and request inclusion of the Clients table. Save the .edmx diagram to generate the model code.

Finally, add a web page named GetData.aspx Here's the HTML:

.
<%@ 
  Page Language="C#" 
  AutoEventWireup="true"
  CodeFile="GetData.aspx.cs" 
  Inherits="GetData" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>Test of AJAX GET</title>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <h1 style="text-shadow: 3px 3px 3px #300; 
       color: Red; font-size: 24pt">
       Using AJAX to return text</h1>
      <asp:Label ID="info" runat="server" 
       ForeColor="Green" /><hr />
      <asp:GridView
        ID="grid"
        runat="server"
        Font-Weight="Bold"
        BorderStyle="Dotted"
        BorderWidth="1px"
        BorderColor="Blue"
        Font-Size="8"
        Width="125"
        ForeColor="FireBrick"
        Font-Names="Arial">
        <AlternatingRowStyle BackColor="LightGreen" />
      </asp:GridView>

    </div>
  </form>
</body>
</html>

The code-behind is pretty simple:

using System;
using System.Linq;
using System.Collections.ObjectModel;

public partial class GetData : System.Web.UI.Page
{
  TestEntities mgr = new TestEntities();
  public ObservableCollection<string> names { get; set; }

  protected void Page_Load(object sender, EventArgs e)
  { names = new ObservableCollection<string>();
    string startLetter = Request.QueryString["startLetter"].ToString();
    if (startLetter != null && startLetter.Length == 1)
    { var query = mgr.Clients
     .Where(x => x.LastName.StartsWith(startLetter))
     .OrderBy(x => x.LastName).ThenBy(x => x.FirstName);
      foreach (dynamic d in query) { names.Add(d.FullName); }
    }
    else
    { var query = mgr.Clients.OrderBy(x => x.LastName).ThenBy(x => x.FirstName);
      foreach (dynamic d in query) { names.Add(d.FullName); }
    }
    grid.DataSource = names;
    info.Text=string.Format("{0} last names start with "+startLetter,names.Count);
    grid.DataBind();
  }
}

Inside Visual Studio, make sure you've made index.html the Start Page. Select a letter from the dropdown combo. When the SelectedIndex changes, the onchange function will fire. It calls loadData(), which retrieves the letter selected by the user, and then runs GetData.aspx to retrieve last names starting with that letter, formats an HTML table, and returns the formatted table:

  var ltr = e.options[e.selectedIndex].value;

and constructs the line of JavaScript that actually calls GetData.aspx:

    xhttp.open("GET", "GetData.aspx?startLetter=" + ltr, true);

When this asynchronous call completes, the formatted table replaces the innerHTML content for the element <p> with id = "demo".

  document.getElementById("demo").innerHTML = this.responseText;

Run the website, and make sure you pick letters for which you have some matching last names!

Fig. 3 - Using AJAX to load text into an element inside a page

There are probably dozens of ways to write the server page that returns data. You can use an .asp page in which you declare a connection and a dataadapter, and bypass the generation of entity-framework classes (and learning entity-framework, if you're still putting that off...). You can also return XML, JSON, CSV data or anything you want. Angular, React and a number of other frameworks actually contain their own mechanisms for iterating through JSON data and constructing <table>, <tr> and <td> tabs with the data parsed out. So this is just one way to use AJAX.

But the biggest benefit of AJAX is that you don't POST and reload the page, which would reload all script and link files as well. So even if you aren't ready for Angular, Vue or React, consider AJAX for any and all interactive content updates. Your users will appreciate it.

Conclusion

JavaScript has a dizzying potential for browser-based software. Here are a few examples:

and about a million others. A list of what can't be done with JavaScript would be shorter than a list of what you can do with it.

In my article "The Five Pillars of the Web" I said that you need to learn C#, Java, Python, PHP or some other high-level language in order to serve pages. That's not entirely correct. NODE.JS lets you write JavaScript that runs on the server. In our React.js course, you'll learn how you can significantly outperform ASP.NET web servers by writing non-blocking JavaScript code that doesn't make users wait while pages are being rendered.

JavaScript is already amazing, and we're just getting started. No matter which technical direction you take, JavaScript will be a part of it. And the better you are at it, the bigger role it will play. Get started today.

❑❑❑