JavaScript and JQuery: Add Two Numbers… and fail.

In which I program with JavaScript and JQuery 1.1.4, write a sample HTML and JavaScript page to add two numbers together. And fail.

The goal:

This was a goal in writing a program in JavaScript to add two numbers. I picked jQuery as the “less evil than working directly in the DOM” solution. The entire application runs in one web page. Writing this program was significantly harder than a “hello world” program, but still manageable. At least, easy to get sort of working.

Step 1: Find the tools.

JQuery is the emerging library of choice for working in JavaScript. It smooths over most of the odd differences between browsers and brings a little sanity to the world. There are a million extensions for better UI elements, form validation, and such. I stuck to the basic jQuery for its stability and popularity.

As a library, jQuery is just a big JavaScript file which defines a couple entry points into a library of functions. It gets little enhancements between versions; while I used version 1.4.2, your experience and knowledge will work for future versions. You can read the jQuery source code, and Paul Irish has a great screencast of what they learned by reading it. As long as you are watching video, you should watch JavaScript, the Good Parts.

Next, I looked at tools. I tried to use Eclipse, and installed the web editor. I looked at Aptana, which is a customized version of Eclipse, though it didn’t really help either.  The w3schools TryIt box gave instant feedback for little tests.  I also used FireBug with FireQuery, which worked exceedingly well. FireBug is an extension to FireFox that debugs web pages and JavaScript; FireQuery adds clean debugging for jQuery calls. My final toolset ended up as Vim, FireBug and FireQuery.

JQuery documentation works well. Most quick Google hits for docuementation ended up at the jQuery site. Also, the w3Schools jQuery tutorial provides good information.  Also helping was a random chunk of code from a friend’s large JavaScript project.  I use Safari Books Online for books, and skimmed the JavaScript the Good Parts book.   I also evaluated some the of the books on jQuery.  I looked at quick reference sheets.  My advice is to skip all the books, stick to Google and w3schools.

Step 2: The Application

My application had a simple defined goal:

Have two input boxes. When a number is entered into an input box, the sum of the two input boxes is updated whenever the boxes are changed.

I downloaded the latest version of jQuery. Grab the ‘Development Version’, meaning the uncompressed version that you need to Save As “jquery.js”.  I found it faster for development to stick my JavaScript into my HTML file.  Here is my basic “hello world” to see the parts work:

<html>
<head>
  <script type="text/javascript" src="jquery.js"></script>
  <script type="text/javascript">
    /* Ready function called once after loading */
    $(document).ready(function(){
       $("#bang").html("<b> Go jQuery Go! </b>");
    });

  </script>
</head>
<body>
  <div id="bang"></div>
</body>
</html>

All the JavaScript in all my examples was  inside that ready() call.  Keeping the indentation straight in the nested mess is a pain, and I would occasionally just ignore it for a while.  Also, I kept getting the wrong prefix (#id, .class, or selector) as well has trying to use the wrong HTML tag attribute (id, class, name, etc.).  The script would happily go forward, but without any valid values or updates.    For example, were I to type:

$(".bang").html("Stop, Javascript, stop!");

the system would quietly go its way ignoring this line. This was the most common error I made in coding.

I found myself going back to quick and dirty debugging, checking each line for some silly error. I would throw up debug messages in alert boxes, which pause execution:

<script type="text/javascript">
  /* Ready function called once after loading */
  alert("In Script");
  $(document).ready(function(){
    alert("In ready")
    $("#bang").html("<b> Go jQuery Go! </b>");
    alert("Just set it. Html is now" + $("#bang").html());
  });
</script>

This gets choppy quickly as the alert boxes pile up. I used this construct and added a ‘<div id=”messages”></div>‘ to have a long line of running messages:

var messages = "";
function update_message(a_message) {
  $("#messages").html("<b>" + a_message + "</b>:" + messages);
  messages = a_message + ':' + messages;
} ;
update_message("Running");
...
update_message("step 2.  X = " + x + "and y = " + y);

Sometimes I would use the breakpoint in FireBug to stop the code in the correct scope and start typing expressions in the console.  Sometimes FireBug would find syntax errors if I noticed the ‘ERROR’ indicator on the bottom of the screen.  Remember the JavaScript, jQuery, HTML, and CSS are all utterly silent on most typos, so “don’t trust and verify” is your mantra. You can disable the test code by commenting out the function body.

I ended up with this basic code:

<html>
  <head>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
      /* Ready function called once after loading */
      $(document).ready(function(){
        var new_sum = function() {
        //$('#sum_value').html('in new_sum' + Math.random() + ' ' + $('#sum_value') + "." + $('[name=first_number]').val() + "+" + $('[name=second_number]').val());
        update_message("in new_sum");
        var first = $('[name=first_number]').val();
        var second = $('[name=second_number]').val();
        var total = parseFloat(first) + parseFloat(second);
        $('#sum_value').html(total);
        update_message("first [" + first + "] second [" + second + "] total [" + total + "]");
      }    

      var messages = "";
      function update_message(a_message) {
        $("#messages").html("<b>" + a_message + "</b>:" + messages);
        messages = a_message + ':' + messages;
      } ;
      update_message("Running");

      $('.numbers').change(function() { update_message("change"); new_sum();} );
      $('#sum_value').html('no sum yet.');
    });
    </script>
  </head>
  <body>
    <div id="messages"></div>
    <div id="title1">First Number</div>
    <input type="text" name="first_number" value="1" />
    <div id="title2">Second Number</div>
    <input type="text" name="second_number" value="2" />
    <div id="sum_title">Sum</div>
    <div id="sum_value"></div>
  </body>
</html>

Yes, JavaScript and HTML both get verbose quickly. I think the verbosity encourages the lack of comments, white space, and the long chained function calls commonly found in this type of code.  Of course, one could always claim ‘performance’.

Step 3: The Event Bugs

If you play with the code, you will find it doesn’t quite work. You need to switch away from the text field before the change event gets called. The situation gets better by catching not just the change event but also keyup and click. It still gets broken on cut and paste. I looked at Stack Overflow questions, read available documentation, experimented, and figured out that the program will never quite work.

jQuery is built on JavaScript and the HTML standards. These standards are fundamentally flawed, though some flaws get fixed like upkeep on an old house.  Most GUI toolkits would have a pair of events for “About to change value” and “Value was just changed.”. HTML and JavaScript do not.  I can catch the cut and paste events before they make a change, wait some time, and hope to catch it after the event was processed. I can make a busy loop which just updates the total every little bit of time.  Still, it will never be perfect. “Good enough” appears to be the mantra for web programming.

So, that’s the experiment. It took about a day, mostly figuring out the event bugs and that the problem could not be properly fixed. As always, if there enough questions or comments, I’ll expand the blog entry.

0 comments ↓

There are no comments yet...Kick things off by filling out the form below.

Leave a Comment