This section is about using JavaScript to create an interactive UI.

  1. Buggy JavaScript Code
  2. Font Manipulation
  3. Is it Caturday?
  4. Weight Conversion
  5. Order-It (long)

1. Buggy JavaScript Code:

The following pages have mistakes that cause their JavaScript code not to work properly. Look at the pages, find the bug(s), and correct the problems.

  1. buggy page #1 (JavaScript)
  2. buggy page #2 (JavaScript)
  3. buggy page #3 (JavaScript)
  4. buggy page #4 (JavaScript)

The following links may help you in the debugging process:

Solutions

  • buggy1: HTML script tag has name of JS file misspelled. Discover by putting alert at top of JS file, noticing that it doesn't show, checking script tag.
  • buggy2: HTML script tag is self-closing (not valid; breaks whole page in FF), and misspelled name of onclick attribute. Discover by using W3C HTML Validator.
  • buggy3: many syntax errors:

    • semicolon after () in function header
    • '' instead of " to close string
    • Alert shouldn't be uppercase
    • ) instead of } to close function

    Discover by looking at Firebug error console, and/or by running JSLint.

  • buggy4: syntax error, missing } brace. Discover by running JSLint (error message more helpful than Firebug's).

2. Font Manipulation

Apply JavaScript to the paragraph #text to beautify it. Change the following:

  1. the text of the paragraph to something of your choice
  2. the font, font size, and color of the text

font.html:

<!DOCTYPE html>
<html>
   <head>
      <title>Prettify</title>
      <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js" 
         type="text/javascript"></script>
      <script src="font.js" type="text/javascript"></script>
   </head>

   <body>
      <p id="text">Click the button below and beautify the font.</p>
      <div><button id="prettify">Prettify</button></div>
   </body>
</html>

problem by Rishi Goutam

Solution

Add the following to font.html:

<div><button id="prettify" onclick="prettify();">Prettify</button></div>

font.js:

function prettify() {

   var text = document.getElementById("text");

   // can also use: var text = $("text");

   text.innerHTML = "Look! It's pretty!";

   

   // font styles added by JS:

   text.style.fontSize = "13pt";

   text.style.fontFamily = "Comic Sans MS";

   text.style.color = "red";

}

3. Is it Caturday?

Given the following skeleton HTML file, write the necessary JavaScript code to decide whether it is "Caturday" (Saturday) when the "Is it Caturday?" button is clicked.

<!DOCTYPE html>
<html>

   <head>

      <title>Is it Caturday?</title>

      <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js" type="text/javascript"></script>

      <script src="caturday.js" type="text/javascript"></script>

      <link rel="stylesheet" type="text/css" href="http://webster.cs.washington.edu/cse190m/sections/5/caturday/caturday.css" />

   </head>

   <body>

      <h1 id="answer"></h1>

      <p><button id="button">Is it Caturday?</button></p>

   </body>

</html>

You should inject "YES" or "NO" into the #answer paragraph depending on whether the current day of the week is Caturday. You should also change the class of the body tag to .yes or .no accordingly.

To figure out whether today is Caturday, use a JavaScript Date object:

var now = new Date();   // this very moment!

You can use the getDay method of a date object to figure out the day of the week. It will return a number between 0 (Sunday) and 6. To test on a day you know is Caturday, pass a parameter to the date object:

var caturday = new Date("April 23, 2011 01:23:45");

Here's a working solution for you to try out. (Don't peek at the code!)

problem by Morgan Doocy

Solution

Add the following to caturday.html:

<p><button id="button" onclick="caturday();">Is it Caturday?</button></p>

font.js:

function caturday() {

   var today = new Date();

   // var today = new Date("April 23, 2011 01:23:45");

   

   var caturday = today.getDay() == 6;

   var text = caturday ? "YES" : "NO";

   $('answer').innerHTML = text;

   document.body.className = text.toLowerCase();

}

5. Weight Conversion

Write a function convert() in conversions.js that takes the value in the text input and converts it from the unit selected in the left dropdown box to the unit selected on the right. The result should be displayed in the empty span with the id of “answer.” The conversion factor from pounds to kilograms is 0.45359237, and the conversion factor from kilograms to pounds is 2.20462262. You should edit the HTML file conversions.html to add ids to the elements as necessary and you may assume valid input.

conversions.html:

<!DOCTYPE html>
<html>
   <head>
      <title>Weight Conversion</title>
      <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"
         type="text/javascript"></script>
      <script src="conversions.js" type="text/javascript"></script>
   </head>
   <body>
      <fieldset>
         Convert <input type="text"/>
         <select>
            <option>kg</option>
            <option>lb</option>
         </select>
         <select>
            <option>lb</option>
            <option>kg</option>
         </select>
         <button>Calculate</button>
         <span id="answer"></span>
      </fieldset>
   </body>
</html>

Solution

conversions.html:

<!DOCTYPE html>
<html>
   <head>
      <title>Weight Conversion</title>
      <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"
         type="text/javascript"></script>
      <script src="conversions.js" type="text/javascript"></script>
   </head>
   <body>
      <fieldset>
         Convert <input type="text" id="input" />
         <select id="from">
            <option>kg</option>
            <option>lb</option>
         </select>
         <select id="to">
            <option>lb</option>
            <option>kg</option>
         </select>
         <button onclick="convert();">Calculate</button>
         <span id="answer"></span>
      </fieldset>
   </body>
</html>

conversions.js:

function convert() {
   value = parseInt($("input").value);
   if ($("from").value == "kg" && $("to").value == "lb") {
      value *= 2.20462262;
   } else if ($("from").value == "lb" && $("to").value == "kg") {
      value *= 0.45359237;
   }
   $("answer").innerHTML = value;
}

6. Order-It: (long)

Today we'll write a page that lets us perform various manipulations on the text in a text area. Here is the page (click the image to run our sample solution, written by TAs Sylvia Tashev and Stefanie Hatcher):

The HTML and CSS are already written, but we must add JavaScript code to make the UI respond when the user clicks the buttons. Start from the following skeleton:

<!DOCTYPE html>
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
      <title>Order-It!</title>

      <link href="http://www.cs.washington.edu/education/courses/cse190m/09sp/labs/section5-orderit/solution/orderit.css" type="text/css" rel="stylesheet" />

      <script src="http://www.cs.washington.edu/education/courses/cse190m/09sp/scriptaculous/prototype.js" type="text/javascript"></script>

      <!-- your file -->
      <script src="orderit.js" type="text/javascript"></script>
   </head>

   <body>
      <h1>
         Order-It!

         <a href="http://validator.w3.org/check/referer">
            <img src="http://www.cs.washington.edu/education/courses/cse190m/12sp/images/w3c-html.png" alt="Valid HTML" />
         </a>
         <a href="http://jigsaw.w3.org/css-validator/check/referer">
            <img src="http://www.cs.washington.edu/education/courses/cse190m/12sp/images/w3c-css.png" alt="Valid CSS" />
         </a>
         <a href="http://webster.cs.washington.edu/jslint?referer">
            <img src="http://www.cs.washington.edu/education/courses/cse190m/12sp/images/jslint.png" alt="JavaScript Lint" />
         </a>
      </h1>

      <div>
<textarea rows="18" cols="100">
Sample Item 1
Sample Item 2
Sample Item 3
Sample Item 4

Sample Item 5
Sample Item 6


Sample Item 7
</textarea>
      </div>

      <div>
         <button>Clear All</button>
         <button>Capitalize</button>
         <button>Sort</button>
         <button>Reverse</button>
         <button>Add Numbers</button>
         <button>Strip Blank</button>
         <button>Shuffle</button>
      </div>
   </body>
</html>

Add the following behavior to the buttons:

Recall that you can retrieve the JavaScript "DOM" object for a given HTML element with the document.getElementById function. Recall that an array has a length field and methods such as: concat, join, pop, push, reverse, shift, slice, sort, splice, unshift

If you finish all of that behavior, consider adding a button to change the capitalization of lines, such as capitalizing/lowercasing entire lines or converting lines to AlTeRnAtInG cAsE.

Solution

orderit.html

<!DOCTYPE html>
<html>
   <!-- Sylvia Tashev - April 20, 2009 -->

   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
      <title>Order-It!</title>

      <link href="orderit.css" type="text/css" rel="stylesheet" />
      <script src="http://www.cs.washington.edu/education/courses/cse190m/09sp/scriptaculous/prototype.js" type="text/javascript"></script>

      <!-- your files -->
      <script src="orderit.js" type="text/javascript"></script>
   </head>

   <body>
      <h1>
         Order-It!

         <a href="http://validator.w3.org/check/referer">
            <img src="http://www.cs.washington.edu/education/courses/cse190m/12sp/images/w3c-html.png" alt="Valid HTML" />
         </a>
         <a href="http://jigsaw.w3.org/css-validator/check/referer">
            <img src="http://www.cs.washington.edu/education/courses/cse190m/12sp/images/w3c-css.png" alt="Valid CSS" />
         </a>
         <a href="http://webster.cs.washington.edu/jslint?referer">
            <img src="http://www.cs.washington.edu/education/courses/cse190m/12sp/images/jslint.png" alt="JavaScript Lint" />
         </a>
      </h1>

      <div>
<textarea id="text" rows="18" cols="100">
Sample Item 1
Sample Item 2
Sample Item 3
Sample Item 4

Sample Item 5
Sample Item 6


Sample Item 7
</textarea>
      </div>

      <div>
         <!-- Note the "dirty" use of Javascript: onclick as an attribute -->
         <button onclick="clearAll();">Clear All</button>
         <button onclick="capitalize();">Capitalize</button>
         <button onclick="sort();">Sort</button>
         <button onclick="reverse();">Reverse</button>
         <button onclick="lineNumbers();">Add Numbers</button>
         <button onclick="stripBlank();">Strip Blank</button>
         <button onclick="shuffle();">Shuffle</button>
      </div>
   </body>
</html>

orderit.js

// orderit.js Solution by Sylvia Tashev - April 25, 2009



// grabs the contents of the text box and puts the lines in an array

function getLines() {

    var textarea = document.getElementById("text");

    return textarea.value.split("\n");

}



// replaces the contents of the text box with the result

function putLines(a) {

    var textarea = document.getElementById("text");

    textarea.value = a.join("\n");

}



// removes all text from text area

function clearAll() {

    var textarea = document.getElementById("text");

    textarea.value = "";

}



// converts to uppercase

function capitalize() {

    var textarea = document.getElementById("text");

    textarea.value = textarea.value.toUpperCase();

}



// sorts by alphabetical order

function sort() {

    var a = getLines();

    a.sort();

    putLines(a);

}



// reverses order

function reverse() {

    var a = getLines();

    a.reverse();

    putLines(a);

}



// shuffles by randomly swapping elements

function shuffle(a) {

    var a = getLines();

    for (var i = 0; i < a.length; i++) {

        // swap each element i with another randomly chosen element in

        // the range [i, a.length)

        var j = i + parseInt(Math.random() * (a.length - i));

        if (i != j) {

            var temp = a[i];  // swap

            a[i] = a[j];

            a[j] = temp;

        }

    }

    putLines(a);

}



// removes empty lines

function stripBlank() {

    var a = getLines();

    var a2 = [];

    for (var i = 0; i < a.length; i++) {

        if (a[i]) {

            a2.push(a[i]);

        }

    }

    putLines(a2);

}



// adds numbers "1. " to the front of each item

function lineNumbers(a) {

    var a = getLines();

    for (var i = 0; i < a.length; i++) {

        a[i] = (i + 1) + ". " + a[i];

    }

    putLines(a);

}

Solutions

1. Buggy JavaScript Code:

2. Font Manipulation

Add the following to font.html:

<div><button id="prettify" onclick="prettify();">Prettify</button></div>

font.js:

function prettify() {

   var text = document.getElementById("text");

   // can also use: var text = $("text");

   text.innerHTML = "Look! It's pretty!";

   

   // font styles added by JS:

   text.style.fontSize = "13pt";

   text.style.fontFamily = "Comic Sans MS";

   text.style.color = "red";

}

3. Is it Caturday?

Add the following to caturday.html:

<p><button id="button" onclick="caturday();">Is it Caturday?</button></p>

font.js:

function caturday() {

   var today = new Date();

   // var today = new Date("April 23, 2011 01:23:45");

   

   var caturday = today.getDay() == 6;

   var text = caturday ? "YES" : "NO";

   $('answer').innerHTML = text;

   document.body.className = text.toLowerCase();

}

4. Regular Expressions

regex.php:

<?php

   // This solution puts all regular expressions into an array

   // and loops over them, printing the matches for each one.

   $regexps = array (

      "/Marty/",     // 1. Both Martys

      "/Stepp/",     // 2. The Stepp Brothers

      "/hw\d/",      // 3. HW Directories

      "/abba/",      // 4. Babbage through scabbards

      "/^(yes)$/i",  // 5. Any variation of "yes"

      "/^\w{7}$/",   // 6. Words of length seven

      "/bert$/"      // 7. Characters from Dilbert

   );

   

   $lines = file("words.txt", FILE_IGNORE_NEW_LINES);

?>



<!DOCTYPE html>
<html>

   <head>

      <title>Regular Expression Tester</title>

   </head>

   <body>

      

<?php

   foreach ($regexps as $regexp) {

      ?>

      <p><strong><code><?= $regexp ?></code></strong>:</p>

      <ol>

      <?php

         foreach ($lines as $line) {

            if (preg_match($regexp, $line)) {

               ?>

               <li><?= $line ?></li>

               <?php

            }

         }

      ?>

      </ol>

      <?php

   }

?>

   </body>

</html>

5. Weight Conversion

conversions.html:

<!DOCTYPE html>
<html>
   <head>
      <title>Weight Conversion</title>
      <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"
         type="text/javascript"></script>
      <script src="conversions.js" type="text/javascript"></script>
   </head>
   <body>
      <fieldset>
         Convert <input type="text" id="input" />
         <select id="from">
            <option>kg</option>
            <option>lb</option>
         </select>
         <select id="to">
            <option>lb</option>
            <option>kg</option>
         </select>
         <button onclick="convert();">Calculate</button>
         <span id="answer"></span>
      </fieldset>
   </body>
</html>

conversions.js:

function convert() {
   value = parseInt($("input").value);
   if ($("from").value == "kg" && $("to").value == "lb") {
      value *= 2.20462262;
   } else if ($("from").value == "lb" && $("to").value == "kg") {
      value *= 0.45359237;
   }
   $("answer").innerHTML = value;
}

6. Order-It:

orderit.html

<!DOCTYPE html>
<html>
   <!-- Sylvia Tashev - April 20, 2009 -->

   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
      <title>Order-It!</title>

      <link href="orderit.css" type="text/css" rel="stylesheet" />
      <script src="http://www.cs.washington.edu/education/courses/cse190m/09sp/scriptaculous/prototype.js" type="text/javascript"></script>

      <!-- your files -->
      <script src="orderit.js" type="text/javascript"></script>
   </head>

   <body>
      <h1>
         Order-It!

         <a href="http://validator.w3.org/check/referer">
            <img src="http://www.cs.washington.edu/education/courses/cse190m/12sp/images/w3c-html.png" alt="Valid HTML" />
         </a>
         <a href="http://jigsaw.w3.org/css-validator/check/referer">
            <img src="http://www.cs.washington.edu/education/courses/cse190m/12sp/images/w3c-css.png" alt="Valid CSS" />
         </a>
         <a href="http://webster.cs.washington.edu/jslint?referer">
            <img src="http://www.cs.washington.edu/education/courses/cse190m/12sp/images/jslint.png" alt="JavaScript Lint" />
         </a>
      </h1>

      <div>
<textarea id="text" rows="18" cols="100">
Sample Item 1
Sample Item 2
Sample Item 3
Sample Item 4

Sample Item 5
Sample Item 6


Sample Item 7
</textarea>
      </div>

      <div>
         <!-- Note the "dirty" use of Javascript: onclick as an attribute -->
         <button onclick="clearAll();">Clear All</button>
         <button onclick="capitalize();">Capitalize</button>
         <button onclick="sort();">Sort</button>
         <button onclick="reverse();">Reverse</button>
         <button onclick="lineNumbers();">Add Numbers</button>
         <button onclick="stripBlank();">Strip Blank</button>
         <button onclick="shuffle();">Shuffle</button>
      </div>
   </body>
</html>

orderit.js

// orderit.js Solution by Sylvia Tashev - April 25, 2009



// grabs the contents of the text box and puts the lines in an array

function getLines() {

    var textarea = document.getElementById("text");

    return textarea.value.split("\n");

}



// replaces the contents of the text box with the result

function putLines(a) {

    var textarea = document.getElementById("text");

    textarea.value = a.join("\n");

}



// removes all text from text area

function clearAll() {

    var textarea = document.getElementById("text");

    textarea.value = "";

}



// converts to uppercase

function capitalize() {

    var textarea = document.getElementById("text");

    textarea.value = textarea.value.toUpperCase();

}



// sorts by alphabetical order

function sort() {

    var a = getLines();

    a.sort();

    putLines(a);

}



// reverses order

function reverse() {

    var a = getLines();

    a.reverse();

    putLines(a);

}



// shuffles by randomly swapping elements

function shuffle(a) {

    var a = getLines();

    for (var i = 0; i < a.length; i++) {

        // swap each element i with another randomly chosen element in

        // the range [i, a.length)

        var j = i + parseInt(Math.random() * (a.length - i));

        if (i != j) {

            var temp = a[i];  // swap

            a[i] = a[j];

            a[j] = temp;

        }

    }

    putLines(a);

}



// removes empty lines

function stripBlank() {

    var a = getLines();

    var a2 = [];

    for (var i = 0; i < a.length; i++) {

        if (a[i]) {

            a2.push(a[i]);

        }

    }

    putLines(a2);

}



// adds numbers "1. " to the front of each item

function lineNumbers(a) {

    var a = getLines();

    for (var i = 0; i < a.length; i++) {

        a[i] = (i + 1) + ". " + a[i];

    }

    putLines(a);

}

Valid HTML Valid CSS