Chapter 10. Event Handlers

CONTENTS

CONTENTS>>

  •  The location, anchor, and history Objects
  •  Events and Event Handlers in HTML and JavaScript
  •  Summary

To have an interactive web page using JavaScript, you need two things: a user action and a reaction by the browser. The most common reaction in an HTML page is clicking the mouse, and you have seen several examples of the mouse firing off a function using the HTML onClick event handler in example scripts in this book. Some scripts have even included onLoad event handlers that fire a script automatically when a page is loaded. So by now, you have some idea about event handlers from your experience with basic functions such as rollovers.

This chapter takes a closer look at the events and event handlers in HTML pages and JavaScript. Here all of the events and the triggering conditions for an event to launch a function or JavaScript code are examined in detail. By the end of this chapter, not only will you have more options for firing functions, but you also will have a better understanding of how and when to use them. However, before getting into the events and event handlers, three unexamined window objects location, anchor, and history should be studied because all are often associated with events involving loading and unloading pages.

NOTE

One of the interesting characteristics of JavaScript and HTML is that, while they both use the same event-handler names, conventions have developed in HTML so that the event handles in HTML look different from those in JavaScript. HTML is not case-sensitive, and certain HTML conventions have led to spellings such as onLoad and onMouseOver. However, in JavaScript, the event handlers are lowercased, such as onload and onmouseover. For the most part, the HTML event handlers in this chapter fire JavaScript functions, so the conventional upper/lowercase combinations are used. However, when an event handler in JavaScript is expressed as a property, you will see it done so only in lowercase.

The location, anchor, and history Objects

Using links in HTML is second nature to web developers, and creating links with JavaScript is both easy and much more powerful than what can be done with the <a href="myURL"> tag in HTML. The main linking objects in JavaScript are location and history. When the location object is assigned a URL, you get the same results as linking a page. It has the following format:

window.location="http//:www.yourURL.something"; 

(This states that the window object is optional, and it typically is not used with location. It is included simply to remind the reader that location is a property of window.)

The location object has eight properties and two methods, as shown in Table 10.1.

Table 10.1. Properties of the location Object

Properties

Methods

hash

reload()

host

replace()

hostname

 

href

 

pathname

 

port

 

protocol

 

search

 

To get a sense of the properties in the location object, the following scripts attempt to display all of the properties. The first script uses location.URL to load a page. The second script opens itself and displays information about its current status.

locationprop.html
<html>  <head>  <title>Location Properties </title>  <script language="JavaScript">  window.location="http://www.sandlight.com/JS/locaInfo.html"  </script>  </head>  <body>  </body>  </html>

The second script is the page being called up for inspection. It will reveal information about its location in an alert box.

locaInfo.html
<html>  <head>  <title>Location Properties </title>  <script language="JavaScript">  function revealAll() {       var cr="\n";        var display = "Hash: " + location.hash + cr;        display += "Host: " + location.host + cr;        display += "Hostname: " + location.hostname + cr;        display += "HREF: " + location.href + cr;        display += "Path name: " + location.pathname + cr;        display += "Port: " + location.port + cr;        display += "Protocol: " + location.protocol + cr;        display += "Search: " + location.search + cr;        alert(display)        }  </script>  </head>  <body onLoad="revealAll()">  New Window  </body>  </html>

As you can see from Figure 10.1, not all of the properties are displayed in the alert box.

Figure 10.1. The alert box displays all of the information about the location object available in the URL.

graphics/10fig01.gif

In looking at Figure 10.1, you can see that the page called was on a host named www.sandlight.com with the same hostname. The file's full HREF and pathname are shown along with the protocol. No port was cited, nor was a hash or search value returned. You will find such values in a URL like this:

http://www.sandlight.com:67/dogHouse/search.html?query=swissy& matches=47#gsmd 

The port value is 67, the hash value is #gsmd, and the search value is ?query= swissy&matches=47.

The two location methods, locaton.reload() and location.replace(), have very different functions. The reload() method acts just like the Reload button on a browser. However, the replace() method acts more like the location object itself. When a variable is defined in this format, it sends the page identified in the URL:

var sendMe=location.replace(URL); 

However, the replacing page treats the previous page as though it never existed. If you press the Back button on the browser, it goes to the next-to-the-last previous page. The following script uses a menu to demonstrate the different ways to use the location property in a frameset context. A menu frame launches different pages delineated by a number and different cell background color to appear in an adjacent column.

The first script just sets up the frameset and provides target names for the two frames. The most important one to name is the second frame because no new pages will be replacing the page in the menu frame.

placeSet.html
<html>  <frameset cols ="10%,*">  <frame name="menu" src="placeMenu.html">  <frame name="travel" src="place.html">  </frameset>  </html>

The heart of the frameset is the menu script. In the script are examples of the different ways that location can be used to access a page in a frameset. Because only a single frameset is in the window, the script can use parent and top interchangeably. All of the JavaScript, except for a single function, is in the event-handler context. When you use several different single-statement scripts, it is just as easy to write the JavaScript in the event tag as it is to create a whole set of new functions.

placeMenu.html
<html>  <style type="text/css">  body {       font-size:14pt;        font-family:verdana;        background-color:#ecdac0        }  </style>  <head>  <script language="JavaScript">      function goT() {           parent.frames[1].location="place2.html";      }  </script>  </head>  <body>  Menu:<p>  <form>  <input type=button value=" 1 " onClick = "parent.frames[1].location = 'place.html'"> <br>  <input type=button value=" 2 " onClick="goT()"><br>  <input type=button value=" 3 " onClick = "parent.travel.location = 'place3.html'"> <br>  <input type=button value=" 4 " onClick = "top.frames[1].location = 'place4.html'"> <br>  <input type=button value=" 5 " onClick = "top.travel.location ='place5.html'"> <br>  <input type=button value=" 6 " onClick = "parent.frames[1].location.replace  graphics/ccc.gif('place6.html')"><br>  <input type=button value=" 7 " onClick ="parent.frames[1].location = 'place7.html'"><br>  </form>  </body>  </html>

This next script needs to be reproduced six times, for a total of seven pages. The first script is named place.html, the second is place2.html, the third is place3.html, and so forth until place7.html. Use the following cell-background colors, and replace the number to sequentially follow the filename numbers.

2 #537479

3 #eaaf54

4 #de5c0d

5 #cdb9a1

6 #704611

7 #782616

You will also want to change the text color value of the page display number in scripts 6 and 7 to #ecdaco. In that way, you can see the light numbers against the dark contrast of the cell background color.

NOTE

I used an old web page design trick with the pages in the right frame. Each page is dominated by a single-cell table. The numeric character in the middle of the page will maintain its relative position, no matter what size or proportion the frame is. By using the table and cell alignment attributes in HTML, it's easy to create a page that keeps its shape.

place.html
<html>  <head>  <style type="text/css">  .num {       font-size:36pt;        font-family:verdana;        }  </style>  </head>   <body>  <table width=100% height=100% align=center bgcolor="#f43615">      <tr valign=center halign=middle>         <td align=center height="90%" width=90%><p class="num">1 </p>         </td>      </tr>  </table>  </body>  </html>

Figure 10.2 shows the frameset with the third page moved to the right frame by the script in Button 3.

Figure 10.2. All of the buttons fire a JavaScript function or statement to control the pages in the right frame.

graphics/10fig02.gif

Working with the history Object

The history object is a property of the window object. It has a single cross-browser property, length, and three cross-browser methods, back(), forward(), and go(n). The length refers to the number of previous URLs that have been saved.

The most common use of the history object is to move back and forth in a site by referencing the previously visited sites. Depending on the order the pages were visited, you specify back() or forward(). The history.go(n) method uses positive values to go to a forward reference and negative numbers to go to a backward reference. Keeping in mind that the history object can reference only previously visited pages, the following two scripts demonstrate using the history functions. (Write both scripts first before trying to use them.)

The first script initially has no effective history. It has been nowhere, so it does not have a track record yet. You can click on the Go Forward button, and nothing will happen. However, after you go to the target page and return, the Go Forward button is active because it has a history to a forward page.

DblClick.html
<html>  <head>  <title>Forward </title>  <script language="JavaScript">  function doubleUp() {       window.location="backPage.html";        }        function forwardTo() {       var alpha=history.forward();        }  </script>  </head>  <body bgcolor="lightgreen">  <p>  <H3> Remember this page!</h3>  First double-click the top button. That will take you to another site.<br>  When you return to this page, click the bottom button.<P>  <form>  Double-click this button first:  <input type=button value="Two Clicks Here" onDblClick="doubleUp()"><P>  When you return, click this button.<input type=button value="Go Forward"  graphics/ccc.gifonClick="forwardTo()">  </form>  </body>  </html>

This second page has a history upon arrival because it is accessed from another page. It can "back up" to the page that it came from. Therefore, you have no need to build a history initially, and you can immediately fire the script that will return to the previous page.

backPage.html
<html>  <head>  <title>Reverse </title>  <script language="JavaScript">  function backUp() {       var alpha=history.back();        }  </script>  </head>  <body bgcolor="yellowgreen" onUnLoad="alert('You can return here by pressing the Go  graphics/ccc.gifForward button on the page.')" >  <p>  <H3> Thanks for the Visit</h3>  Place your mouse over the button and return from whence you came.<P>  <form>  <input type=button value="Mouse over here" onMouseOver="backUp()"><P>  </form>  </body>  </html>

anchor Object

The anchors[] array is somewhat of a disappointment at this time. The two major browsers are incompatible with anchors. Within the location object is a hash property that can be used to target an anchor with the following format:

location.hash="anchorName" 

Within a page, location.hash can provide to be quite useful; however, all that the anchors[] array returns in a cross-browser environment is the length property with this format:

document.anchors.length

However, if you run the anchors[] array through a loop with anchors.length, you will not get the anchor names returned. The following script should give you a good idea of what you can do with anchors in a cross-browser environment. (Several different mouse events were used in preparation for the following section on event handlers.)

anchorsArray.html
<html>  <head>  <title>Anchors and Hashes </title>  <style>  body {       background-color:#d9e6cc;        font-family: verdana;        }  h2 {       font-size: 24pt;        color: #ff0040;        }  h3 {       font-size: 16pt;        color: #008080;        }  a {color:#e68026; font-size:10; font-weight:bold;}  </style>  <script language="JavaScript">  function countAnchors() {       alert("This script has " + document.anchors.length + " anchors.");        }  function goAnchors(anchName) {       location.hash=anchName;        }  </script>  </head>  <body onLoad="countAnchors();">  <p>  <h2>Top Level <a name="top"></h2>  <a href="#" onMouseDown="goAnchors('one')">one</a> | <a href="#" onMouseOut =  "goAnchors('two')"> two </a> | <a href="#" onMouseMove ="goAnchors('three')"> three </a>  graphics/ccc.gif|  <a href="#" onMouseOver="goAnchors('four')">four</a>  <p>  <p><hr><hr>  <p>  <h3>Level One<a name="one"></a></h3>  <p><hr><hr>  <p>  <h3> Level Two<a name="two"></a> </h3>  <p><hr><hr>  <p>  <h3> Level Three<a name="three"></a> </h3>  <p><hr><hr>  <p><a href="#" onMouseUp="goAnchors('top')">Top</a>  <h3> Level Four<a name="four"></a>  </h3>  </body>  </html>

Figure 10.3 shows that the anchors[] array does, in fact, have elements, but getting to the elements in JavaScript has not been consistently resolved.

Figure 10.3. The anchors[] array has limited use, but the location.hash object/property can target anchors.

graphics/10fig03.gif

Events and Event Handlers in HTML and JavaScript

Throughout the book, and especially in this chapter, you have seen examples of different event handlers, and by now you should have an idea of what they do. To complete your understanding of what events are, how they are triggered, and what you can do with them, this chapter breaks them down into four different categories:

  • Mouse events

  • Key events

  • Form events

  • Page/window/image events

Some events and event handlers are different in the two major browsers. As with the other topics in this book, the focus will be on those features of JavaScript that have cross-browser compatibility. Likewise, some of the events deal with certain elements in HTML, to the extent that much of the discussion of those events is reserved for the chapters that cover the specific topics where the event handler has the most relevance. Most notable are the form events that are covered extensively in the next chapter (Chapter 11, "Making Forms Perform"). Event-like properties, such as form.checked, not only will be examined in the next chapter to look at the particular object with which they are most pertinent, but they also will be treated as properties and not events. In many ways, the event handlers that can be treated as properties in JavaScript represent the future of client-side JavaScript, and as the language (not to mention the browser manufacturers) matures, we hope to see cross-browser implementation of event handlers that are methods (a type of property), not as external HTML firing devices.

Mouse Events

Seven mouse events can be used to trigger a JavaScript program. They include the following:

  • onClick

  • onDblClick (NN6+)

  • onMouseDown

  • onMouseUp

  • onMouseMove (NN6+)

  • onMouseOut

  • onMouseOver

Most of the mouse events listed are familiar to you by now because so many have been used in examples. The following script provides an example of each of the mouse events, with the appropriate responses for feedback:

<html>  <head>  <title>Mouse Events </title>  <style type="text/css">  body{      font-family:verdana;       background-color:#ffbf00;       }  h2 {     color:#b51300;      font-size:16pts;      font-weight:bold;  }  a {color:a573b6;font-weight:bold}  </style>  <script language="JavaScript">  function helpMe() {       alert('Help has arrived. \n----------------------\n 1. Turn on your monitor.        \n 2. Look at the monitor.\n 3. Follow instructions.');        }  </script>  </head>  <body onDblClick="helpMe()";>  <H2> Follow the instructions: <br> (Or double-click to get help.)</h2>  <ul>  <a href="#" onMouseOver="alert('As you move over the spot.');"> onMouseOver </a><p>  <a href="#" onMouseUp="alert('You have to press Down to get Up');"> onMouseUp </a><p>  <a href="#" onMouseDown="alert('You can keep it down.');"> onMouseDown </a><p>  <a href="#" onClick="alert('Any click will do');"> onClick </a><p>  <a href="#" onMouseOut="alert('First move over and then off');"> onMouseOut </a><p>  <form>  <input type=button value ="onMouseMove" onMouseMove="alert('Press enter or return-- don\'t move the mouse!')"><p>  </ul>  </form>  </body>  </html>

The script uses the double-click (onDblClick) as part of the <body> tag. You're accustomed to seeing the onLoad event handler in the <body> tag, but you can place any of your mouse or key event handlers there as well. By using the double-click event handler, there is less chance of the event cropping up in one of the single-click hot spots on the page.

Figure 10.4 shows all the different mouse hot spots, a button, and what happens when the user double-clicks the mouse anywhere on the page.

Figure 10.4. The mouse event handlers can be placed in most HTML tags that recognize an event, including the <body>, forms, and <a> tags.

graphics/10fig04.gif

Key Events

JavaScript recognizes three key events:

  • onKeyDown

  • onKeyUp

  • onKeyPress

Unfortunately, Netscape Navigator and Internet Explorer have different ideas on how to implement certain key features (no pun intended) for these events. As a result, the designer has a limited choice of options for a bulletproof cross-browser implementation of the key event. The general format of any of the key events resides in firing them from within different HTML tags:

<tag onKeyEvent="functionToFire()"> 

You can place the key events in any of the tags that accept mouse events, but capturing which key has been pressed is inconsistent between the browsers. As a result, the event handlers have limited utility. The following script shows several different ways that the key event handlers can be employed. Because one of the key events is placed in the <body> tag, it pops up whenever any of the other key events are triggered.

<html>  <head>  <style type="text/css">  body{      font-family:verdana;       background-color:#e3f37f;       }  h2 {      color:#4d57ab;       font-size:16pts;       font-weight:bold;  }  a {color:fe0006;font-weight:bold}  </style>  <script language="JavaScript">  function fillIn() {       document.forms[0].elements[1].value="JavaScript is here!"  }  </script>  <title>Keys Up and Down </title>  </head>  <body bgColor= "cornflowerblue" onKeyPress="alert('This was set up in the body  element.');">  <center>  <H2> Click on the link text, button, or text window.<br>  Then press any key.</h2>  <a href="#" onKeyUp="alert('The <a href> did it!');"> Link Text </a><p>  <form>  <input type=button value ="Surprise me" onKeyPress="alert('You have to press the  Surprise Me button first!')"><p>  <input type=text size=20 onKeyDown="fillIn()">  </center>  </form>  </body>  </html>

When you press the Link Text hot spot, the event trigged by the onKeyPress event handler in the <body> tag appears and seems stuck. However, if you press the Enter/Return key on your computer, the key-launched function from the Link Text hot spot appears and keeps coming up every time you press a key. Now you have to click on the OK button in the alert box.

Form Events

The next chapter will explore form events, along with other form characteristics, in greater detail. In this section, however, you will see how to use the basic event handlers associated with forms. JavaScript recognizes five event handlers HTML associates with forms:

  • onBlur

  • onChange

  • onFocus

  • onReset

  • onSubmit

The references to "blur," "change," and "focus" all pertain to text elements in HTML only. When using the <input type=text> tags in HTML, the resulting text windows can be clicked and text can be entered. At the time that text is entered in a window, the window is considered to be in focus. The focus event means that a particular text window has been clicked and is ready for text input. The general format for setting up an onFocus event handler in HTML is the following:

<input type=text onFocus="functionGo()"> 

As soon as the user clicks in the text box, the function fires. The following little script shows how to use onFocus:

<html>  <head>  <title>onFocus</title>  <script language="JavaScript">  function autoWrite() {       document.forms[0].elements[0].value="Greetings earthling!";        }  </script>  </head>  <h3>Click on the Text Window:</h3>  <body bgColor="rosybrown">  <form>        <input type=text onFocus="autoWrite();">  </form>  </body>  </html>

The other two event handlers that look for events in text window, onChange and onBlur, first look for the event of selecting a text window and then selecting something else. The blur event occurs when a window has been selected and then deselected, while the change event looks to see whether a window has been selected or deselected. The following script shows how both are used, in both a text element and a textarea element:

<html>  <head>  <style type="text/css">  body { background-color:peru; font-family:verdana; color:white}  </style>  <title>onFocus</title>  <script language="JavaScript">  var auto = new Object();  var bigOne= new Object();  function showChange() {       auto=document.forms[0].ralph;        auto.value="More change."        }  function areaWrite() { bigOne=document.forms[0].alice;  bigOne.value="You have plenty of room to write here."  }  </script>  </head>  <h3>Write something in either text window<br>  and then click the other window.</h3>  <body>  <form>        <input type=text name="ralph" onChange="showChange();"><p>        <textarea cols=30 rows=5 name="alice" onBlur="areaWrite();"></textarea>  </form>  </body>  </html>

No matter what content is placed in either form element, they always end up with the same message because, as soon as the user moves out of the window, the functions fire. Figure 10.5 shows what the windows will always appear to be after a text window is clicked.

Figure 10.5. Both blurring and changing in text and textarea windows can launch JavaScript functions.

graphics/10fig05.gif

The final two event handlers associated with forms are unique in that they are a form type as well as an event handler. To establish a Reset and Submit button in a form container, use this format:

<input type=submit>  <input type=reset> 

What's more, the Reset button will clear all of the text and textarea windows in the form with nothing more than the tag <input type=reset>. No onReset() event handler is required, and no JavaScript is needed, either. However, using the reset() method in JavaScript allows you to reset the forms with the method attached. Also, the onreset event handler can be used as a property in JavaScript in a cross-browser environment. This next example shows how the reset() method can be treated as a property of a form. Because it is a property of a form, you will see that it clears only the form elements of which the method is connected. A second dummy form is provided so that you can see that, while one form is cleared, the other is not. Note also that the reset() method is not part of a form element (property), but is connected directly to the form object.

<html>  <head>  <style type="text/css">  body { background-color:darkorange; font-family:verdana; color:white}  </style>  <title>Reset Property</title>  <script language="JavaScript">  function autoFire() {       document.hope.reset();        }  </script>  </head>  <h4>Type in something in the both text windows and then<br>  pass the mouse over the "JavaScript Method" button.</h4>  <body >  <form name="hope">        <input type=text name="faith"><p>        <input type=button name="glory" value="JavaScript Method"  onMouseOver="autoFire();">  </form> <p>  <form name="dummy">        <input type=text name="dummer">  </form>  </body>  </html>

In addition to the reset( ) method, JavaScript has a submit( ) method that coincides with onSubmit( ) in HTML. However, to really understand the submit( ) method or the onSubmit( ) event handler, you will need to understand more about submitting forms. A discussion of the submit( ) method is left to Chapter 11, where forms are explored in depth.

Page/Window/Image Events

As a category, this last set of events occurs as a side effect to what a user might have initiated. The following five event handlers make up this category:

  • onAbort

  • onError

  • onLoad

  • onResize

  • onUnload

These event handlers work with changes that occur when an event occurs that is not directly controlled by the user. A click by the mouse is fully controlled by the user, but a closing page, while selected by the user because she decided to go to another page, occurs incidental to the event. (In this case, the event would be going to another page.) In several examples, the onLoad event handler has been used to illustrate different features of JavaScript and a few for onUnload, but the other event handlers in this category have not been discussed at all.

The onLoad and onUnload event handlers are associated with the page itself, so the <body> tag is where they are expected to be found and where they usually are found. The event occurs after the page has been loaded, so references to forms that might be in the page that are parsed after the <body> tag can still be included in any function launched by the onLoad event handler. A lesser known use of the onLoad and onUnload event handlers is with the <image> tag. As soon as an image has completed loading, the event can be used to launch a function. Both tags use the following format:

<image src="someGraphic.jpg" onLoad="showLoaded( );">  <body onLoad="showLoaded( );"> 

The following example shows how the onLoad event handler can fill in a form and announce the loading of an image. (An intentionally large graphic file helps in understanding what happens in an onLoad situation.)

<html>  <head>  <title>Using Load with pages and images</title>  <script language="JavaScript">           function whew( ) {          alert("Finally got tubby loaded!");           }  function fillEmUp( ) {          var alpha="All done!";           document.fuzzy.wuzzy.value=alpha;           }  </script>  </head>  <body bgColor="floralwhite" onLoad="fillEmUp( );">  <img src="jumbo.jpg" onLoad="whew( )">  <form name="fuzzy">  <input type=text name="wuzzy">  </form>  </body>  </html>

Both of the onLoad events fire different functions, so you can see that each is working independently with the same type of event handler. The onUnload handler works the same way, except that it occurs on closing.

When something goes wrong, you might want to know about it, especially when debugging the program. Sometimes users will elect to abort a page themselves, most notably when the page is slow in loading. The onError and onAbort event handlers can help in both instances. Both event handlers are used in combination with the <image> tag. The first script shows where to place an onError event handler. (Be sure you do not have a file named importantPic.jpg in the folder where you save this next file.)

<html>  <head>  <title>Error</title>  <script language="JavaScript">  function whoops() {          alert("Ok, Elrod, where\'d you put the graphic file?")           }  </script>  </head>  <body bgcolor="lightskyblue" >  <p>  <h3>This is an important picture you will want to see!</h3>  <img src="importantPic.jpg" onError="whoops( );">  </body>  </html>

The onAbort event handler works in a similar manner to onError, except that, rather than an error causing the show to come to a halt, the viewer has elected to click the Stop button on the browser to stop the rest of the page from loading usually because of a long load. In those cases, you might want to put an onAbort handler in the <image> tag with a message to the effect, that even though the graphic is large, it is certainly worth waiting for!

onResize is the last event handler examined in this chapter. The event is one that affects the window size, but the event handler can be placed in either the <body> or the <frame> tags. In web page design, information returned from onResize can be critical if linked to some other changes that you want to control in the design. However, the event handler itself is fairly straightforward. Run the following script, and change the size of the window to trigger the event:

<html>  <head>  <title>Size change</title>  <script language="JavaScript">  function sizeMeUp( ) {       alert("Size change!")        }  </script>  </head>  <body bgcolor="maroon" onResize="sizeMeUp( );">  <p>  <h3>Nothing to see here folks! Try resizing the window.</h3>  </body>  </html>

Summary

Event handlers are the interactive triggers in HTML and JavaScript. Whether the script traces a location or history property or launches a function, the World Wide Web would be far less interactive and interesting without the event handlers. They make things happen and give the designer tools to use events in planning and executing a web site design.

The bulk of the event handlers do not now have good cross-browser compatibility when used as properties of JavaScript objects. In future versions of JavaScript, such as JavaScript 2.0, developers and designers fervently hope that all browsers will follow the new standards consistently and will implement better event-handling properties that will launch from a method rather than HTML. However, rather than cursing the darkness of cross-browser incompatibility, using the nonconflicting event handlers in a coordinated development with an HTML page provides a wide variety of events from the mouse, keyboard, forms, and pages. By using the rich mix of events, designers can set up a web environment in which the user can experience a wide range of experiences that she herself causes to happen.

CONTENTS


JavaScript Design
JavaScript Design
ISBN: 0735711674
EAN: 2147483647
Year: 2001
Pages: 25

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net