Documentos de Académico
Documentos de Profesional
Documentos de Cultura
server The browser was just a simple, generalized user interface that did not play a role in executing the application logic It is beneficial for clients to share in the execution of some of the application logic Central focus of client-side scripting is to manipulate the content of a web page Application logic as such is not concerned with presentation, but client-side scripting can be used to make web pages more dynamic
Field and form validation o For example, a date entry field should never accept the date Feb 30 o Without client-side validation this value would be submitted with the form and only there identified as an incorrect value o Relying solely on server-side validation is expensive (server trips) Automatic computation of dependent values o For example, when an item is added to a shopping cart, the new total can be computed automatically on the client
New input controls o For example, a date-picker control that pops up a calendar for the user to select a date from Rollovers and swaps o For example, as the mouse moves over an image it is replaced by another image that gives feedback to the user that the image can be clicked Adding HTML to the page o For example, a client-side script can insert the current date into a web page dynamically
Regardless of the scripting language, the Document Object Model (DOM) provides a platform-neutral interface to browser and content of a page Defined by the W3C Most browsers implement it in their latest versions The name Document Object Model was chosen, because it provides an object interface to HTML (and XML) documents (data and behavior)
JavaScript
Most common scripting technology in browsers available today Name a misnomer: JavaScript was born as "LiveScript" and its name was changed for marketing purposes However, it does share some basic syntax with Java, which makes it easy to learn o JavaScript does not have Java's typing system o Fewer core data types o Prototype-based object model (does not support inheritance)
Browser?
<script language="JavaScript"> function inRange(value, low, high) { return low <= value && value <= high; } function checkAge(field) { if (!inRange(field.value, 18, 99)) { alert("Enter a correct age!"); } } </script> Check Age
Events
Normal way of invoking JavaScript is in response to interface events
o <input type="text" name="age" onChange="checkAge(this);">
An event is something that triggers a script The event handler parameter of the HTML element defines the code (usually a call to a function) that will handle the event when it is fired o Some of the more common events are: onClick -- User clicks a form field or link onChange -- User changes the value of a form field onMouseOver -- User moves mouse pointer over a link onMouseOut -- User moves mouse out of an image or link onSubmit -- User submits a form
o o
Include it between <script> tags in the head of your web page, and insert the following somehwere in the body
o <form name="f2c"> Temperature: <input type="text" name="fahrenheit" value="32"> F to <input type="text" name="celsius"> C <input type="button" value="Convert" onClick="convert(this.form)"> </form>
Convert Temperature
How to Rollover?
A rollover swaps one image for another as the user moves over an image In the following code we refer to the image by its name (order) The onMouseOver handler sets the "src" property of the image to another value The onMouseOut handle resets the "src" property to its original value
o <a href="checkout.html" onMouseOver="images.order.src='rollover-2.jpg'" onMouseOut="images.order.src='rollover-1.jpg'"> <image name="order" src="rollover-1.jpg" border="0"> </a>
Rollover
Input Validation
o
Restrictions on a form Some fields may only accept numbers Others may only accept dates Some fields may only accept a range of entries Some fields may be required Some combination of fields may not be permitted Handle restrictions by two types of checks Validate each element as data is entered Perform validation when the form is submitted
Perform data validation just before form is submitted Perform such checks using the onSubmit event handler
onSubmit handler must return true or false If it returns false, the form will not be submitted
function checkForm(form) { if (form.age.value == "") { alert("Please enter your age"); return false; } return true; } o
form.age.value form["age"].value
Checking for integers Checking for ranges Checking for phone numbers Checking for postal codes
If the value contains other characters than numbers, parseInt() will be different from value
o
function inRange(value, low, high) { return low <= value && value <= high; } o
Obvious!
number
function checkPostalCode(field) { if (!field.value.match(/([A-Z][0-9]){3}/)) { alert("Incorrect postal code"); return false; } return true; } o
Examples
o
All examples
Day of Week
Add new appointment for:
Events
How old are you?
Temperature Converter
Temperature: F to C
Rollover
Input Validation
Phone: Postal Code:
Topics
Basics Primitives, Operations and Expressions Screen Output Control Statements Object Creation Arrays, Functions
JavaScript Basics
Collection of objects supporting control of browser and user interaction. Can be used on server too, but it is different there. Not studied here Isn't typed like Java -- more like Perl. Variables are dynamically bound at run time.
Similar syntax to Java ... but don't be fooled! Used instead of Applets because: o Easier to learn, graphics are simpler o Simple event model using callbacks o Applets downloaded separately to HTML
JavaScript Objects
Objects have collections of properties (members in Java or C++). Properties are data or method. Data either primitive or reference to object. Properties referenced by <object>.<property;> e.g. myCar.engine Javascript objects appear as Perl hashes: internally and externally Identifiers are CASE SENSITIVE: Foo and foo are different variable names.
Using JavaScript
Using <script> tag in head and body of HTML. Can write JavaScript inline or reference files externally. Internally <script language="JavaScript"> function testValue(field) { if (field.value < 0) { alert("Negative value!); } } </script> Externally <script language="JavaScript" src="test_value.js"></script>
Hide code from browsers without JavaScript using: <!-- ... //--> Semi-colons are optional in most cases, but use them anyway!
Number String Boolean Wrappers for primitive types but define methods on them. Variable declared with var keyword.
var birthday = "8th March", index;
e.g. max, min, floor, sin, cos ... Number provides several useful constants: MAX_VALUE Largest representable number MIN_VALUE Smallest representable number
NaN Not a number POSITIVE_INFINITY Special value to represent infinity NEGATIVE_INFINITY Special value to represent negative infinity PI 3.14159265358979323846 approximately NaN != NaN (Use isNaN() to test). Useful method toString() on Number, although coercion often automatic.
Strings
Returns character at N Position in string of character C Substring from Ith to Jth characters Converts to lower case Converts to upper case
Screen Output
JavaScript interpreted as body of HTML document is interpreted. Output from JavaScript goes to same place as HTML document. Use Document object (see DOM) A good reference on DOM programming. Use write method of document object: document.write("Hello world<br/>"); Can include ANY HTML in write method -- don't use \n Window object can generate dialog boxes: alert("Warning something bad has happened."); Alert var question = confirm("Do you want to continue?"); Confirm var birthday = prompt("What is your birthday?", "8th March"); Prompt Dialogs are modal
Is equal to Is not equal to Is less (or equal) than (to) Is greater (or equal) than (to) Is strictly equal to Is strictly not equal to
Also have the use AND (&&), OR (||) and NOT (!)
switch
switch (expression) { case value_1: // value_1 statements case value_2: // value_2 statements ... default: // default statements // Optional }
Selection Example
<html> <head> <title>A switch statement</title> </head> <body> <script language="JavaScript"> var case = 3; switch (4 * case - 10) { case 1: document.write("It's case 1", "<br/>"); break; case 2: document.write("It's case 2", "<br/>"); break;
case 3: document.write("It's case 3", "<br/>"); break; default: document.write("Error in switch statement, "<br/>"); break; } </script> </body> </html> Switch
my_new_object has no properties initially. Can create properties by assigning them. Object is a hash ... just like Perl
var my_car = new Object(); my_car.make = "Ford"; my_car.model = "Focus"; my_car.year = 2002; my_car.engine = new Object();
Can also use constructors to generate "types". Can iterate on properties (just like Perl's foreach):
for (identifier in object) { statements } for (var prop in my_car) { document.write("Name: " + prop + "; Value: " + my_car[prop] + "<br/>"); }
Arrays
Array bounds start at zero. my_array.length; // gives me the current length of my_array my_array.length = 100; // makes the current length of my_array 100 my_array.join(" : ") would yield "1 : 2 : three : four" my_array.reverse() would yield ["four", "three", 2 1] Also have sort()
var names = ["Bill", "Ben", "Alice", "Tony"]; var sorted_names = names.sorted(); sorted_names == ["Alice", "Ben", "Bill", "Tony"];
And slice()?
var slice_of_names = names.slice(1,3); slice_of_names == ["Ben", "Alice", "Tony"]; slice_of_names = names.slice(2); slice_of_names == ["Alice", "Tony"];
Array Operations
to to
Multidimensional Arrays
Functions
Using "function" keyword Can have references to functions too. function foo(arg1, arg2) { var function_name = "foo"; current_function = function_name; document.write("This is the " + function_name + " function. <br/>";); } var reference2foo = foo; // Can call foo via reference now reference2foo(); Have to define function before refering to it. Functions go in <head> section of document.
Functions
NOTE: Implicitly declared variables are GLOBAL; e.g. current_function Local variables of same name take precedence over global declarations. Parameter passing is by value, but objects are references! Parameters communicated via arguments array -- actual as well as formal. arguments array is similiar to @_ in Perl.
foo(1, 2, 3); // Formal are 1 and 2, arguments array is [1, 2, 3] foo(1); // Formal is 1, arguments array is [1]
Constructors
You can use "new Object()" and assign properties, but it's awkward. Constructors are special functions for creating and initializing objects.
function car(new_make, new_model, new_year) { this.make = new_make; this.model = new_model; this.year = new_year; } // Constructing a car var my_car = new car("Saturn", "SL1", "2002"); Can have method as well as data properties. function display_car() { document.write("Car make: ", this.make, "<br/>"); document.write("Car model: ", this.model, "<br/>"); document.write("Car year: ", this.year, "<br/>"); } // Now constructor is: function car(new_make, new_model, new_year) { // Data properties this.make = new_make; this.model = new_model; this.year = new_year; // Method properties this.display = display_car; // <-- Method to display myself } // Display myself var my_car = new car("Saturn", "SL1", "2002");
Pattern Matching
replace method
var str = "Fred, Freddie, and Frederica were siblings"; str.replace(/Fre/g, "Boy"); // str == "Boyd, Boyddie, and Boyderica were siblings"; // $1, $2, and $3 variables are set to "Fre"
match method
var str = "I can have 1 2 3 or 4 chances to win." var matches = str.match(/\d/g); // matches == [1, 2, 3, 4]
split method
var str = "pears:grapes:apples"; var fruit = str.split(/:/); // fruit == [pears, grapes, apples]
Topics
Document Object Model (review) Events and event handling Events, attributes and tags Load and unloading documents Button events Event propagation
forms Forms defined within the HTML document forms.elements Objects within the form; e.g. buttons and menus
Events
JavaScript implements an event-driven programming model. Events are notifications of something noteworthy happening: o Document loading or unloading o Clicking a button o Changing focus from one element to another Events are processed by event handlers. Similiar to, but simpler than, Java model. Events are objects, so names are case-sensitive. Don't use the document.write() method in event handlers! Tag Attribute Explanation onAbort Image loading aborted 1. A document or frame loses input focus onBlur 2. Text or selection element loses focus 1. Text field or area changes and loses focus onChange 2. Selection element changes and loses focus 1. Click on link 2. Submit, Reset or other Button is pressed 3. Radio button is pressed onClick 4. Checkbox is clicked 1. Image loading error 2. Document loading error 3. Frame loading error 1. Document or frame receives focus 2. Text field or area receives focus 3. Select element receives focus 1. Image has been loaded
change
click
error
onError
focus
onFocus
load
onLoad 2. Document or frame has been loaded 1. Mouse moved from over link
mouseout
onMouseOut 2. Mouse moved out of image map 1. Mouse moved over link
mouseover onMouseOver reset resize onReset onResize 2. Mouse moved into image map Reset button pressed Window size is changed
1. Mouse cursor moved over text field select submit unload onSelect onSubmit onUnload 2. User exits a frameset 2. Text area is selected within a text area Submit button is pressed 1. User exits the document
Event Propagation
Can handle events on one element by another Document can handle ALL onchange events (for example) Table could handle ALL onchange events for its cells load, unload, focus and blur events do not propagate
Dynamic Content
DHTML examples Can modify DOM tree dynamically. Addition, deletion and editing possible e.g. Adding TEXT function appendTEXT(tag,index,text){ var oj = document.createTextNode(text) ; document.getElementsByTagName(tag).item(index).appen dChild(oj); } <FORM> <INPUT TYPE="button" VALUE=" to DIV0" onClick="if(document.getElementById)appendTEXT('D IV',0,' (^^)/DIV0 ')"> <INPUT TYPE="button" VALUE=" to DIV1" onClick="if(document.getElementById)appendTEXT('D IV',1,' (^^)/DIV1 ')"> <INPUT TYPE="button" VALUE=" to DIV2" onClick="if(document.getElementById)appendTEXT('D IV',2,' (^^)/DIV2 ')"> <INPUT TYPE="button" VALUE=" to SPAN0" onClick="if(document.getElementById)appendTEXT('S PAN',0,' (^^)/SPAN0 ')"> <INPUT TYPE="button" VALUE=" to SPAN1" onClick="if(document.getElementById)appendTEXT('S PAN',1,' (^^)/SPAN1 ')">
Adding an Image function addImage(imageURL) { var imgEl = document.createElement("IMG"); imgEl.src = imageURL; imgEl.id = imageURL; document.body.appendChild(imgEl); } <a href="javascript:addImage('rollover.jpg'); void 0">Adding an Image</a>
Adding an Image
Edit the image function editImage(id, src) { var imgEl = document.getElementById(id); imgEl.src = src; // Should re-do the size of the image -- exercise to student } <a href="javascript:editImage('rollover.jpg', 'dom.jpg'); void 0">Editing an Image</a>
Editing an Image
Remove an Image
Text field: Hide form <a href="javascript:document.getElementById('dynamicForm').style.visibility ='hidden'; void 0">Hide form</a> Show form <a href="javascript:document.getElementById('dynamicForm').style.visibility ='visible'; void 0">Show form</a>
Cookies
Can be created on the client side too. DOM exposes cookie through document.cookie Set a cookie by assigning property, retrieve one by reading its current value. The following statement, for example, sets a new cookie with a minimum number of attributes:
Value of document.cookie is string containing a list of all cookies associated with web page. Consists of name=value pairs for each cookie that matches the current domain, path, and date.
cookieName1=cookieValue1; cookieName2=cookieValue2
begin += 2; var end = document.cookie.indexOf(";", begin); if (end == -1) end = dc.length; return unescape(dc.substring(begin + prefix.length, end));
// name - name of the cookie // [path] - path of the cookie (must be same as path used to create cookie) // [domain] - domain of the cookie (must be same as domain used to create cookie) // * path and donavigator.mimeTypesdoublemain default if assigned null or omitted if no explicit argument proceeds // Sets the expiry date so that the cookie will disappear immediately. function deleteCookie(name, path, domain) { if (getCookie(name)) { document.cookie = name + "=" + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT"; } }
if (!visits) { visits = 1; // the value for the new cookie document.write("<span style=color:red>By the way, this is your first time here.</span>"); } else { // increment the counter visits = parseInt(visits) + 1; document.write("<span style=\"color:red\">By the way, you have been here <i>" + visits + "</i> times.</span>"); } // set the new cookie setCookie("counter", visits, now);
Has it changed?
if (lastModified) { document.write("Document changed since last visit"); } // create an instance of the Date object var now = new Date(); // fix the bug in Navigator 2.0, Macintosh fixDate(now); // cookie expires in one year (actually, 365 days) // 365 days in a year // 24 hours in a day // 60 minutes in an hour // 60 seconds in a minute // 1000 milliseconds in a second now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); setCookie("lastModified", document.lastModified, now); } // --> >/script> Document changed since last visit
Bookmarklets
URLs with JavaScript code that have been saved as bookmarks o http://www.bookmarklets.com How you turn an URL into a bookmark is browser-specific, for example o Right-click and choose to save link as bookmark o Left-drag to personal toolbar Your first bookmarklet
javascript:void(window.open(''))
Open window
Create your own bookmarklet that looks up a word you have selected on your page on the Merriam-Webster web site
javascript:q=document.selection.createRange().text;location.href ='http://www.m-w.com/cgi-bin/dictionary? book=Dictionary&va='+escape(q); void(0)
How did we know this? Look at the form on the web site
<FORM name="dict" method="post" action="/cgi-bin/dictionary"> <TD valign="middle" width="165"> <INPUT type="hidden" name="book" value="Dictionary"> <FONT color="#ffffff" size="2" face="Arial, Helvetica"><B>Collegiate<SUP></SUP> Dictionary</B></FONT> </TD><TD valign="middle" width="140"> <INPUT name="va" size="15"> </TD><TD valign="middle" width="95"> <INPUT type="submit" value="Look it up"> </TD> </FORM>
Lookup in Webster
Google Search
Recap
o
Execute in the browser's frontmost window Can interact with object or data in this window Example o Create and store comments on web pages o Retrieve them later when you visit the pages again
o o
Example - CGI
Accepts an URL and a comment and records them Retrieves a comment when given an URL Declarations
#!/usr/bin/perl use CGI; use CGI::Carp( fatalsToBrowser ); my $scriptUrl = "http://localhost/~mrw/cgi-bin/245/comment.cgi"; my $q = new CGI; my $url = $q->param("url"); my $comment;
Example - CGI
Example - CGI
print $q->header("text/html"), $q->start_html(-title => $url, -bgcolor => "yellow"), $q->start_form({ action => $scriptUrl }), $q->hidden("url"), # inherits value $q->textarea(-name => "comment", -cols => 30,
$q->p(
Example -CGI
sub getComment { my $url = shift; my %db; dbmopen(%db, "comment_db", 0666) || die "unable to open comment database"; requestLock("comment_db"), my $comment = $db{$url}; releaseLock("comment_db"), dbmclose(%db); return $comment; }
Example - CGI
sub saveComment { my ($url, $comment) = @_; my %db; dbmopen(%db, "comment_db", 0666) || die "unable to open comment database"; requestLock("comment_db"), $db{$url} = $comment; releaseLock("comment_db"), dbmclose(%db); }
Example - JavaScript
Commentlet
Example - Usage
Visit a web site and select the bookmarklet Browser displays another window
Enter a comment and save it On returning to the page, the window will contain your original comment Comments can be shared with other users!
#!/usr/bin/perl
comment.cgi
use CGI; use CGI::Carp( fatalsToBrowser ); my $scriptUrl = "http://localhost/~mrw/cgi-bin/245/comment.cgi"; my $q = new CGI; my $url = $q->param("url"); my $comment; if ($q->param("save")) { $comment = $q->param("comment") || ""; saveComment($url, $comment); } else { $comment = getComment($url); } print $q->header("text/html"), $q->start_html(-title => $url, -bgcolor => "yellow"), $q->start_form({ action => $scriptUrl }), $q->hidden("url"), # inherits value $q->textarea(-name => "comment", -cols => 60, -rows => 14, -value => $comment, -wrap), $q->p( $q->submit(-name => "save", -value => "Save Comment")), $q->end_form, $q->end_html; sub getComment { my $url = shift; my %db; dbmopen(%db, "comment_db", 0666) || die "unable to open comment database"; requestLock("comment_db"), my $comment = $db{$url}; releaseLock("comment_db"), dbmclose(%db); return $comment; } sub saveComment { my ($url, $comment) = @_; my %db; dbmopen(%db, "comment_db", 0666) || die "unable to open comment database"; requestLock("comment_db"), $db{$url} = $comment; releaseLock("comment_db"),
dbmclose(%db);
# one of many ways to do this ... sub requestLock { my $alias = shift; my $n = 0; my $lock = $alias . ".lock"; while (mkdir($lock, 0555) == 0) { $! == $EEXIST || die "can't make $lock: $!"; $n++ < 30 || die "timed out waiting for $lock"; sleep(1); } } sub releaseLock { my $alias = shift; my $lock = $alias . ".lock"; rmdir($lock); }