Activate your free membership today | Log-in

Friday, November 14th, 2008

Guid0: JavaScript GUIDs

Category: JavaScript, Library, Tip

Our own Michael Mahemoff is at it again, creating a simple little GUID generator called Guid0:

Guid0 is a GUID library for Javascript. Okay, it doesn't yet do official, bona fide, 128-bit, GUIDs yet, mainly for API design reasons. But this is a library you might find useful if you want to generate a unique ID in your Ajax app.

JAVASCRIPT:
  1.  
  2. // simple
  3. guid = new Guid();
  4. var newguid = guid.generate();
  5.  
  6. // options
  7. guid = new Guid(
  8.   {
  9.         chars: Guid.constants.base85// or you could say "abc" if you only wanted those chars to appear
  10.         epoch: "June 1, 2003",
  11.         counterSequenceLength: 2, // a counter field appended to the end
  12.         randomSequenceLength: 2 // a random field appended to the end
  13.   }
  14. );
  15.  

He is working on 128-bit support.

Posted by Dion Almaer at 6:47 am
3 Comments

++---
2.9 rating from 14 votes

Wednesday, October 1st, 2008

Finding those trailing commas

Category: Tip, Utility

Dan Fabulich got bitten by the "trailing comma" issue one too many times, so he created a script to solve his problem:

“How many thousands of developer hours have been lost to random IE bugs like this?” I asked myself. I decided that there had to be a good way to detect this problem in an automated way, without firing up a copy of IE and running a full test suite.

It turns out that these and other syntax errors can be detected automatically from the Windows command line, using the Windows Scripting Host (WSH). On Windows XP and higher, the command-line tool “cscript.exe” can be used to run JavaScript (ahem, JScript) headlessly (outside of any browser).

Just create a file called “wsh-parser.js” like this:

JAVASCRIPT:
  1.  
  2. var fso = new ActiveXObject( "Scripting.FileSystemObject" );
  3.  
  4. function parse(fname) {
  5.     var file = fso.OpenTextFile( fname, 1 );
  6.     ret = file.ReadAll();
  7.     file.Close();
  8.     try {
  9.         eval("(function(){\n"+ret+"\n});");
  10.     } catch (e) {
  11.         WScript.Echo("Syntax error parsing " + fname);
  12.         WScript.Echo("  " + e.message);
  13.     }
  14. }
  15.  
  16. function findJavaScript(folder) {
  17.     for (var fc = new Enumerator(folder.files); !fc.atEnd(); fc.moveNext()) {
  18.         var file=fc.item();
  19.         if (/.js$/.test(file.Name)) {
  20.             parse(file);
  21.         }
  22.     }
  23.     for (var fc = new Enumerator(folder.subfolders); !fc.atEnd(); fc.moveNext()) {
  24.         var subfolder = fc.item();
  25.         if (subfolder.Name == ".svn") continue; // ignore .svn folders
  26.         findJavaScript(subfolder);
  27.     }
  28. }
  29.  
  30. var rootPath = "src/main/javascript";
  31. var rootFolder = fso.GetFolder(rootPath);
  32.  
  33. findJavaScript(rootFolder);
  34.  

Other tools will help you hunt this down too, and I am sure some of you have Perl/Ruby/Python one liners to do the same ;)

Posted by Dion Almaer at 5:37 am
Comment here

+++--
3 rating from 2 votes

Friday, September 26th, 2008

Maintaining Browser Specific CSS

Category: CSS, Tip

Nick Cairns saw our post on conditional CSS for browsers and followed up discussing how he handles maintaining IE specific CSS selectors:

We keep our IE related styling right below the common (standards-based) declarations. BUT, we DON’T use hacks. Underscore hacks, * hacks, and all of those things that we all gave up with the birth of IE7 should remain dead and buried. Instead, we’re going to use IE’s conditional commenting to create IE specific CSS selectors. We do this by adding a conditional comment block as the outer most wrapper in our html template (ie. the first tag inside the ).

HTML:
  1.  
  2.   </body><body>
  3.      <!--[if IE 7]><div id="body1" class="IE IE7 IE67"><![endif]-->
  4.      <!--[if IE 6]><div id="body1" class="IE IE6 IE56 IE67"><![endif]-->
  5.      <!--[if IE 5]><div id="body1" class="IE IE5 IE56"><![endif]-->
  6.      <!--[if !IE]>-->
  7.           <div id="body1" class="W3C">
  8.      <!--<![endif]-->
  9.                 /* THE REST OF YOUR HTML GOES HERE */
  10.           </div>   
  11.   </div></div></div></body> 
  12.  

Now, in this sample, we do have support for older legacy versions of IE, so you could always reduce the number of conditions if your project doesn’t need this level of support. And, you could also easily extend it to include IE8, or to do minus versioning such as IE8-.

With this conditional block in place, it becomes quite easy to place IE only style declarations right below their standards-based counterparts. As an example:

CSS:
  1.  
  2. #header { overflow: hidden; }
  3. .IE #header { zoom: 1; }
  4.  

Posted by Dion Almaer at 6:35 am
23 Comments

++---
2.3 rating from 32 votes

Monday, September 15th, 2008

Tip: Using a background image on an image

Category: CSS, Tip

Pascal Opitz answered the question "Can you set an image background on an image element?" in simple fashion.

All you have to do is make sure that the image is display: block and has a padding.

He put up a simple demo that uses a div with an image, and he applies backgrounds to both:

CSS:
  1.  
  2. div {
  3.         background: url('blur.jpg') no-repeat top left;
  4.         width: 232px;
  5.         height: 200px;            
  6. }
  7.                
  8. img {
  9.         display: block;
  10.         background: url('parallax.gif') no-repeat bottom left;
  11.         padding: 93px 100px 75px 100px;
  12. }
  13.  

You have the little chap running as the actual src of the image, the animated background as the img background, and then the sky background applied to the div.

Posted by Dion Almaer at 5:23 am
8 Comments

++++-
4.2 rating from 24 votes

Tuesday, September 2nd, 2008

addSizes.js: automatic link file-size generation

Category: JavaScript, Tip, jQuery

Nathalie Downe has taken Simon Willison's json-head App Engine mini-service and used it to create addSizes.js, a little script that looks for large files linked from a page, and automatically adds their file size to the copy after the link.

Once in place, you simple do your usual link, and asynchronously the Web page will be updated to look like "your pdf link (pdf 2.8 MB)".

JAVASCRIPT:
  1.  
  2. jQuery(function($){
  3.         $('a[href$=".pdf"], a[href$=".doc"], a[href$=".mp3"], a[href$=".m4u"]').each(function(){
  4.                 // looking at the href of the link, if it contains .pdf or .doc or .mp3
  5.                 var link = $(this);
  6.                 var bits = this.href.split('.');
  7.                 var type = bits[bits.length -1];
  8.                
  9.                
  10.                 var url= "http://json-head.appspot.com/?url="+encodeURI($(this).attr('href'))+"&callback=?";
  11.        
  12.                 // then call the json thing and insert the size back into the link text
  13.                  $.getJSON(url, function(json){
  14.                         if(json.ok && json.headers['Content-Length']) {
  15.                                 var length = parseInt(json.headers['Content-Length'], 10);
  16.                                
  17.                                 // divide the length into its largest unit
  18.                                 var units = [
  19.                                         [1024 * 1024 * 1024, 'GB'],
  20.                                         [1024 * 1024, 'MB'],
  21.                                         [1024, 'KB'],
  22.                                         [1, 'bytes']
  23.                                 ];
  24.                                
  25.                                 for(var i = 0; i <units.length; i++){
  26.                                        
  27.                                         var unitSize = units[i][0];
  28.                                         var unitText = units[i][1];
  29.                                        
  30.                                         if (length>= unitSize) {
  31.                                                 length = length / unitSize;
  32.                                                 // 1 decimal place
  33.                                                 length = Math.ceil(length * 10) / 10;
  34.                                                 var lengthUnits = unitText;
  35.                                                 break;
  36.                                         }
  37.                                 }
  38.                                
  39.                                 // insert the text directly after the link and add a class to the link
  40.                                 link.after(' (' + type + ' ' + length + ' ' + lengthUnits + ')');
  41.                                 link.addClass(type);
  42.                         }
  43.                 });
  44.         });
  45. });
  46.  

Posted by Dion Almaer at 5:07 am
8 Comments

++++-
4.5 rating from 14 votes

Wednesday, August 27th, 2008

Using CSS to do the print watermark technique

Category: CSS, Tip

Andy Pemberton has put together a simple solution to get the watermark technique to work nicely with print CSS.

Check out the sample and pull up a print preview. He details the good, bad, and ugly:

The Good

The first step to getting a printable watermark is to use an inline tag, rather than background-images. In most browsers, background-images won’t be printed unless the user selects an additional browser option to enable it.

From here, we need to place the watermark image so that it is repeated on each page. It looks like the W3C thought of this ahead of time in the positioning module. The position property’s fixed value should ensure that a watermark is printed on each page. Some browsers, like FireFox and Internet Explorer 7, apply this rule correctly.

The Bad

Not all browsers play nicely with position:fixed and we haven’t yet considered using z-indexing to ensure the watermark displays behind all the regular page content. For IE and FireFox 3+, simply applying z-index:-1 to the watermark will do the trick.

Though, it turns out that earlier versions of FireFox (and other Gecko-based browsers) don’t play nicely with negative z-indexing. So, my current approach uses a few Gecko-specific hacks to degrade the watermark approach for FireFox 2. For FireFox 2, the watermark will display over the content, but still display on every page. Unfortunately, this means the CSS for my approach doesn’t validate.

The Ugly

But of course, position:fixed isn’t supported at all in IE6; it appears to ignore the rule altogether and display the image inline. So, I use conditional comments to filter just a *few* IE6-specific hacks:

Absolute positioning and an additional 100% height on the watermark and printable content are the keys to getting this working for IE6:

div.watermark{
position:absolute;
overflow:hidden;
}
div.content{
height:100%;

}

Posted by Dion Almaer at 2:14 am
Comment here

++---
2.7 rating from 16 votes

Monday, August 18th, 2008

A simple solution to the “other” problem with select boxes

Category: Examples, JavaScript, Tip, jQuery

Jeffrey Olchovy has posted a simple tutorial on using jQuery to solve a "select-to-input toggle" that shows and hides a text field when you select "Other". It overloads the same form name, so the server side gets just one value, and doesn't know or care if it was in the drop down or typed in. You can try it live here.

This is a simple little solution to the issue that there isn't a native control to really do the job. What you really probably want here is the ability to drop down and select items, or just type into the select box field itself. This is one reason why people implement auto-complete text fields instead of using select boxes for this case, but wouldn't it be nice to be able to tag your <select> and be done?

Posted by Dion Almaer at 5:51 am
10 Comments

+++--
3.2 rating from 31 votes

Getting a JavaScript stracktrace in any browser

Category: JavaScript, Tip

Eric Wendelin has posted on getting a JavaScript stack trace no matter that the browser.

With Firebug you can call console.trace() but what about the rest?

Luke Smith took Eric's work and added to it, ending up with:

JAVASCRIPT:
  1.  
  2. (function () {
  3. YOUR_NAMESPACE.getStackTrace = (function () {
  4.  
  5. var mode;
  6. try {(0)()} catch (e) {
  7.     mode = e.stack ? 'Firefox' : window.opera ? 'Opera' : 'Other';
  8. }
  9.  
  10. switch (mode) {
  11.     case 'Firefox' : return function () {
  12.         try {(0)()} catch (e) {
  13.             return e.stack.replace(/^.*?\n/,'').
  14.                            replace(/(?:\n@:0)?\s+$/m,'').
  15.                            replace(/^\(/gm,'{anonymous}(').
  16.                            split("\n");
  17.         }
  18.     };
  19.  
  20.     case 'Opera' : return function () {
  21.         try {(0)()} catch (e) {
  22.             var lines = e.message.split("\n"),
  23.                 ANON =