Sunday, 29 January 2012

Modal Dialog Box


Part 3 : Use the Script

To actually use the modal dialog script requires two things - the HTML code in your web page that contains the content of what you want the dialog to display and the Javascript calls to display the dialog and to handle the resonses based on what action that tyour visitors take with respect to that dialog. Let's start by looking at what the HTML needs to look like. Here's the simple one from the sample page:
<div id="box" class="dialog">
<div style="text-align:center"><span id="txt">Press OK to continue.</span><br>
<button onclick="hm('box');okSelected()">OK</button></div>
</div>
The first thing you will notice is that the div has both an id and a class. The class being set to "dialog" is what identifies the content of this div to the dialog box script as being the content for a dialog box so that it wont be displayed as part of the regular web page. The id is what we will use to reference this particular div when we want to run it.
The second thing is the processing that we perform when a button in the dialog box is selected. We need to call the hm() function passing it the id of the current dialog so that the dialog box will be removed from the display when the button is selected. Assuming that you have some processing of your own that needs to run when a button in the dialog is pressed all that you need to do in order for that processing to be run is to put that code into a separate function and call that function from within the onclick code immediately after calling the hm() function (as I have shown with the okSelected() function in the example). You can either call a different function depending on which button is selected or call the same function and pass it different values.
If you want to put an actual form into the dialog box then instead of using an onclick on a button tag you would place the same Javascript code into the onsubmit on the form tag instead.
All that remains then is to actually call this code from within our Javascript. To help show how to do this properly I am going to take the simple case of the following code which calls the alert dialog.
var x = 'something to check';
alert(x);
var y = x;
Now that code doesn't actually do a great deal but let's say that we want to convert that to call our modal dialog box instead. Here's the code that we need:
var x = 'something to check';
$('txt').innerHTML = x;
sm('box',200,50);
function OKSelected() {
var y = x;
}
There are three things to take not of in this code. The first is that we actually perform the modal dialog display with the sm() function call. This takes three parameters identifying the id of the dialog to be displayed, the width of dialog box to display and the height of the dialog to be displayed.
The second is that the call to the sm() function should come last in whatever code that is being run and whatever code that you want to be run once a response is received back from the dialog goes into the separate function that the buttons or form in the dialog call.
The third and final thing is the weay that you pass information into the dialog box. This is done by attaching an id to the sections within the dialog box into which you want to be able to load dynamic content. You can then use document.getElementByID().innerHTML to load your content into that part of the dialog box. The dialog box script provides a shorter way to specify this by substituting $ for document.getElementById.

Modal Dialog Box


Part 2 : Obtain the Script


To be able to add your own "modal dialogs" to your web page the first thing you need to do is to get the JavaScript that handles the modal display. Copy the following code and save it as modaldbox.js.


// Modal Dialog Box
// copyright 8th July 2006, 16th April 2011 by Stephen Chapman
// http://javascript.about.com/
// permission to use this Javascript on your web page is granted
// provided that all of the code in this script (including these
// comments) is used without any alteration
function pageWidth() {return window.innerWidth != null? window.innerWidth: document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth:document.body != null? document.body.clientWidth:null;}function pageHeight() {return window.innerHeight != null? window.innerHeight: document.documentElement && document.documentElement.clientHeight ? document.documentElement.clientHeight:document.body != null? document.body.clientHeight:null;}function posLeft() {return typeof window.pageXOffset != 'undefined' ? window.pageXOffset:document.documentElement && document.documentElement.scrollLeft? document.documentElement.scrollLeft:document.body.scrollLeft? document.body.scrollLeft:0;}function posTop() {return typeof window.pageYOffset != 'undefined' ? window.pageYOffset:document.documentElement && document.documentElement.scrollTop? document.documentElement.scrollTop: document.body.scrollTop?document.body.scrollTop:0;}function $(x){return document.getElementById(x);}function scrollFix(){var obol=$('ol');obol.style.top=posTop()+'px';obol.style.left=posLeft()+'px'}function sizeFix(){var obol=$('ol');obol.style.height=pageHeight()+'px';obol.style.width=pageWidth()+'px';}function kp(e){ky=e?e.which:event.keyCode;if(ky==88||ky==120)hm();return false}function inf(h){tag=document.getElementsByTagName('select');for(i=tag.length-1;i>=0;i--)tag[i].style.visibility=h;tag=document.getElementsByTagName('iframe');for(i=tag.length-1;i>=0;i--)tag[i].style.visibility=h;tag=document.getElementsByTagName('object');for(i=tag.length-1;i>=0;i--)tag[i].style.visibility=h;tag=document.getElementsByTagName('input');for(i=tag.length-1;i>=0;i--)tag[i].style.visibility=h;tag=document.getElementsByTagName('textarea');for(i=tag.length-1;i>=0;i--)tag[i].style.visibility=h;if ('hidden' === h) {tag=$('mbox').getElementsByTagName('input');for(i=tag.length-1;i>=0;i--)tag[i].style.visibility='visible';tag=$('mbox').getElementsByTagName('textarea');for(i=tag.length-1;i>=0;i--)tag[i].style.visibility='visible';tag=$('mbox').getElementsByTagName('select');for(i=tag.length-1;i>=0;i--)tag[i].style.visibility='visible';}}function sm(obl, wd, ht){var h='hidden';var b='block';var p='px';var obol=$('ol'); var obbxd = $('mbd');obbxd.innerHTML = $(obl).innerHTML;obol.style.height=pageHeight()+p;obol.style.width=pageWidth()+p;obol.style.top=posTop()+p;obol.style.left=posLeft()+p;obol.style.display=b;var tp=posTop()+((pageHeight()-ht)/2)-12;var lt=posLeft()+((pageWidth()-wd)/2)-12;var obbx=$('mbox');obbx.style.top=(tp<0?0:tp)+p;obbx.style.left=(lt<0?0:lt)+p;obbx.style.width=wd+p;obbx.style.height=ht+p;inf(h);obbx.style.display=b;return false;}function hm(){var v='visible';var n='none';$('ol').style.display=n;$('mbox').style.display=n;inf(v);document.onkeypress=''}function initmb(){var ab='absolute';var n='none';var obody=document.getElementsByTagName('body')[0];var frag=document.createDocumentFragment();var obol=document.createElement('div');obol.setAttribute('id','ol');obol.style.display=n;obol.style.position=ab;obol.style.top=0;obol.style.left=0;obol.style.zIndex=998;obol.style.width='100%';frag.appendChild(obol);var obbx=document.createElement('div');obbx.setAttribute('id','mbox');obbx.style.display=n;obbx.style.position=ab;obbx.style.zIndex=999;var obl=document.createElement('span');obbx.appendChild(obl);var obbxd=document.createElement('div');obbxd.setAttribute('id','mbd');obl.appendChild(obbxd);frag.insertBefore(obbx,obol.nextSibling);obody.insertBefore(frag,obody.firstChild);
window.onscroll = scrollFix; window.onresize = sizeFix;}
window.onload = initmb;


Next copy the following stylesheet commands and save them as modaldbox.css.



                    #mbox{background-color:#eee; padding:8px; border:2px outset #666;}
#mbm{font-family:sans-serif;font-weight:bold;float:right;padding-bottom:5px;}
#ol{background-image: url(overlay.png);}
.dialog {display:none}


* html #ol{background-image:none; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="overlay.png", sizingMethod="scale");}



The third step is to save this image as overlay.png. While it doesn't necessarily look like a semi-transparent grey image displayed this way on the page this image will display that way when used with the script. Note that the references to this image are within the stylesheet code so if you put the image somewhere other than the same folder as the pages where you are going to use the script then you will need to change the stylesheet to reference the correct location for the image in both places where it is referenced. You can of course substitute your own semi-transparent png image if you want to use a different colour. The image needs to be defined as a semi-transparent png in order to give the appropriate effect as no other image format will allow the main content to show through. While Internet Explorer 5.5 and 6 do not correctly support transparent png files the last line in the stylesheet will apply an equivalent effect in those browsers.
The final step in setting things up to be able to add "modal dialogs" to your web pages is to add the following code into the head of each page where you want to apply the be able to add them.
<script type="text/javascript" src="modaldbox.js">
</script>
<link rel="stylesheet" href="modaldbox.css" type="text/css" />
That done now all that remains is to add the HTML andd JavaScript that is required to actuallyuse the script

Modal Dialog Box


Part 1 : Introduction and Sample Page


The three dialog boxes that Javascript provides are
 alert() which displays a message and an OK button, confirm() which provides a message along with OK and cancel buttons and returns true if OK is pressed and false if cancel is pressed, and finally prompt() which provides a text input box and an OK button and returns the text that is entered.One limitation of Javascript is that it only provides three dialog boxes that you can link to from within JavaScript and they are intended more for debugging your script than interacting with visitors (as in some browsers they contain a checkbox to disable JavaScript). Dialog boxes are useful because they allow the script to interact with your visitor where that visitor must provide a response to the dialog box before the script can continue processing. This is because dialog boxes are modal and do not permit anything else to happen until the dialog box receives a response.
So what do we do when we want a dialog box that is different from any of these three or want to ensure that our visitors can't use the dialog to disable JavaScript? We build our own of course. Well we can't build an actual dialog box since those are created by the browser (which is why they look different depending on which browser you are running). What we can do is to build something into our web page that achieves the same result. Let's start by looking at an example of a modal dialog alert substitute. Well go on, click on the preceding red underlined text to see the effect. Of course since the actual content of the "dialog box" is coded in the HTML of the page we can customize it to contain whatever content that we want rather than being limited to the three standard dialog boxes. We just need to handle the processing of what we get back from the script a little differently since the Javascript doesn't actually wait for the response but that is quite simple to handle as well.
Note that the script has now been updated to ensure that your visitors can't use the tab key to access forms outside of the modal dialog.
If this is the effect that you want to add to your page then the next step is to obtain the script.

Obtaining Your Visitor's IP Address


JavaScript itself has no way of reading the IP address of the local computer and so for JavaScript to obtain that information we need to use a different language to obtain the information. Once possible way of doing this is to call Java to get the information for you.
if (java && java.net)
ip = ''+java.net.InetAddress.getLocalHost().getHostAddress();
else ip = 'unknown';
The problem with doing this is that not all browsers support accessing Java this way from within JavaScript (for example Internet Explorer and Opera do not even though such calls have been a part of JavaScript since JavaScript was first added to Netscape 2). Even on browsers that do support it you can't test the script without first uploading to a web server first as access to the Java object is not available for local files. Even in browsers that do support the call you are reliant on both JavaScript and Java being enabled in order for the command to work. This is therefore not the ideal way to obtain the IP address. Fortunately there are better ways.
The better ways of obtaining the IP address in JavaScript rely on server side processing and so if you have no access to add server side processing to your pages at all then the Java option is really the only one available to you despite its limitations. You do not need much in the way of server side processing capability to be able to always get the IP address and so few people should be in the position of having the Java option as their only choice. Even with just Server Side Includes (SSI) you can obtain the IP address using the following code:
ip = '<!--#echo var="REMOTE_ADDR"-->';
You just need to make sure that the file that contains that code gets parsed for server side includes either by using a .shtml file suffix or by configuring the file suffix you do use appropriately.
The code using PHP is even simpler provided that the file either has a .php suffix or is parsed for PHP.
ip = "<?php echo $_SERVER['REMOTE_ADDR']?>";
The ASP version is somewhat longer:
ip = '<%= Request.ServerVariables("REMOTE_ADDR")%>';
This has been somewhat simplified for those who have upgraded to .NET
ip = '<%= Request.UserHostAddress>';
Java is one language that can run server side as well as client side. Earlier we looked at the client side code for accessing the IP address but there is a simpler way to use Java to get the IP address for JavaScript if your file can be parsed as JSP.
ip = '<%=request.getRemoteAddr()%>';
The final option I am going to illustrate is how to do it using ColdFusion.
ip = '<cfoutput>#cgi.remote_addr#</cfoutput>';
Of course if you are using some other language on the server there is probably a way you can use that to provide the IP address to JavaScript too.

Monday, 16 January 2012

Learn Modern Unobtrusive JavaScript - Nodelists


Learn Modern Unobtrusive JavaScript

Nodelists

From  Kumar Rajguru , former PlusDeveloper.in Guide
Earlier tutorials in this series have used document.getElementById() to reference a specific element within the current web page. There are two additional calls which also provide access to the elements in the web page only these two commands do not just return one element reference but instead return all of the elements in the page that match the specified criteria. These two calls are document.getElementsByName() anddocument.getElementsByTagName(). Since each of these returns multiple references they need to be returned using an object type that supports multiple fields. The actual object type that these calls return is a nodelist. There is no need to be able to define a nodelist yourself in JavaScript since a nodelist always relates to the actual elements found in the web page Running either of the two DOM commands previously mentioned will make the appropriate nodelist object available to JavaScript and the appropriate DOM commands to update the web page will update the nodelist appropriately.
A nodelist is a more advanced object than an Object is as the elements in a nodelist do have an order and a length. This doesn't make a nodelist an Array though since none of the array methods can be used on a nodelist. The only way to change the content of a nodelist is via the appropriate DOM commands.
Of the two commands for creating a nodelist getElementsByName is the less useful of the two since it can only reference those elements within the page that actually have a name attribute associated with them. This basically limits their use to referencing form fields which are the only elements in a web page that are allowed to have a name. The getElementsByTagName is far more useful since you can specify any tag name in the command or even specify '*' in order to retrieve a nodelist of all of the elements in the page. You can then loop through all of the elements in the nodelist performing whatever action you require on each node that meets whatever other criteria you specify and create an array of references to those nodes that satisfy that specific criteria. As this is an array we can use all the usual array methods on it. Since the array only contains references to the nodelist entries, and actions performed on the array will not affect the nodelist at all.
Let's look at an example of using getElementByTagName to go through all of the elements in our web page and create an array of references to all of those elements that have a particular class associated with them. We are going to extend the functionality of the document object by adding a new method that will retrieve just those elements with a specific class.

document.getElementsByClassName = function(cl) {
    var retnode = [];
    var myclass = new RegExp("\\b"+cl+"\\b");
    var elem = this.getElementsByTagName("*");
    for (var i = 0; i < elem.length; i++) {
       var classes = elem[i ].className;
       if (myclass.test(classes)) retnode.push(elem[i ]);
       }
    return retnode;
 };

We haven't yet looked at the RegExp object but basically that object allows us to test the content of a field for a match to a particular pattern. In the case of classes associated with an element, an element can have multiple classes attached as a space separated list of class names. The myclass RegExp object therefore allows us to easily test if a particular class name appears in that space separated list.
The for statement provides us with a way to process all of the elements in the nodelist in order. It takes three values separated by semi-colons. The first value indicates start conditions. We set i to zero so that we can use i as the value of the element within the nodelist that we want to check and since nodelists like arrays start from zero, that is where we need to start. The second value indicates the test we want it to make to finish the loop. the length property on a nodelist or array contains the number of elements in that nodelist or array and so we only want to process while the element number we are looking at is less than the length (since the first element is numbered zero). The last value i++ instructs the for loop to add one to i each time through the loop.


Learn Modern Unobtrusive JavaScript - Arrays


Learn Modern Unobtrusive JavaScript

Arrays

From  Kumar Rajguru , former PlusDeveloper.in Guide
There are two ways in JavaScript to group items together. Where there is no particular ordering required or implied by the various items then the most obvious way or associating them together is to make them all properties of the same object. That object can then be passed around the code making all of the properties available at the same time without needing to pass each separately.
Where the items do have a specific order that they need to be processed in then JavaScript provides an alternative object that we can use as the basis for our group of items. This type of object is the Array which adds a large number of additional methods that make processing the items in the required order much easier.
As with objects, there are several different ways that we can create an array.

var ary = new Array();
var ary2 = new Array(3);
var ary3 = new Array('1','2','3','4');
var ary4 = ['1','2','3','4'];

The first of these simply creates a new array called ary which contains no items. The items would need to be added after the array has been created. The second example creates an array that already contains three items each of which currently has a value of null since no values have actually been assigned yet. The last two examples create identical arrays each with four items and each of which assigns the values '1', '2', '3', and '4' to those four items. The [] notation is a shortcut way of referencing a new Array the same way that {} is a shortcut for a new Object.
We can both assign values to and reference values in an array by using the [] notation with a number representing the item within the array that we want to reference. JavaScript arrays are numbered from zero and so ary4[2] currently contains a value of '3'. You can assign a value to any element in an array, even one way beyond those items that currently exist. Where you do assign a value to an element outside of the existing array, the array will be expanded to include that element and intervening elements will be null.
There is a page in the reference section that already lists all the Array methods and properties and of course all of those listed in the prior tutorial on Objects also apply. There are also proposals for additional methods to be added that will make array processing even more useful and some browsers have already implemented some of those methods. Should you decide to use those methods then you will either need to define them yourself for those browsers that do not yet support the methods or use a JavaScript framework which provides the definitions of the methods for you. Those methods listed in my method reference are available on all but the most antiquated of browsers and can therefore be safely used without needing to code them for yourself.
Because arrays have an order to the entries we can also set up a loop to process through all of the entries in the array one after the other in the specified order. We'll get to how to do that in a subsequent tutorial.
Some programming language have the concept of multi-dimensional arrays where you can assign an array to have two or more ordered values associated with each item instead of only one. Such languages would allow items to be referenced using a[x,y] or even a[x,y,z]. JavaScript only allows one dimensional arrays. That isn't really any real disadvantage though because JavaScript allows the items in an array to be anything at all and so we can place an array into each item in our array so as to effectively achieve the same result as a multi-dimensional array.

var a = [['1,1','1,2'],['2,1','2,2']];

This example defines an array of two elements each of which is an array of two elements (see how convenient the shortcut notation is). We can reference the item containing '2,1' for example using a[1][0] (which isn't greatly different from the a[1,0] notation that languages that do support two dimensional arrays would use.
One other restriction that many other languages have which doesn't exist in JavaScript is the requirement that all of the items in an array be the same type. This requirement doesn't exist in JavaScript and so the following is a perfectly valid array.

var b = [3,'t',myobj,['x',3]];

It is however far more common when the various items are of different types to define them as properties of an object rather than as an array since such mixes of different types seldom have any order associated with them and using an array implies that the order has some meaning.

Associative Arrays

Some languages support the concept of associative arrays where the items in the array are named rather than numbered. Javascript does support this concept in that you can reference entries such as myobj['myprop'] however such associative array references are treated as object references in JavaScript and so myobj['myprop'] is equivalent to myobj.myprop and none of the additional methods or properties that arrays have and objects do not can be used with an associative array.

Learn Modern Unobtrusive JavaScript - Objects


Learn Modern Unobtrusive JavaScript

Objects

From  Kumar Rajguru , former PlusDeveloper.in Guide
The entire JavaScript language is based around Objects and yet there are many people writing simple JavaScript code using classical obtrusive techniques who have no idea what an object is and have certainly never knowingly used one in their code. Of course they are unknowingly using them all the time since as discussed in prior tutorials, every function and variable in JavaScript are actually methods and properties of a JavaScript object - often the Window object. We'll leave discussion of the Window object until later though and start by looking at the simplest object that is predefined in JavaScript - the Object.
JavaScript Objects with the exception of the Object object itself are all basically extensions of that object and so an understanding of the Object object is the first step in being able to understand both how the predefined objects work as well and how to extend them, as how to define your own objects.
The first thing we are going to look at with objects is how to define our own alternative names to refer to existing objects as well as how to make a copy of an object. The following code sets o as an alternative name to referenceObject and obj as a completely separate object.

var o = Object;
var obj = new Object;

As you can see the difference between creating a reference to an existing object and creating a copy of an object is the absence or presence of the reserved word new.
Since all JavaScript objects (with the exception of the Global object) are derived from the Object object, all objects will have access to the properties and methods that an Object has. It is therefore extremely useful to know what these properties and methods are and what they do since you can use them with every object you have in your code including all of those built into JavaScript itself.
A JavaScript object always has the following properties:
  • constructor provides a reference to the function used to create the object. for the Object object this points to the Object() function,
  • prototype provides a reference to the object prototype for the object. In practice this allows us to share methods between objects without having to have a separate copy of the method in each object.
A JavaScript object also has the following methods:
  • toString() converts the content of the object into a text string. The exact means for doing so will vary depending on the object. In the case of the Object object the text string to be returned is not defined in the standards and so can vary between JavaScript implementations.
  • toLocaleString() a locale specific version of toString()
  • valueOf() returns the most appropriate primitive value to represent the object (such as a number or text string). Where a text string is the most appropriate representation (as it will be in most cases) this method may or may not return the same value as toString().
  • hasOwnProperty(propertyname) when a text string is passed to this method, the method will return true or false depending on whether or not a property by that name exists within this object.
  • isPrototypeOf(object) returns true or false depending on whether or not this object is a protptype for the specified one.
  • propertyIsEnumerable(propertyname) returns true if the property will be processed if a for/in loop (to be covered later) and false if the property will be excluded from processing in such a loop. Most predefined properties will return false while those you define yourself will always return true.
All of the objects that you create for yourself in JavaScript will be created by taking a copy of a predefined object (usually Object) and then adding your own properties and methods to it. You can also extend the functionality of the predefined objects by adding methods to them the same way as you add them to your new objects. The next thing we need to consider then is how we add properties and methods to an object. We have actually already looked at one way of doing this in the prior tutorials on functions and variables.

var myobj = new Object;
myobj.prototype.mymethod = function() {...} ;
myobj.someProp = 7;

There are actually a couple of other ways that we can add properties and methods at the time when we create an object. The shortest way to do it is:

var myobj = {mymethod:myfunction,someProp:7}
function myfunction() {...}

The braces {} are a JavaScript shortcut means of referencing an object.
The other way of creating our own new objects is to simply define them as functions (since all objects are also methods of a higher level object in JavaScript). Here's an object with two properties and two methods that has been created this way.

function AdBox() {
this.width = 200;
this.height = 60;
this.text = "default ad text";
this.prototype.move = function() {
// code for move method goes here
}
this.prototype.display = function() {
// code for display method goes here
}
}
var myobj = new AdBox;

Note that we use the this reserved word to attach the properties and methods to whichever object is actually using the object definition.
You can of course combine these different ways for adding properties and methods to your objects.