CSC 4800 Javascript
See book! Javascript Syntax
How to embed javascript between <script></script> from an external file In an event handler URL - bookmarklet <script language= javascript > <![CDATA[ // javascript code ]]> </script> <script src= myfile.js > </script> <input onclick= foo(); />
Timers id = settimeout(code, delay) cleartimeout(id) id = setinterval(code, interval) clearinterval(id)
When is javascript executed? Code can be embedded at various places in the document. It executes when that section of the document is rendered. This is the one time you can use document.write() without erasing the current document! More frequently, code is attached to an event handler. It runs when the event occurs.
Naming document objects <form name= f1 > </form> document.forms[0] // by position document.forms.f1 // by name document.forms[ f1 ] // array index As we will shortly see, we will normally use other methods to access pieces of a document.
DOM
Interfaces Javascript defines interfaces for: document createattribute(), createelement(), createtextnode() getelementbyid(), getelementsbytagname() node appendchild(), removechild(), replacechild() insertbefore() element getattribute(), setattribute(), removeattribute() getelementsbytagname() This list is not exhaustive!
DOM Levels DOM Level 1, October 1998. defines core DOM interfaces, such as Node, Element, Attr, and Document All modern browsers DOM Level 2, November 2000. required core module has Document, Node, Element, and Text interfaces (and others) events, css Firefox, Safari, Opera IE supports some level 2, like CSS; but not events
innerhtml property more convenient than createelement(), appendchild()
scripting CSS Set the style directly change the class change the stylesheet
Javascript Events Three event models original event model standard event model IE event model
Basic Event Handling Events and Event Types onblur onchange onclick, ondblclick onkeydown, onkeypress, onkeyup onmouseover, onmousedown, onmousemove, onmouseout, onmouseup onfocus onload onsubmit etc. Device-dependent vs. device-independent events
Event Handlers as Attributes <input type= button onclick= alert( pressed ); /> Usually better to call a function: <form onsubmit= return formvalidate() >
Event Handlers as Properties document.f1.b1.onclick=myfunction; Note that the line is NOT: document.f1.b1.onclick=myfunction(); Advantages (vs attributes) reduces intermingling of HTML and js dynamic Disadvantage separates handler from element
Event Handler Return Values return false to prevent default action For example, form validation.
Event Handlers and this handler is a method of the element that generated the event. button.onclick = o.mymethod; Inside mymethod, this refers to button, not to o. You can do this: button.onclick = function() {o.mymethod();}
Javascript & forms Every form element has a name attribute used for form submission: <input type= text name= lastname /> <form> also has a name attribute Not used for form submission But can be used with javascript <form name= studentform > can be accessed like document.studentform and the fields can be accessed like document.studentform.lastname
Form element properties type (read-only) form (read-only) name (read-only) value (read/write) string sent to server when form is submitted. text, textarea: text entered by user radio, checkbox: value not seen by user a string set in html
Ajax Using XMLHttpRequest create XMLHttpRequest object specify and submit HTTP request to server (usually) asynchronously retrieve response
Creating a request object // This is a list of XMLHttpRequest creation factory functions to try HTTP._factories = [ function() { return new XMLHttpRequest(); }, function() { return new ActiveXObject("Msxml2.XMLHTTP"); }, function() { return new ActiveXObject("Microsoft.XMLHTTP"); } ]; // When we find a factory that works, store it here HTTP._factory = null; // Create and return a new XMLHttpRequest object. // // The first time we're called, try the list of factory functions until // we find one that returns a nonnull value and does not throw an // exception. Once we find a working factory, remember it for later use. // HTTP.newRequest = function() { if (HTTP._factory!= null) return HTTP._factory(); for(var i = 0; i < HTTP._factories.length; i++) { try { var factory = HTTP._factories[i]; var request = factory(); if (request!= null) { HTTP._factory = factory; return request; } } catch(e) { continue; } } } // If we get here, none of the factory candidates succeeded, // so throw an exception now and for all future calls. HTTP._factory = function() { throw new Error("XMLHttpRequest not supported"); } HTTP._factory(); // Throw an error
Sending/Handling async response function makerequest() { var request = HTTP.newRequest(); request.onreadystatechange = function() { if (request.readystate == 4) { // if request is finished if (request.status == 200) { // if it was successful Using Ajax from html: <h2 onclick="makerequest()">simple Ajax</h2> alert(request.responsetext); } } } request.open("get", 'getcountries'); } request.send(null);
Javascript Libraries Prototype - http://www.prototypejs.org/ script.aculo.us
Prototype: Ajax.Updater In the layout: <%= javascript_include_tag :defaults %> <%= stylesheet_link_tag "ajaxtest" %> javascript: <script type="text/javascript"> //<![CDATA[ function makerequest() { new Ajax.Updater('cresult','getcountries', { method: 'get', parameters: {name: $('name').value} }); return false; // don t submit the form! } //]]> </script>
Prototype: Ajax.Updater HTML: <h2>prototype Ajax Example</h2> <form action="#" onsubmit="return makerequest()" > <input type="text" name="name" id="name" /> <input type="submit"> </form> <div id="cresult"></div>
Prototype: Ajax.Updater getcountries.rhtml <ul> <% @countries.each do c %> <li><%= c.name %></li> <% end %> </ul> getcountries in controller def getcountries end name = params['name'] 'G'; @countries = Country.find(:all, :conditions => render :layout => false ["name ilike?", name+'%'])
script.aculo.us autocomplete View <%= text_field 'user', 'country' %> <br/> <div id="user_country_auto_complete" class="auto_complete"> </div> <%= auto_complete_field :user_country, :url=>{:action=>'autocomplete_countries'} %> autocomplete_countries.rhtml <ul class="autocomplete_list"> <% @countries.each do c %> <li class="autocomplete_item"><%= c.name %></li> <% end %> </ul>
script.aculo.us autocomplete controller code for autocomplete def autocomplete_countries end @countries = Country.find(:all, :conditions => ["name ilike?", params[:user][:country]+'%']) render :layout => false