When developing sites I am often asked to perform tasks that from the first look seem very simple. But when I dig into it I soon find out that it's turning out to be one of those things that make you go "hm...". I actually enjoy puzzling tasks, if I have the time to play. I feel victorious when I solve the problem. *
Take a look at the demo | Download zip file
The problem
I once was asked to prevent line breaks in a phone number. The client wanted to use spaces instead of hyphens. Phone number was formated like so:
0800 555 5555
So when/if the phone number reached the end of the line, it wrapped to another line. Client was little annoyed with it and wanted it fixed. Ok, let's take a look at the possible solutions.
First solution that came to mind was hardcoding non-breaking spaces. The source code would look like this:
0800 555 5555
Problem solved!
Another awesome solution is placing the number inside a container element, assign class name to the container like so:
<span class="num">0800 555 5555</span>
and edit css:
.num{
white-space:nowrap;
}
There! Another day saved, now I am off to play some racket-ball. **
I wouldn't give it another thought If my client didn't call me in a few days saying that he updated the code and he had the same issue with another phone number. Ok, so I need to find a way to automate things...
The Script
After doing some thinking, I decided to use regular expressions. The idea was to:
- extract the html from a certain object
- use regular expression to search for a predefined pattern
- wrap the part of the string that matches the pattern into span (with a certain class name)
- put the updated html back
This simple yet effective script does exactly that:
this.preventBreaks = function(){
/* */
var id = "text";
/* edit pattern here */
var pattern = /\d{4}\s\d{3}\s\d{4}/g;
/* */
var obj = document.getElementById(id);
if(obj){
var html = obj.innerHTML;
var nhtml = html.replace(pattern,function(r){return ""+r+""})
obj.innerHTML = nhtml;
};
};
Variable id should be the id of the container element - the element with all the text :)
The script should be invoked when the page loads. When not using jQuery (and that is rarely the case) I use addEvent script that I found somewhere a long time ago. Forgive me for not linking to script's author, I really forgot where I found it.
this.addEvent = function(obj,type,fn){
if(obj.attachEvent){
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn](window.event );}
obj.attachEvent('on'+type, obj[type+fn]);
} else {
obj.addEventListener(type,fn,false);
};
};
addEvent(window,"load",preventBreaks);
Of course, CSS will prevent line breaking with white-space property set to nowrap
span.num{
white-space:nowrap;
}
Regular Expression
Constructing regular expression is the only tricky part here. Don't worry, you don't have to be regex ninja *** to understand this. Let's take a look at our regular expression:
/\d{4}\s\d{3}\s\d{4}/g
As explained here, here and here
/d matches all digit character 0-9
/d3 actually means that we have 3 digits in a row
/s matches any white space character
g global search for all occurrences of a pattern
so when we write:
/\d{4}\s\d{3}\s\d{4}/g
we actually have:
/ 4 digits -> white space -> 3 digits -> white space -> 4 digits / apply globally
Following the same principle you will be able to construct your own pattern. Here's another example. The phone number is formated like this:
(555) 555 5555
The regex for this will look like:
/\(\d{3}\)\s\d{3}\s\d{4}/g
which means:
/ open bracket -> 3 digits -> close bracket -> white space -> 3 digits -> white space -> 4 digits / apply globally
Another example:
+1 555 555 5555
Regular expression:
/\+\d\s\d{3}\s\d{3}\s\d{4}/g
means:
/ plus -> digit -> white space -> 3 digits -> white space -> 3 digits -> white space -> 4 digits / apply globally
Note that + and brackets () are special characters so you match those you have to put backslash in front of them.
One step further.
I soon realized that this script would be also applicable if you want to prevent line breaks for specific text phrases. For instance if you have a company called "Alen's Awesome Pizza" and you'd hate to see that beautiful name break you can use this script. Edit regular expression to match the name like so:
/Alen's Awesome Pizza/g
and that's it. Hope you found it useful!
* this particular task wasn't so difficult but I enjoyed it anyway.
** just kidding about the racket-ball, I don't play it. I smash into walls far too often!
*** please note that I am not regex ninja either. Samples you see are probably not the best ones but they work.
Abdullah 15 Dec, 2008
Sameer 7 Jan, 2009