| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| <html xmlns="http://www.w3.org/1999/xhtml"> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
| <title>Ajax</title> |
| <link rel="stylesheet" href="../templates/wondrous/styles.css" type="text/css" /> |
| </head> |
| |
| <body> |
| <div id="container"> |
| <div id="header"> |
| <h1><a href="../index.html">Rivet</a></h1> |
| <h2 id="slogan">Webscripting for Tcl'ers</h2> |
| <div class="clear"></div> |
| </div> |
| <div id="body"> |
| <div id="content"> |
| <h2>Ajax</h2> |
| <div class="example"> |
| <!-- p class="title"><b>Example 6. XML Messages and Ajax</b></p --> |
| <div class="example-contents"> |
| <p> |
| The <b>headers</b> |
| |
| command is crucial for generating XML messages that have to be understood by JavaScript |
| code used in Ajax applications. |
| </p> |
| <p> |
| <b style="border-bottom: 1px solid black;">Brief introduction to Ajax</b> |
| <p> |
| Ajax is a web programming technique that heavily relies on the abilty of a web browser to run in backround |
| JavaScript functions. JavaScript functions can be run as callbacks of events generated by a user interaction |
| but they can also react to other I/O events, for example network events. |
| Modern browsers endow JavaScript with the ability to build http GET/POST requests to be sent to a remote |
| webserver. Generally these requests refer to scripts (e.g. Tcl scripts run by Rivet) which inherit as |
| variables the arguments encoded in the request. |
| The output produced by these scripts is sent back to the browser where callbacks functions extract |
| information and hand it down to functions that directly manipulate a page's DOM. |
| Therefore through Ajax becomes possible to build web applications that are more responsive and flexible: |
| instead of going through the cycle of request-generation-transfer-display |
| of a whole page, Ajax scripts request from a webserver only the essential data to be displayed. |
| Ajax emphasizes the requirement of separation between data and user interface, saves |
| the server from sending over the same html code and graphics if only a fraction of a page has to be |
| updated, allows the programmer to design flexible solutions for complex forms and makes possible |
| to find new innovative approaches to simple problems (e.g. Google tips that show up as you type in |
| a query). A downside of this approach is the large number of complexities, subtleties and incompatibilities |
| that still exist in the way different versions of popular browsers handle the DOM elements of a page. |
| </p> |
| <p> |
| JavaScript can handle the communication between client and server through an instance of a |
| specialized object. For quite a long time 2 approaches existed, the non-IE world (Firefox,Safari,Opera...) |
| used the XMLHttpRequest class to create this object, whereas IE (before IE7) used the ActiveXObject class. |
| With the release of IE7 Microsoft introduced native support for XMLHttpRequest class objects thus enabling |
| programmers with a unique method for the development of dynamic pages. |
| </p> |
| <p> |
| By creating an instance of this class a POST or GET request can be sent to the server and the response is |
| stored in a property ('returnedText') of the communication object. It's become widely customary to encode |
| these responses in XML messages. You can invent your own message structure (either based on XML or anything |
| else), but one has to be aware that if the http headers are properly set and the message returned to the |
| client is a well formed XML fragment, also the property XMLResponse is assigned with a reference to an object |
| that represents the DOM of the XML response. By means of the XML W3C DOM interface the programmer can easily |
| manipulate the data embedded in the XML message. |
| </p> |
| </p> |
| <p> |
| <b style="border-bottom: 1px solid black;">Browsing a database of classical music composers</b> |
| <p> |
| In this example a Rivet script fills a Tcl dictionary with the essential data regarding a few of the major |
| composers of the european music. This dictionary plays the role of a database. The script sends back to the |
| client two types of responses: a catalog of the composers or a single record of a composer. |
| </p> |
| <pre class="programlisting"># |
| # Ajax query servelet: a pseudo database is built into the dictionary 'composers' with the |
| # purpose of emulating the role of a real data source. |
| # The script answers with 2 types of responses: a catalog of the record ids and a database |
| # entry matching a given rec_id. The script obviously misses the error handling and the |
| # likes. Just an example to see rivet sending xml data to a browser. The full Tcl, JavaScript |
| # and HTML code are available from http://people.apache.org/~mxmanghi/rivet-ajax.tar.gz |
| |
| # This example requires Tcl8.5 or Tcl8.4 with package 'dict' |
| # (http://pascal.scheffers.net/software/tclDict-8.5.2.tar.gz) |
| # |
| |
| # A pseudo database. rec_id matches a record in the db |
| |
| set composers [dict create 1 {first_name Claudio middle_name "" last_name Monteverdi \ |
| lifespan 1567-1643 era Renaissance/Baroque} \ |
| 2 {first_name Johann middle_name Sebastian last_name Bach \ |
| lifespan 1685-1750 era Baroque } \ |
| 3 {first_name Ludwig middle_name "" last_name "van Beethoven" \ |
| lifespan 1770-1827 era Classical/Romantic} \ |
| 4 {first_name Wolfgang middle_name Amadeus last_name Mozart \ |
| lifespan 1756-1791 era Classical } \ |
| 5 {first_name Robert middle_name "" last_name Schumann \ |
| lifespan 1810-1856 era Romantic} ] |
| |
| # we use the 'load' argument in order to determine the type of query |
| # |
| # load=catalog: we have to return a list of the names in the database |
| # load=composer&res_id=<id>: the script is supposed to return the record |
| # having <id> as record id |
| |
| if {[var exists load]} { |
| |
| # the xml declaration is common to every message (error messages included) |
| |
| set xml "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" |
| switch [var get load] { |
| catalog { |
| append xml "<catalog>\n" |
| foreach nm [dict keys $composers] { |
| set first_name [dict get $composers $nm first_name] |
| set middle_name [dict get $composers $nm middle_name] |
| set last_name [dict get $composers $nm last_name] |
| append xml " <composer key=\"$nm\">$first_name " |
| if {[string length [string trim $middle_name]] > 0} { |
| append xml "$middle_name " |
| } |
| append xml "$last_name</composer>\n" |
| } |
| append xml "</catalog>\n" |
| } |
| composer { |
| append xml "<composer>\n" |
| if {[var exists rec_id]} { |
| set rec_id [var get rec_id] |
| if {[dict exists $composers $rec_id]} { |
| |
| foreach {k v} [dict get $composers $rec_id] { |
| append xml "<$k>$v</$k>\n" |
| } |
| |
| } |
| } |
| append xml "</composer>\n" |
| } |
| } |
| |
| # we have to tell the client this is an XML message. Failing to do so |
| # would result in an XMLResponse property set to null |
| |
| ::rivet::headers type "text/xml" |
| ::rivet::headers add Content-Length [string length $xml] |
| puts $xml |
| }</pre> |
| <p> |
| For sake of brevity the JavaScript and HTML will not listed here. |
| The whole example is at |
| <a href="http://people.apache.org/~mxmanghi/rivet-ajax.tar.gz">rivet-ajax.tar.gz</a> |
| |
| . |
| By simply opening this tar archive in a directory accessible by your apache server and |
| pointing your browser to <em>rivetService.html</em> |
| |
| you should see a page with a |
| drop-down list. Every time a different name is picked from the list a new query is sent and |
| the data displayed on the page updated accordingly even though the whole html never gets |
| reloaded. |
| The background exchange between browser and apache rivet can be observed looking at |
| the apache log file. |
| </p> |
| <p> |
| This example requires Tcl8.5 or Tcl8.4 with |
| <a href="http://pascal.scheffers.net/software/tclDict-8.5.2.tar.gz" target="_blank">package 'dict'</a> |
| |
| |
| installed |
| </p> |
| </p> |
| </div> |
| </div> |
| |
| |
| |
| <div class="contentbottom"> |
| |
| </div> |
| </div> |
| |
| <div class="sidebar"> |
| <ul> |
| |
| </ul> |
| <ul> |
| <li id="home"> |
| <h4>Rivet</h4> |
| <ul class="blocklist"> |
| <li class="navitem"> |
| <a title="A home for Rivet" href="../index.html">Rivet Homepage</a> |
| </li> |
| <li class="navitem"> |
| <a title="Home of Apache Tcl related stuff" target="asf" href="http://tcl.apache.org/">Apache Tcl Home</a> |
| </li> |
| <li class="navitem"> |
| <a title="Getting Rivet" href="download.html">Getting Rivet</a> |
| </li> |
| <li class="navitem"> |
| <a title="Hello World!" href="hello%5fworld.html">Examples</a> |
| </li> |
| <li class="navitem"> |
| <a title="The Rivet development team" href="about.html">About Us - Contact</a> |
| </li> |
| </ul> |
| </li> |
| <li id="manual"> |
| <h4>Documentation</h4> |
| <ul class="blocklist"> |
| <li class="navitem"> |
| <a title="Rivet 2.1 Manual" target="rivetman2.1" href="http://tcl.apache.org/rivet/manual2.1/">Rivet 2.1</a> |
| </li> |
| <li class="navitem"> |
| <a title="Rivet 2.2 Manual" target="rivetman2.2" href="http://tcl.apache.org/rivet/manual2.2/">Rivet 2.2</a> |
| </li> |
| <li class="navitem"> |
| <a title="Rivet 2.3 Manual" target="rivetman2.3" href="http://tcl.apache.org/rivet/manual2.3/">Rivet 2.3</a> |
| </li> |
| <li class="navitem"> |
| <a title="Rivet 3.0 Manual" target="rivetman3.0" href="http://tcl.apache.org/rivet/manual3.0/">Rivet 3.0</a> |
| </li> |
| </ul> |
| </li> |
| <li id="rivetexamples"> |
| <h4>Examples</h4> |
| <ul class="blocklist"> |
| <li class="navitem"> |
| <a href="hello%5fworld.html">Hello world!</a> |
| </li> |
| <li class="navitem"> |
| <a href="colorful%5ftable.html">A colorful table</a> |
| </li> |
| <li class="navitem"> |
| <a href="var%5faccess.html">Variable Access</a> |
| </li> |
| <li class="navitem"> |
| <a href="file%5fupload.html">File Upload</a> |
| </li> |
| <li class="navitem"> |
| <a href="file%5fdownload.html">File Download</a> |
| </li> |
| <li class="navitem"> |
| <a href="ajax.html">XML and Ajax</a> |
| </li> |
| <li class="navitem"> |
| <a href="calendar.html">Calendar</a> |
| </li> |
| </ul> |
| </li> |
| |
| </ul> |
| <ul> |
| |
| </ul> |
| </div> |
| <div class="clear"></div> |
| </div> |
| </div> |
| <div id="footer"> |
| <div class="footer-content"> |
| <p><a href="http://www.apache.org/">Apache Software Foundation</a> | Design by <a href="http://www.spyka.net">Free CSS Templates</a> | <a href="http://www.justfreetemplates.com">Free Web Templates</a></p> |
| </div> |
| </div> |
| <div style="text-align: center; font-size: 0.75em;">Design downloaded from <a href="http://www.freewebtemplates.com/">free website templates</a>.</div></body> |
| </html> |
| |