Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Focusing on an element via anonymous function

Actually, the most challenging part of this post was the title. Defining its content in a few words was not so easy as writing it.

The problem is writing a piece of JavaScript code to set the focus on an element in the HTML page when the page is loaded. It is a pretty simple issue, but I felt it was worthy spending a few words.

Say that we want to put the focus on an element named "focusMe" when the page is loaded. This is the code that does the trick:

<script type="text/javascript">
window.onload = function () { document.getElementById('focusMe').focus(); }

// ...
</script>

The code included in the function body should be clear: we get the element with id "focusMe" and call focus() on it.

More interesting is how we assign it to the window onload property, the one responsible to keep the reference to the function that has to be called at page load time: we create a function with no name, and we include in its body the code we want to be called.

We could have given any name to this function, but why bother? the only caller of this piece of code already know where to find it, and no one else would need it.

Go to the full post

Class method

We have seen that a method could be assigned to any instance of a given class, or could be put in the class prototype, and having the same behaviour: a full access to all the other properties and methods in the class.

But we can also define a method as class member. This method wouldn't see "this", so could be used only to access class properties and methods.

To create a new class method we simply create it at class level, like this:

BlogEntry.showSignature = function() {
alert(BlogEntry.prototype.signature);
}

More information on custom objects in chapter ten of Head First JavaScript.

Go to the full post

Extending standard classes

We have another change request of our toy blog manager. The user is happy with the signature we added at the end of each post, but he is not so happy with the format we are using to display the post date. He wants it to be showed in an his own specific format.

This is quite a nuisance 'cause we can't use a standard method but we have to create a brand new one. On the other side it is very easy to add a custom method to an existing class (even a standard one): it is just a matter of adding a new function to the prototype object of the class.

Here what we do for customizing Date:

Date.prototype.shortFormat = function() {
return this.getDate() + "/" + this.getMonth() + "/" + this.getFullYear();
}

Now we can call shortFormat() from any date objects in our code:

BlogEntry.prototype.toHTML = function() {
return "<b><i>(" + this.date.shortFormat() + ")</i> " + this.title +
"</b><br />" + this.body + "<br /><i>" + this.signature +"</i>";
}

More information on custom objects in chapter ten of Head First JavaScript.

Go to the full post

Class properties

We have just seen that makes sense putting the method definition in the prototype property of a class, and now it comes natural to us asking: and what about properties?

It could make sense too. But only if you really need that the same piece of information is shared among all the objects of that kind.

Let's say we want to show a signature at the end of each post in our simple blog. The signature should be the same for all the posts, so in this case it makes sense to have it defined as class property. Curiosly enough, even though a class property is not related with a single instance of the class, when we want to access it from a class method we have to qualify it by using "this". It is kind of obvious, though, if we think that it is actually stored in the prototype property, that is accessed as a normal property in a object.

In the coding of the class this resolves in adding the definition of the signature property and using it in the required methods:

BlogEntry.prototype.signature = "The blog owner";

BlogEntry.prototype.toHTML = function() {
return "<b><i>(" + this.date.toDateString() + ")</i> " + this.title +
"</b><br />" + this.body + "<br /><i>" + this.signature +"</i>";
}


More information on custom objects in chapter ten of Head First JavaScript.

Go to the full post

Assigning methods to prototype

We have implemented a simple JavaScript class defining a few methods in the constructor. There is a better way of doing it, using the prototype property.

Every class has its own property property, that is a sort of blueprint used to create a new object of that kind. So, instead of creating a different instance of the same method for each instantiated object, we can have a unique method for each instance of that class.

To get this result we rearrange the code in this way:

function BlogEntry(title, body, date) {
this.title = title;
this.body = body;
this.date = (typeof(date) == "undefined" || date == null) ? new Date() : date;
}

BlogEntry.prototype.toString = function() {
return this.title + " (" + this.date.toDateString() + "): " + this.body;
}

BlogEntry.prototype.toHTML = function() {
return "<b><i>(" + this.date.toDateString() + ")</i> " + this.title +
"</b><br />" + this.body;
}


More information on custom objects in chapter ten of Head First JavaScript.

Go to the full post

Random post

Our simple little blog manager is boring. We want to enjoy the thrill of reading a random post, and we can do it easily using a couple of mathematical methods made available to our JavaScript code by the Math class.

We are going to use Math.random(), that gives us a pseudo-random number in (0,1), and Math.floor() that truncates a number to the lower integer.

We add a button to the HTML code and make it call, as onclick reaction, this function:

function randomPost() {
var i = Math.floor(Math.random() * blog.length);
var element = resetBlog();
showPost(element, i, false);
}

Math.random() generates a number in (0,1), we multiply it for the number of items in the blog, and then we reduce it to an integer in [0, blog.length - 1] through Math.floor().

More information on the JavaScript Object Oriented features in chapter nine of Head First JavaScript. The code here is heavily based on an example you can find in this fun and useful book.

Go to the full post

String searching

A common requirement for a blog is a way to search for the post having a specific text in it. A requirement that could be easily implemented considering that any string in JavaString is actually an instance of the class String, that offers a bunch of useful methods. Among them indexOf() that returns the index of the passed substring in the current string, if it is there, or -1.

First thing, let's change the HTML for our blog, adding a button and a text input element, so that the user could perform a search:

<input id="btnSearch" type="button" value="Search the blog" />
<input id="txtSearch" type="text"/>

In the script, we specify the onclick behaviour for the search button:
document.getElementById("btnSearch").onclick = searchBlog;
The search function is this:

function searchBlog() {
var element = resetBlog(); // 1.

var text = document.getElementById("txtSearch").value; // 2.
var found = false;
var yellow = false;

for(var i = 0; i < blog.length; ++i) { // 3.
if(blog[i].body.indexOf(text) != -1) { // 4.
showPost(element, i, yellow); // 5.
yellow = !yellow;
found = true;
}
}

if(!found)
showNoPost(element); // 6.
}

1. remove all elements previously in the blog section
2. get the searching text specified by the user
3. loop on all the blog items
4. call indexOf() on the current post body, looking for the search text
5. show the post - yellow is a boolean set alternatively to true and false, to alternate the text background
6. if no post has been found display a dummy element

The resetBlog() function was part of the already existing showBlog() function, I have extracted its functionality in a new function so that it could be used here too, without duplicating code:

function resetBlog() {
var element = document.getElementById("blog");

while(element.firstChild)
element.removeChild(element.firstChild);

return element;
}

The showPost() function has been redesigned to be more flexible, now the decision if the background color should be yellow is left to the caller:

function showPost(element, i, yellow) {
var newNode = document.createElement("p");
newNode.appendChild(document.createTextNode(""));
newNode.innerHTML = blog[i].toHTML();
if(yellow)
newNode.setAttribute("style", "background-color: yellow");
element.appendChild(newNode);
}

A dummy element is put as child of the passed element by this function:

function showNoPost(element) {
var newNode = document.createElement("p");
newNode.appendChild(document.createTextNode("No item selected"));
newNode.setAttribute("style", "background-color: orange");
element.appendChild(newNode);
}


More information on the JavaScript Object Oriented features in chapter nine of Head First JavaScript. The code here is heavily based on an example you can find in this fun and useful book.

Go to the full post

Array sorting

Now that we have provided a date field to our blog, it strucks to us that maybe we should provide a way to keep it ordered.

This is very easy to be done, because the JavaScript Array class has a method sort() that is exactely what we want.

What we have to do is just call sort() on blog before using it:

window.onload = function(evt) {
blog.sort();
showBlog(2);
// ...

This way of sorting could be enough sometimes, but not in our case. We sorted the array using the standard comparison algorithm applied to the first field in the array. So we have our blog ordered alphabetically by post title.

Hardly what we usually expect.

To specify a different field and a different sorting comparison we pass a function to the sort() method. This function has to accept in input two parameters, the two array items that are about to be compared, and return an integer that should be:
  • less than zero if the first parameter should be before the second
  • zero if they are considered equal
  • greater than zero if the second parameter should be before the first
So here is a couple of function we can use to sort our blog by date:

// older first
function compare1(post1, post2) {
return post1.date - post2.date;
}

// newer first
function compare2(post1, post2) {
return post2.date - post1.date;
}

We use that functions calling sort() like this:
blog.sort(compare);
But can avoid creating a function that should be used just for one single call, and use a anonymous function. Here we choose to implement the "newer first" behaviour, that is the standard for blogs:
blog.sort(function(post1, post2) {return post2.date - post1.date;});

More information on the JavaScript Object Oriented features in chapter nine of Head First JavaScript. The code here is heavily based on an example you can find in this fun and useful book.

Go to the full post

Dating a blog

The simple blog we create is so cute, that we decide give it a few improvements.

First of all, what's a blog without a date for each post? Managing dates it's a common task, so JavaScript provides a class for doing that, Date.

There are a few alternative constructors for a Date object: we can call the no-argument one creates a date for the moment we call it; or we can pass it year, month, day, ... all of them as integer (but remember: January is the month number 0, and December is 11), or we can pass the date as a string, in american format (month/day/year).

Once we have a Date object we can convert it in a readable string using a few method, toDateString() is one of them, providing a representation that is often what we are looking for.

Let's rewrite our BlogEntry class having a Date among its properties. We want preserve the existing code, so we are ready for the case the constructor is passed without specifying a date. In this case, from the point of view of the JavaScript interpreter, we say that the type of the passed date is undefined. For better robustness of our code we check also if the passed date is null, in both case we translate that as a user request to use the current date:

function BlogEntry(title, body, date) {
this.title = title;
this.body = body;
this.date = (typeof(date) == "undefined" || date == null) ? new Date() : date;

this.toString = function() {
return this.title + " (" + this.date.toDateString() + "): " + this.body;
}

this.toHTML = function() {
return "<b><i>(" + this.date.toDateString() + ")</i> " + this.title +
"</b><br />" + this.body;
}
}

Now we change our predefined blog entries:

var blog = [ new BlogEntry("Welcome", "Welcome to my new blog", new Date(2005, 11, 31)),
new BlogEntry("Last one", "Today's news"),
new BlogEntry("Again me!", "Many things to say", new Date("01/02/2006")),
new BlogEntry("Summertime", "I'm so <b>busy</b>!", new Date("07/15/2007")) ];

And we enjoy the view.

More information on the JavaScript Object Oriented features in chapter nine of Head First JavaScript. The code here is heavily based on an example you can find in this fun and useful book.

Go to the full post

Class with JavaScript

JavaScript is (kind of weak) object oriented programming language. We can create our own classes, and use them to improve the readability of our code.

Here we'll write a simple blog manager based on a custom class, BlogEntry.

We will use it in an HTML page simple like this:

<h3>Welcome to My Blog</h3>
<div id="blog"></div>
<input id="btnShowAll" type="button" value="Show all entries" />

Just a div section, where we'll put our blog posts, and a button to show them all.

In the script section we specify the window onload behavior in this way:

window.onload = function(evt) {
showBlog(2);

document.getElementById("btnShowAll").onclick = function() {showBlog(blog.length);}
}

As the page is loaded, we call the showBlog() function to show a couple of items. And we associate to the button onclick property a call to the same showBlog() function, asking to show all the items in the blog. Before defining the function, and the blog itself, we need to define the BlogEntry class.

To define a JavaScript class we simply have to write its constructor, that carries the definition of the class properties and methods. So, here is our class, having title and body for a blog post, and a couple of methods to make them available as plain text, or in a fancy HTML format:

function BlogEntry(title, body) {
this.title = title;
this.body = body;

this.toString = function() {
return this.title + ": " + this.body;
}

this.toHTML = function() {
return "<b>" + this.title + "</b><br />" + this.body;
}
}

Given that, we define an array of a few blog entries:

var blog = [ new BlogEntry("Welcome", "Welcome to my new blog"),
new BlogEntry("Post 2", "Another <u>thrilling</u> post"),
new BlogEntry("Again me!", "Many things to say"),
new BlogEntry("Last one", "I am so busy with this blog!") ];

Now make sense writing the showBlog() function:

function showBlog(nr) {
const len = (nr < blog.length) ? nr : blog.length;
var element = document.getElementById("blog");

while(element.firstChild)
element.removeChild(element.firstChild);

for(var i = 0; i < len; ++i) {
showPost(element, i);
}
}

We don't trust the caller of our function so, instead of using the parameter nr, we use len, that is not bigger than the number of items in the blog array.

We get the blog element from the HTML page, we remove all its children (to avoid double insertions) and then we call the showPost() to put in all the required items:

function showPost(element, i) {
var newNode = document.createElement("p");
newNode.appendChild(document.createTextNode(""));
newNode.innerHTML = blog[i].toHTML();
if(i%2 == 0)
newNode.setAttribute("style", "background-color: yellow");
element.appendChild(newNode);
}

We append as a child to the passed element a new node, a "p" element in which we put as innerHTML the string returned by toHTML() called on the i element of the array blog. If we were not interested in fancy HTML formatting, we could have avoided using innerHTML (so practical but non-standard) and putting the result from a call to BlogEntry.toString() directly in the createTextNode() call.

To embellish a bit our page, we se the background color for alternate items in the blog, making it more readable.

More information on the JavaScript Object Oriented features in chapter nine of Head First JavaScript. The code here is heavily based on an example you can find in this fun and useful book.

Go to the full post

Making history

If we can change text in a element, we also can add a completely new node in the DOM structure of a page.

We can use this feature to dinamically change the content of our HTML page to show live the decisions we are taking.

In our HTML we add a couple of buttons, as a way to take decisions:

<p>
<input type="button" id="btnLeft" value="Left" onclick="cmdButton(true)" />
<input type="button" id="btnRight" value="Right" onclick="cmdButton(false)" />
</p>

At bottom page we add a div section, where we are going to put the decisions history:

<div id="history">
</div>

In the script tag we add a variable definition, to keep track of the current step:
var currentStep = 0;
Then we define the function called to react to the buttons onclick event - currently it doesn't do much, just increasing the current step and calling a function that add a new entry in the history section:

function cmdButton(left) {
++currentStep;
setHistory(left);
}

And finally here is the real point of interest of this post. In setHistory() we get the node where we keep the history, create a new "p" element, adding to it a new text child, containing the information that we want to store, and then appending the "p" element to the history:

function setHistory(left) {
var history = document.getElementById("history");
var newNode = document.createElement("p");
var newText = document.createTextNode("Decision " + currentStep +
": you clicked " + (left ? "left" : "right"));
newNode.appendChild(newText);
history.appendChild(newNode);
}

More details on DOM in chapter eight of Head First JavaScript.

Go to the full post

Using a DOM approach instead of innerHTML

We have already seen how to modify the text (actually, an HTML fragment) included in an element accessing its innerHTML property.

The issue is that innerHTML is not a standard property, so we shouldn't actually rely on it. Expecially if we consider that we cand do the same considering the element as a node in the document, accordingly to the DOM (Document Object Model), and accessing its included text as its child.

To see this approach in action let's build an HTML page containing an image and its caption. We want our JavaScript being able to initialize and change the actual picture and text, so we put just the structure in the HTML code, and leave to the script the fun of assigning the content:

<body>
<div style="margin-top: 100px; text-align: center;">
<p><img id="sceneImg" alt="" src=""></p>
<div id="sceneTxt"></div>
</div>
</body>

We initialize the HTML from the script assiging an anonymous callback function to window.onload. Here we see what we were used to do, using innerHTML:

window.onload = function(evt) {
document.getElementById("sceneImg").alt = "The first scene image";
document.getElementById("sceneImg").src = "scene1.png";
document.getElementById("sceneTxt").innerHTML = "This is the first scene";
}

The same result of calling the third line could be achieved removing all the children from the node "sceneTxt" and assigning to it a new text node containing the requested string. To keep the code simpler, we could use a short function like this:

function setTextElement(elemId, newTest) {
var node = document.getElementById(elemId);
while(node.firstChild)
node.removeChild(node.firstChild);
node.appendChild(document.createTextNode("This is the first scene"))
}

That would be called from the anonymous function in this way:
setTextElement("sceneTxt", "This is the first scene");

More details on DOM in chapter eight of Head First JavaScript.

Go to the full post

Regular expressions with JavaScript

We could build by hand complex validation functions for our JavaScript code, but it is not a good idea. We should use instead the regular expession tool that is part of the JavaScript engine, that is close enough to other popular regex engines, like the Perl one.

In JavaScript, a regular expression is an object of a specific class (RegExp) that is created in a specific way. For instance, here is a regular expression that defines a ZIP code respecting the rule "a string of exactely 5 digit":
var pattern = /^\d{5}$/
A regular expression is delimited by two slashes. So, if we want to put a slash in a regular expression we need to escape it with a backslash.

The first character in our first regex is a "^" that stands as a marker for the beginning of the string, then we have a "\d", meaning a digit, than a specifier "{5}" that tells us that the regex is expecting 5 items just specified, i.e. five digits, and finally a "$", marker for the end of the string.

Reading all together this means: we are expecting a string described from the beginning to the end by exactely 5 digits.

To start using regular expression in JavaScript you should have a grasp on a few metacharacters:
  • . = any character but a newline
  • \d = any digit
  • \w = any alphanumeric character
  • \s = any whitespace (blank, tab, return, newline)
  • ^ = marker to the beginning of text
  • $ = marker to the end of text
  • * = preceding subpattern appears 0+ times
  • + = preceding subpattern appears 1+ times
  • ? = preceding subpattern appears 0 or 1 time
  • {n} = preceding subpattern appears exactely n times
  • () = delimiter for a subpattern

Once we create a regex, it is easy to check if a string comply to its request, we just call the method test() on the regex passing the string to be tested as parameter. Here is a function we can use to validate our text inputs:

function patternCheck(fldInput, regex, fldHelp) {

if(!regex.test(fldInput.value)) {
if(fldHelp != null) {
fldHelp.innerHTML = "Should match the pattern: " + regex.source;
return;
}
}
else {
if(fldHelp != null)
fldHelp.innerHTML = "";
}
}

In the source property of the regex we have access to the regular expression as a string, we display it to the user as an hint for the reason why we didn't accept his input - hoping this is not gibberish to him.

This is the HTML block that would display a text input for a ZIP:

<p>ZIP code:
<input id="zipId" name="zip" type="text" size="5"
onblur="patternCheck(this, /^\d{5}$/, document.getElementById('zipHlp'))" />
<i><span id="zipHlp"></span></i></p>

If we want to specify a valid range for the number of elements that should be in a regular expression, we can use the construct {min,max}, meaning that there should be at least "min" elements, and at the most "max" of them.

So we can rewrite the text input we should accept 3-12 character string in this way:

<p>Your input:
<input id="msgId" name="message" type="text" size="10"
onblur="patternCheck(this, /^\w{3,12}$/, document.getElementById('msgHlp'))" />
<i><span id="msgHlp"></span></i></p>

We can offer a limited option to the user, using the "|" operator. Here is how we permit to input just "blue" or "red":

<p>Color:
<input id="colorId" name="color" type="text" size="10"
onblur="patternCheck(this, /^(blue|red)$/, document.getElementById('colorHlp'))" />
<i><span id="colorHlp"></span></i></p>


More details on regular expression in chapter seven of Head First JavaScript.

Go to the full post

Changing the innerHTML

Popping up windows is not considered a good way of user interaction. Often is better to think of another way, less intrusive, to communicate.

With JavaScript we can modify the text in a HTML element, changing in this way the actual page, changing the content of its innerHTML property.

Let's use this capability to improve the input text validation example.

We change the HTML adding a "span" element, initially empty, just after our text input.
We change the validation function, too, to accept in input both the text input and the related span element:

<form name="order" action="notImplemented" method="POST">
<p>Your input:
<input id="msgId" name="message" type="text" size="40"
onblur="basicCheck(this, document.getElementById('msgHlp'))" />
<i><span id="msgHlp"></span></i></p>
<input type="button" value="Do it" onclick="doSomething(this.form);" />
</form>

The idea is that we are going to put a message in the "span" element, if the text input is not valid.

We change the validation function in this way:

function basicCheck(fldInput, fldHelp) {
if(fldInput.value.length == 0) {
if(fldHelp != null)
fldHelp.innerHTML = "Please enter a value";
fldInput.focus();
}
else {
// ensure no help message is showed when not required
if(fldHelp != null)
fldHelp.innerHTML = "";
}
}

If a fldHelp is specified, and if the string in fldInput is empty, the fldHelp text is set to a helper text.

More details on this stuff in chapter seven of Head First JavaScript.

Go to the full post

Validation: accessing a field in a form

We want to ensure that a text input we put in a HTML form is not empty. To do that we have to associate a function to the event handler onblur (meaning: we are leaving the element), and we should pass the element itself to the checking function.

We have a really this simple form:

<form name="order" action="notImplemented" method="POST">
<input id="msgId" name="message" type="text" size="40" onblur="basicCheck(this)" />
<input type="button" value="Do it" onclick="doSomething(this.form);" />
</form>

When we leave the text input, an onblur event is generated, and so the function basicCheck() is called.
The parameter "this" is a reference to the element that was in control, so, the text input itself.

Here is how we check the text input value:

function basicCheck(inputField) {
if(inputField.value.length == 0) {
alert("Please enter a value");
inputField.focus();
}
}

In the parameter inputField we have the "this" referring to the text input. In its "value" property we have the string input by the user. In "length" is stored is actual length, so we check it against zero.

In case of empty text, we issue an alert, reset the focus on the "bad" input, and return the control to the user.

As a bonus, in this post we have a look to the onclick for the button in our minimal form. A function is called passing the form associated with the button itself, meaning, the form that contains the button (and incidentally, the text input too).

The idea is that in this way we have an easy access to the element in the form from the function:

function doSomething(form) {
alert("You wanted to do something with: " + form["message"].value);
alert("But you can't do anything here with: " + form.message.value);
}

Not a big function, but it shows us how we can access the elements in a form. We can use the array notation, (form["message"].value), or the "dot" notation, form.message.value, for getting absolutely the same result.

More details on this stuff in chapter seven of Head First JavaScript.

Go to the full post

Callback with JavaScript

We are about to see a way to get a better separation between our JavaScript code from the HTML body.

Instead of relying on the onXXX tag attributes, we can access the even handlers from the inside of the script tag, leaving the HTML body cleaner and easier to maintain.

To do that we use the callback mechanism, that require us to manage the function address as a variable. Good news is that it quite easy to be done with JavaScript.

The basic fact is that we can see onload, that we have previously accessed as attribute of the body tag, as property of the JavaScript object "window". So we can actually use it to react on the event signalling the page has been completely loaded.

The twist is that we should put in it not a string but the address of a function that we want to be called. Luckly that is pretty easy to be done in JavaScript: just remove the brackets. So, if we had that:
<body onload="greet()"><!-- ... --->
In a script tag, we can write this:
window.onload = greet;

Actually, there is another thing. The event handler expects to be given the address of a function that accept one parameter, a so called object event. But JavaScript is a very permessive language, and there is no complain for passing something different. In any case, to avoid misunderstanding, it would be better to explicitely show that parameter in the definition of the called function, even if it is not used:

function greet(evt) {
// ...
}

It is handy sometimes using an anonymous function. Obviously this makes sense only for a function that has to be used once, like could be one that is used as callback for an event handler. And actually is typical to a piece of code like this:

window.onload = function(evt) {
// ...
}

Here the anonymous function, accepting in input an object event, represents the code that would be called as callback when the page is loaded. At that moment the JavaScript code has access to the elements defined in the page body.

So, we put inside this function all the connection between the HTML and the JavaScript. In a way, this is a sort of constructor for the script.

For instance, let's say that we have this element in the HTML body:

<div style="margin-top:100px; text-align:center">
<img id="rock" src="image1.png" alt="Bored" style="cursor:pointer" />
</div>

And we want that clicking on that element would result calling:

function comment(index) {
alert("You are accessing item " + index);
}

passing as index 42.

Instead of using the HTML attribute onclick in the element tag, we could write our onload callback function in this way:

window.onload = function(evt) {
document.getElementById("rock").onclick = function(evt) { comment(42); };
}


More on JavaScript functions in chapter six of Head First JavaScript.

Go to the full post

Cookies in action

We can use the cookie functions we have just written to improve again our interactive page giving it a way of remembering the user name, so to use it even when the user return to the page after a while.

First thing, we store the utility function in a text file in the same directory of our HTML page. The usual extension for JavaScript is js, so we call it "cookie.js". Then to include it in the HTML page we use this directive:
<script type="text/javascript" src="cookie.js"></script>

Now we modify the existing code, in the already existing script tag. First step is adding a constant, to define the name of the cookie we are about to use:

<script type="text/javascript">
var userName;
const COOKIE_NAME = "name";

<!-- ... -->

The navigator.cookieEnabled flag tells us if we have it available. Only if it is true we can work with them. So, we modify the greet() function to read the user name stored in the cookie (when possible), if have a name we use it to greet the user, otherwise to use a anonymous way to greeting him:

function greet() {
if(navigator.cookieEnabled)
userName = readCookie(COOKIE_NAME);

if(userName) {
alert("Hello " + userName + ", I missed you.");
setHappy(true);
}
else
alert("Hello from a whimsical page!");
}

Then we rewrite the touchMe() function, moving the input request in the getName() function:

function getName() {
userName = prompt("What is your name?", "Enter your name here.");
if (userName) {
alert("Nice meeting you, " + userName + ".");
if(navigator.cookieEnabled)
writeCookie(COOKIE_NAME, userName, 30);
else
alert("Cookie not enabled - I won't remember you for long.");
}
}

function touchMe() {
if (userName)
alert("I like the attention, " + userName + ". Thank you.");
else
getName();

setHappy(true);
}


More on JavaScript cookies in chapter three of Head First JavaScript.

Go to the full post

Persistence by cookies

We can't access the secondary store on the local machine with JavaScript, with the exception of cookies. So, we use a cookie to store basic information for a page.

A cookie is identified by a unique name, it is used to store a value, and it has an expiration date. All the cookies are stored in a string associated to the current web page, that makes them a bit wierd to manage. So it is customary to write a tiny library of JavaScript functions to keep easy the user code.

Here is how we are going to save a cookie:

function writeCookie(name, value, secs) {
// by default the cookie is temporary
var expires = "";

// cookie persistent for the passed number of seconds
if(secs) {
var date = new Date();
date.setTime(date.getTime() + secs * 1000);
expires = "; expires=" + date.toGMTString();
}

// set the cookie to the name, value, and expiration date
document.cookie = name + "=" + value + expires + "; path=/";
}

Normally, it would be more useful if the third parameter of writeCookie() was the number of days. But for testing purposes it is handy having a cookie that expires in a few seconds.

Once a cookie is stored, we should retrieve it:

function readCookie(name) {
var searchName = name + "=";
var cookies = document.cookie.split(';');
for(var i=0; i < cookies.length; i++) {
var c = cookies[i];
while (c.charAt(0) == ' ')
c = c.substring(1, c.length);
if (c.indexOf(searchName) == 0)
return c.substring(searchName.length, c.length);
}
return null;
}

As we said, the code is a bit involute. We split document.cookie in an array of cookies, using semicolon (";") as delimiter. [This is cool, but it leads to the inconvenience that we can't store semicolon in our cookie!]
Then we loop on all the cookies, we skip all the trailing blanks, and check for the key, if we find it then we return the substring starting just after the equal sign to the end of the current cookie.

To erase a cookie we just change it assigning a negative value as expiration:

function eraseCookie(name) {
writeCookie(name, "", -1);
}


More on JavaScript cookies in chapter three of Head First JavaScript.

Go to the full post

Size matters

We have showed a picture to the user. The issue now is that we have no idea of the client window size, that means our picture could be look to the user ridiculy small, or too huge to be seen completely.

So we should rescale the image, and we can do that changing the height (part of the style attribute) for our image, referring to the clientHeight of the document body.

We create a function to do this job:

function resizeMe() {
document.getElementById("rock").style.height =
(document.body.clientHeight - 100) * 0.9;
}

We want call this function as soon as the page is loaded, so we put it in the onload attribute of the body tag:

<body onload="resizeMe(); greet();">
<!-- ... -->
</body>

It is worth noting that it is possible to insert code snippet as argument for the onload attribute, and not just the name of a function.

The attribute onload is the event handler called when the page is loaded for the first time, or reloaded by the user (clicking on F5, for instance). But what we can do to resize our image when the user resize the browser window? Easy solution: we use the onresize attribute:

<body onload="resizeMe(); greet();" onresize="resizeMe()">
<!-- ... -->
</body>

But beware: even if onresize is widely used, it is not (yet) a standard attribute. It should be part of HTML5.

Based on an example found in chapter three of Head First JavaScript, a good book for a new starter.

Go to the full post

Timeout rocks!

We can execute a JavaScript function after a specified delay using setTimeout(). If we want to run a function many times say, any 15 seconds, we can use setInterval().

Here we'll see how to use setTimeout() - setInterval() is quite the same, just remember that to stop it calling the associated function we could call clearInterval() - in an example that is meant to be an extension of the already seen basic JavaScript example.

The point of the code is that when we click on the picture, it is changed with a second one, but the new one shift automatically back to the default after a while (specified in millisecs):

<html>
<head>
<title>A whimsical page</title>

<script type="text/javascript">
var userName;

function greet() {
alert("Hello from a whimsical page!");
}

function setHappy(happy) {
var element = document.getElementById('rock');

if(happy) {
element.src = "image2.png";
element.alt = "Happy";
}
else {
element.src = "image1.png";
element.alt = "Bored";
}
}

function touchMe() {
if (userName) {
alert("I like the attention, " + userName + ". Thank you.");
}
else {
userName = prompt("What is your name?", "Enter your name here.");
if (userName)
alert("Nice meeting you, " + userName + ".");
}

setHappy(true);

setTimeout("setHappy(false)", 3000);
}
</script>
</head>

<body onload="greet()">
<div style="margin-top:100px; text-align:center">
<img id="rock" src="image1.png" alt="Bored" style="cursor:pointer" onclick="touchMe()" />
</div>
</body>
</html>


Post based on an example found in chapter three of Head First JavaScript, you should read it too, if you want more details, and some fun, too.

Go to the full post