nooshu - Matt Hobbs' Web Development Blog

Kneeling on the shoulders of giants

Category: HTML

A Hypertext Markup Language post all versions from HTML 4, XHTML and HTML5.

Auto-spacing input field text

On a recent project, a set of wireframes landed on my desk which contained some “interesting” ideas, particularly when it came to form fields. One that really stood out was having a credit card number auto-space as the user types it into a single input box. This of course would depend completely on what type of card they are entering, as different cards have different layouts. American Express for example have a [4, 6, 5] layout, where as Visa use a [4, 4, 4, 4] number layout.

Thankfully this functionality was eventually removed from the UI specifications after concerns from myself and others were raised. Just to make this perfectly clear; I think this is a bad idea, and here is why:

  • Users are very wary when it comes entering their credit card details. Spaces magically appearing in their credit card number could freak a few of them out.
  • Most e-commerce website I’ve ever used ask for the credit card number as one long string of numbers with no spaces. Auto-spacing goes against this convention, so a user may actually go back and try to remove the spaces (I know I would).
  • Validation scripts for credit card numbers usually ask for the input to have no spaces, or will remove any spaces on submit.
  • If you do want to space out the credit card number, why not use different input boxes for each set of numbers? It looks cleaner and is simpler to implement. Just have your JavaScript automatically jump between boxes as the user types.

Even though this functionality was removed, I decided to build a prototype of it in action because… well because I can and I was bored. :) Please, (please!), whatever you do don’t use this code in production. I created it as an experiment and should be treated that way. It’s very simple to get around the auto-spacing and then all hell breaks loose! (not really, but it is easy to break).

The spacing is implemented by counting the length of the string inside the input field, but you could also monitor the current position of the cursor. Anyone wishing to do this see this excellent set of answers on Stackoverflow.

You can see the prototype here. Remember, don’t use it. It’s not big and it’s not clever :)

Remote Loading HTML5 Elements with jQuery

I ran into a rather annoying problem a few months ago while developing my travel blog; the problem of course was involving Internet Explorer. I’m used to working with WordPress as I use it all the time, but I wanted to get away from the standard pagination you find on a blog. So I decided to use jQuery 1.6.4 to pull in articles from other pages (blogname.com/page/2, blogname.com/page/3 etc). Now this is all fairly simple using the handy jQuery .load() method; point it to a URL, pull in the page, pick the bits you need and reinsert into the page. Simple! Unfortunately once I got a prototype working in ‘good’ browsers, IE8 and below was having non of it!

After a little head scratching to work out what was failing, I worked out it was because I was using HTML5 elements such as ‘article’, ‘header’ and ‘footer’. There was no problem displaying them on the page, as I’d used Remy Sharps excellent HTML5 Shiv script. It only failed when trying to pull in these ‘new’ elements via Ajax.

Note: Before you read on you’ll be happy to hear that this issue no longer occurs in jQuery 1.7.0. Horray!

If you can’t upgrade, for whatever reason, I hashed together a little work-around for browsers IE8 and below, so read on. I admit the work around isn’t pretty, but it works. I tried for a few hours to get IE8- to recognise the ‘new’ elements after an Ajax request, but to no avail. Eventually I had to wrap the HTML5 tags in a div using conditionals:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--[if lt IE 9]><div id="ieHackContainer"><![endif]-->

<article id="html5Content">
    <header>
        <h2>H2 wrapped in a header element</h2>
    </header>
    <!-- Other HTML here... -->
    <footer>
        <p>This is the footer element</p>
    </footer>
</article>

<!--[if lt IE 9]></div><![endif]-->

The div is added for browsers IE8 and below, you can then use it as a hook to pull in the elements inside the div. I was hoping that wrapping the HTML5 elements in a standard div would be the end of it, I’m afraid not. The .load() method still didn’t work, IE just ignored the elements it didn’t recognise. I used jQuerys much more customisable .ajax() method to fix the issue in IE6, 7 and 8:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//IE8- work around to load HTML5 elements into a page
$("#loadHTML5LinkOld").click(function(){
        $.ajax({
                url: "page_to_load.html",
                cache: false,
                success: function(html){
                        var HTML;
                        //Clear before load
                        $("#html5LoadHolder").empty();
                       
                        //IE: Look for the hacky wrapper before insertion
                        HTML = $(html).filter("div#ieHackContainer").html();
                       
                        //If HTML var is empty assume using newer browsers
                        if(!HTML){
                                HTML = $(html).filter("#html5Content").html();
                        }
                       
                        //Append to page
                        $("#html5LoadHolder").append(HTML);
                }
        });
       
        return false;
});

This method works in all browsers I’ve tested in as I’ve added a fall back (or should that be forward?) for newer browsers. The solution isn’t ideal (I really hate the conditional comments), but older versions of IE aren’t going away any time soon, and it works. Maybe there’s a more obvious solution that I missed? Leave a comment if there is, I’d love to know!

You can see a working example here. The page I’m loading from is here and the JavaScript in full here.

The Sieve of Eratosthenes

I recently read Prime Obsession by John Derbyshire; a book all about prime numbers and one of the worlds greatest Mathematicians: Bernhard Riemann. The books main focus is on the Riemann Hypothesis which states that:

The real part of any non-trivial zero of the Riemann zeta function is 1/2.

I’d love to say that after reading the book I understand the Maths behind it but alas I do not. That’s not surprising though as it’s a problem that has yet to be solved, 159 years after Riemann paper on “On the Number of Primes Less Than a Given Magnitude”. It doesn’t look like it’s going to be solved any time soon either! If you’re interested it’s one of the Clay Mathematics Institutes Millennium Prize Problems in which you can earn yourself US$1,000,000.

While reading Prime Obsession it mentioned an interesting method for finding prime numbers called “Sieve of Eratosthenes” (pronounced air-a-TAWS-the-nEEss). Eratosthenes was a librarian at the great library of Alexandria around 230 B.C.E. It’s quite obvious how the method works once you know it, and easy to see why it’s called a sieve. The method goes like this:

  1. Write a list of numbers in which you wish to identify the primes, say 2 – 100 (exclude 1 as it isn’t required)
  2. Take the first number 2. Leaving 2 intact, remove every second number.
  3. Move onto the next number 3. Leave 3 intact and remove every third number
  4. Take the next number 5. Leave 5 intact and take away every fifth number
  5. Repeat until you get to the end of your list

The end result is the set of prime numbers up to your given number. Essentially all you are doing is removing any number that is divisible by the 1st, 2nd… Nth number. Clever stuff!

As a little side project I decided to implement this method using JavaScript, displaying the result in the browser. You can view the demo here. For fun I created two implementations, one relying heavily on the DOM, the other only using arrays. As you’d expect the DOM method is slow; looping through large tables multiple times doesn’t make for a quick execution time. The second method using a single JavaScript array is much quicker. I’ve added a stats panel to the right hand side of the page so it’s possible to compare results from both methods over different input values.

I’ve added a limit to the number you can enter into the input box (5000), I don’t want anyone blaming me for crashing their browser by entering 10 million! :) Feel free to copy the demo if you want to see what happens at higher values.

Sieve of Eratosthenes using JavaScript

The sieve in action showing prime numbers up to 500.

Thanks goes to John Resig for his very handy Array Remove method.It made removing non-primes from the numbers array very simple indeed.

Prime Obsession is a superb book but a word of warning, it contains a lot of higher level Mathematics, so may not be to everyone’s taste. It certainly made my brain hurt at times; not always what you need on that 8am commute to work! View the demo.

Monitoring a value change on an input element

For a recent project I ran into a slight issue with the jQuery change event. It’s not an issue with jQuery, but I was quite surprised when it didn’t work as I expected. I’d set up a selection of form inputs that a user could change; once changed various calculations would be made and the values outputted to a second set of disabled input elements (demo). The inputs are disabled as they are to be calculated rather than entered manually.

I’d attached the jQuery change event to the output elements like so:

1
2
3
$("#outputs").find("input:text").bind("change", function(){
    $(this).highlightFade('red');
});

So the plan was, once an input value had been changed using the jQuery().val() method the change event would fire and it would quickly colour in and out the element (using highlightFade) to notify the user that it’s value had changed. Unfortunately the change event wasn’t firing, so I had to find another way to monitor the output elements.

What I ended up doing was using an array to hold the previous values of the input elements then checking to see if they had changed in the calculation. If changed then fire the event:

1
2
3
4
5
6
7
8
9
10
11
12
13
//Array to store the old values
var oldValues = [];        
   
//Push these values into an array which is checked on calculation
$("#valueOutput input:text").each(function(i){
   var thisValue = $(this).val();
   //If the old value is different to the new, change the colour
   if(oldValues[i] !== thisValue){
       $(this).highlightFade('red');
   }
   //Push the new value into the array
   oldValues[i] = thisValue;
});

It’s quite hard to explain exactly what’s happening so I’ve put together a small demo. Try changing one of the top input fields then tab (or click out) of the input element to recalculate. Is there an easier (or better) way to do this? Comment below.

Experimenting with Webkit form speech input

It’s been a few weeks now since I attended a Web Gaming event hosted by Mozilla and I’ve not yet had chance to write about one of the coolest features that was demonstrated: Speech input in forms. Now I must admit, I had no idea this was even possible; so it was quite a surprise when I saw the demonstration. With a few extra attributes added to a standard input box you can enable speech input:

1
<input name="speech" id="speech" type="text" x-webkit-speech speech error onwebkitspeechchange="dosomething.coolhere(true);" />

It really is that simple! You may notice the “x-webkit-speech” attribute so will have guessed it currently only works in Webkit; and as far as I’m aware only in very recent versions of Google Chrome (note: “The Input Speech API will now be available by default on Chrome’s dev-channel”). The Speech API seems very new and is still a draft, so it will be a while before it’s fully adopted by other browser vendors.

Demo of the new HTML5 Speech API

A quick demonstration of the Speech API in action.

To demonstrate the speech input I’ve put together a very simple festive demo that queries the Flickr API looking for images related to a value entered. So if you have a microphone and the dev channel of Chrome, why not give it a try. Chrome records the input of the microphone before sending it off to an external server to be processed, where a value is then sent back to the browser. At first I thought it was all processed inside the browser but I guess that’s a little to much to expect! It isn’t 100% accurate and the demo accepts Googles first guess so you may get a few strange results. The server returns multiple guesses which a user can select from, but this hasn’t been added (to my demo at least).

Since the API is very new it took a little trial and error to work out how to detect if the Speech API was available in the browser; but with a little help from Paul Irish I managed to crack it:

1
2
3
4
5
function speechcapable(){
    var elem = document.createElement('input');
    var support = 'onwebkitspeechchange' in elem || 'speech' in elem;
    return support;
}

This function will return true if the API is available. It’s worth noting that since it’s very new this function is likely to break in the future as the properties always seem to be changing. It works at the moment, so get thinking about what this brilliant new API can be used for! It’s a big plus for accessibility if used correctly and I can also see some cool applications in web gaming too. View the demo.

Currently on page 1 of 612345Last »