reptile7's JavaScript blog
Sunday, March 25, 2012
Date, Close, Copy
Blog Entry #245

Today we will take up HTML Goodies' "Top 10 JavaScript Snippets for Common Tasks" tutorial, which was composed by Scott Clark. The "JavaScript Snippets" tutorial offers...ah, the title is clear enough, isn't it? Not all of the snippets are worth covering; the business end of one of them isn't even JavaScript. The most useful and interesting snippet is the Calendar snippet, which deserves its own entry and we'll go through it in detail next time (or the time after that). This entry will give quick takes for the Date Display, Close Window, and Copy Selected Text snippets.

Today is the day

The Date Display snippet is a script that writes to the page the current date in the format:

Sunday, January 01, 2012

The script first creates a now Date object. It then sets up an array of day names that map onto the 0-to-6 returns of the Date object's getDay( ) method and an array of month names that map onto the 0-to-11 returns of the Date object's getMonth( ) method.

var now = new Date( );
var days = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
var months = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");

The script's next statement gets now's getDate( ) return:

var date = ((now.getDate( ) < 10) ? "0" : "") + now.getDate( );

A leading zero is prepended to getDate( ) returns in the 1-to-9 range; if you don't feel the need to do this, then the date assignment can be simplified to var date = now.getDate( );.

Embarrassingly, the script gets the year part of the date via now's getYear( ) return. The Date object's getYear( ) method was deprecated and replaced by a getFullYear( ) method in JavaScript 1.3, which was the last version of classical JavaScript. I'm not going to discuss the getYear( ) code or even put it in front of you - go look at it if you want.

Anyway, using now's getFullYear( ) return, we are ready to concatenate the various parts of the date and write the resulting string to the page:

today = days[now.getDay( )] + ", " + months[now.getMonth()] + " " + date + ", " + now.getFullYear( );

For its rendering, the script can be placed/referenced via a script element in a div or span element (or in most other elements, for that matter - both %flow; and %inline; elements can contain script elements). Alternatively, the concluding document.write(today); command can be exchanged for a statement that assigns today to the innerHTML of a suitable element.

In the Date Display section's first sentence Scott italicizes his Friday, June 11, 2010 sample date. The original script does not in fact italicize the today string but it is simple enough to do that via the italics( ) method of the String object (which is not part of the ECMAScript standard but nonetheless has cross-browser support):

document.write(today.italics( ));

FYI: JavaScript's Date object has a toLocaleDateString( ) method that outputs the today format exactly when using Chrome and is only off by a comma when using Opera but falls short with other browsers, e.g., for my sample date Firefox's toLocaleDateString( ) return is 01/01/2012 whereas Safari gives January 1, 2012. IE 5 for Mac does not support the toLocaleDateString( ) method but its new Date("Jan 1, 2012").toLocaleString( ); return is Sunday, 01 January, 2012 12:00:00 AM, implying that more recent versions of IE give a Sunday, 01 January, 2012 toLocaleDateString( ) format - close enough, wouldn't you say?
(If anyone at Mozilla is reading this: unlike its toLocaleString( ) 'parent', the toLocaleDateString( ) method does not go back to JS 1.0 but first appeared in the JS 1.5 spec; check JS 1.4's Date object section - it's not there.)

The window will close

The Close Window snippet provides three simple ways to close a pop-up window. Before going any further, I should note that if you're going to make use of pop-up windows, then they should be opened via clicking buttons or links; browser pop-up blocking, which will be enabled for most of your visitors, typically prevents the opening of secondary windows by load and mouseover events but does not interfere with click-triggered openings (at least that's how things go on my computer).

This snippet caught my eye for two reasons:

(1) Its first close subsnippet unnecessarily uses a JavaScript URL as an onclick event handler:

<form><input type="button" value="Close Window" onclick="javascript:window.close( );"></form>
/* As the Close Window button is a 'user interface element', the form container is semantically inappropriate and should be thrown out. */

I was originally going to comment, "A JavaScript URL can be assigned to the href attribute of an anchor element, and THAT'S IT," but this is actually not true. In theory, JavaScript URLs can be used with any element attribute whose value has a %URI; data type: the action attribute of the form element, the cite attribute of the blockquote/q elements, etc.; however, this page reports that these pairings are not supported by modern browsers much of the time. (sorry, this resource is currently not available).

In any event, the onclick="javascript:window.close( );" attribute is valid HTML: onclick has a %Script; data type and %Script;'s replacement text is CDATA, e.g., we can validly assign a string like "Hello World" to onclick even though this won't do anything for us. Indeed, clicking an <input type="button" value="Button text" onclick="Hello World"> button will throw an Unexpected identifier (or equivalent) error with most browsers, which expect onclick to be set to a function/object - JavaScript is not always so "weakly typed", eh? Conversely, onclick="javascript:window.close( );" is in practice a legitimate JavaScript assignment because the browser sees the JavaScript URL not as a string (it would see an img src URL as a string) but as a function to execute, as can be verified by giving the button an id and running a typeof document.getElementById("buttonID").onclick command. Having said all this, the javascript: protocol is excess baggage and should be thrown out.

The second close subsnippet plants the javascript:window.close( ); URL in an anchor element, where it belongs:

<a href="javascript:window.close( );">Click to Close Window</a>

(2) The third close subsnippet features a setTimeout( ) command with an unusual first-argument syntax:

<body onload="window.setTimeout(window.close, 20000);">

'window.close( )' is what you would usually see. In the window.close expression, close seems to be a property of the window object, and plumbing the window object with a loop

for (var i in window) { document.write("window." + i + " = " + window[i] + "<br>"); }

does produce a window.close = function close() { [native code] } property with some browsers. More precisely, window.close is a reference for the window.close( ) function in the same way that myFunction would be a reference for a function myFunction( ) { /* function body statements */ } function, and the use of a function reference for the first setTimeout( ) argument has long had cross-browser support (one small clarification: IE 5 for Mac only supports the stringified function call syntax).

Copy and paste

The Copy Selected Text snippet presents code that gets a user's mousical text selection and loads it into a textarea field. (Is this really a common task? Maybe I need to get out more.) An it form holds the textarea field and a push button interface for triggering the copy/paste action:

<form name="it"><div align="center">
<input type="button" name="btnCopy" value="Press to copy the highlighted text" onclick="copyit(this.form.select1);"><p>
<textarea name="select1" rows="4" cols="45"></textarea>

Clicking the btnCopy button calls the following function:

function copyit(theField) {
    var selectedText = document.selection;
    if (selectedText.type == "Text") {
        var newRange = selectedText.createRange( );
        theField.focus( );
        theField.value = newRange.text; }
    else { window.alert("Select some text on the page and then press this button."); } }

The copyit( ) functionality is based on Microsoft's proprietary selection interface, which we briefly discussed in the Link and color section of Blog Entry #181. In brief: The user selection (document.selection) is given a selectedText identifier and then type-tested as to whether it contains only Text; if true, then its createRange( ) method is called to create a newRange TextRange object whose text property return, the actual text of the user selection, is subsequently assigned to the value of the theField textarea element. In addition, a theField.focus( ); command imparts focus to the textarea field.

So, how does it work? Can't tell ya: as of this writing, IE is the only major browser that supports the Microsoft selection interface - Opera used to support it, but no longer does so - and thus I as a Mac user am left high and dry vis-à-vis running the code; more specifically, the browsers on my computer throw a selectedText is undefined (or equivalent) error when I click the btnCopy button. Fortunately, the copyit( ) function is easily cross-browserized: condition the original copyit( ) function body via an if (document.selection) { ... } clause and then add the else if clause below.

else if (window.getSelection) {
    var selectedText = window.getSelection( ).toString( );
    if (selectedText) { // If selectedText is not an empty string
        theField.focus( );
        theField.value = selectedText; }
    else window.alert("Please select some text."); }

The else if functionality is based on Mozilla's selection interface, which we briefly discussed in the Are you selected? section of Blog Entry #182. The getSelection( ) method of the window object, and the toString( ) method of the selection object that window.getSelection( ) returns, are today supported by the most recent versions of all of the major browsers, including IE.

Do we need a demo for this guy? Oh, why not:

Select some text anywhere in this div and then click the Press... button.

Web developers often use JavaScript for common tasks on their websites. In this tutorial we'll show you the top 10 JavaScript snippets you can use on your webpages by just cutting and pasting!
In this article we're going to cover the following popular script snippets!

And by the way, today's date is:
A Date Display demo is included for good measure. I've tidied up the Copy Selected Text HTML a bit, namely, I've removed the it form container and exchanged the div's deprecated align="center" attribute for a text-align:center; style declaration; the textarea field is accessed in the copyit( ) function via a getElementById( ) command. N.B. In Blog Entry #182 I stated, The W3C will be bringing the Mozilla selection interface into HTML5; that interface has since been taken out of HTML5 and is slated to be defined in a future Selection API specification.
We'll continue our "JavaScript Snippets" commentary in the following entry.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)