![]() | |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
This probably should be a reply in the 'how do we get there from here' thread but I thought I would start a new thread for those who might be interested. With all of the (apparent) interest in AJAX here (and the attendent ooohs and aaahs when it is mentioned <g>), here is some information that I hope helps people 'allow' themselves to play with this cool technique. All you need is: 1. Access to a web server (I think that even most Microsoft O/S's have one these days). 2. Some sort of server side output producer (a batch file that echoes its input). 3. A javaScript enabled web browser. I thought that Dawn had some new techniques for this but it now appears that was simply confusion over content delivery methods within the AJAX framework - this is covered in the 'notes' below. In an attempt to simplify and de-mystify this technique, I made a little test page that should demonstrate a reasonable use: http://openqm.blackflute.com/pmgr/ziptest.html The bulk of the 'magick' (well all of it really) is accomplished by javaScript functions that can be seen by using your browser's View Source function. I will show those here with some notes: One of the first things to happen is toward the last in the html code: The trigger that initiates everything. In our example, I am using the 'onBlur' method. This will execute the assigned function when the field loses focus. Here is the field definition: input type='text' id='zip' size='10' onblur='loadXMLDoc("zipall.php?zip="+this.value)' The onBlur definition tells the browser to call the 'loadXMLDoc() function with the argument '?zip=xxxxx' where 'xxxxx' is the zip code typed into the zip field. This function is called when the zip field loses focus (the user Tabs away or clicks on another field): The loadXMLDoc() function with notes: function loadXMLDoc(url) { // Internet Explorer try { req = new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) { try { req = new ActiveXObject('Microsoft.XMLHTTP'); } catch(oc) { req = null; } } // Mozilla/Safari if (req == null && typeof XMLHttpRequest != 'undefined') { req = new XMLHttpRequest(); } // Call the processChange() function when the page has loaded if (req != null) { req.onreadystatechange = processChange; req.open('GET', url, true); req.send(null); } } The first two sections (marked 'Internet Explorer' and 'Mozilla/Safari') create the javaScript request object. Microsoft's method is attempted first then if that fails (req == null), the Mozilla method is used. The last step is to set up the actual call: First, we make sure that one of the methods above worked (req != null) then 1. Set the onReadyStateChange handler to our processChange() function (below). 2. Make the actual request (this is like clicking 'Go' in the browser). 3. Send additional information (none in our case). In 2. above, 'url' will be 'zipall.php?zip=12345' where 12345 is the text typed into the 'zip' field. We could have sent the zip=12345 via the req.send() function after setting a content type of 'application/x-www-form-urlencoded' (oops, I was going to keep this simple). This is the 'Asynchronous' part. The request has been sent. Our javaScript interpreter has been asked to track its progress. When things are right (readystate = 4 and status = 200) we will have complete results from the request. This combination of states is tested in the other function (the callback): function processChange() { // The page has loaded and the HTTP status code is 200 OK if (req.readyState == 4 && req.status == 200) { // Write the contents of this URL to the CityDiv layer document.getElementById('CitySpan').innerHTML = req.responseText; } } The first active line of processChange() tests for our 'Request Complete' condition. When these conditions exist, this function simply stuffs the output from the zipall.php function into the named document element 'CitySpan'. The part that you can't see is the zipall.php routine. This could be anything that produces output through the web server - a static HTML page (maybe we have a collection of clever sayings in separate HTML files and our javaScript above generates a random ID), a php script, perl, Java, SSI, you name it. I like PHP so our example uses php. What zipall.php does is this: Upon entry checks if 'zip' (passed from the HTML call) is NULL. If so, prints 'Please enter a Zip Code.' and exits. If zip isn't NULL, zipall.php creates a query string to be passed to openQM via the client library PHP wrappers. This query is: LIST ZIPCODES WITH @ID = '$zip' CITY STATE APN Where '$zip' contains the text entered in the zip form field above. The ZIPCODES file contains among other things a flag for preference, I called it 'APN' for the codes 'Acceptable', 'Preferred' and 'Not Accepted' (but I am ignoring the 'N' and allowing it anyway). If the query yields results (i.e. if a valid Zip was entered), an HTML form select field is constructed containing the city names for this zip. The city that is flagged as 'P'referred is marked 'SELECTED' and so is presented as the selected item in the pull-down. The City and Country (US only) fields are constructed and filled with data from the query result. The whole mess generated above is simply output to the browser. When the processChange() function receives it, it is placed in the CitySpan element. If you wish to look at this part by itself, simply call it: http://openqm.blackflute.com/pmgr/zipall.php?zip=44875 (I used my office's zip because it contains several city names) You can then view source and see what it has spit out: select id='city' option value='Ganges'>Ganges</option option value='Bethlehem'>Bethlehem</option option value='Shelby' selected>Shelby</option option value='Little London'>Little London</option option value='Sharon Township'>Sharon Township</option option value='Taylortown'>Taylortown</option /select St: input type='text' id='state' size='2' value='OH' Ctry: input type='text' id='ctry' size='6' value='US' The above snippet is then stuffed into CitySpan by processChange(). Simple, eh? Some notes: In the phases above it really doesn't matter from whence cometh the data. In this example the original HTML comes from a static file (ziptest.html). This could as easily be generated by a php (perl, java, shell, ASP, whatever) script or could even simply be INCLUDED by a script. No real difference to the browser (which is what counts). I often INCLUDE (REQUIRE actually) a static HTML file so that I can keep the scripts owned by root (therefore the site owner can't overwrite them) and the HTML owned by the site owner so they can change the appearance if they wish. In the server side phase, anything that can output through the web server can be used to generate the data. There is no magick - use whatever works for you. A BIG note: Part of the mystification of this method seems to be the XML part. I don't know whether you noticed but there is NO XML code or data whatsoever invloved in this example. The reason that XML is even part of the name is that the javaScript method used is XMLHttpRequest() - a method developed for XML use. We can use it just fine for HTML or just plain text. HTH, -Tom |
#3
| |||
| |||
|
#4
| |||
| |||
|
#5
| |||
| |||
|
|
What I noticed about this functionality is it's exactly what Tony G did 6 years ago using FlashConnect. The basic idea then was to create a "hidden" frame then communicate to the D3 server directly. The return data came back to the "hidden" frame as an executable Javascript then put data back into the appropriate controls on the main page. |
#6
| |||
| |||
|
|
I daresay Doug @ Modsoft would sugest that this alread HAS been done, and is called Coyote! However, the biggest problem with ASP (in any form, including PHP generated pages) is that the PAGE is dynamic, not just the content, wheich means that every time you call up a 20K page that is dynamically created, you need to send out 20K of "new" HTML |
|
Bill, the end result of using the XMLHTTP pipe is similar to Tony's hidden frame technique (also used by Pixie, and Visage at one stage), but the plumbing is different. Certainly at least close cousins. |
|
AJAX isn't new, but it has ignited interest in web based applications, and as a vendor of a tool that has been (unwittingly) developing AJAX frameworks for over a decade, I think that can only be a good thing :-) |
#7
| |||
| |||
|
|
This probably should be a reply in the 'how do we get there from here' The whole mess generated above is simply output to the browser. When the processChange() function receives it, it is placed in the CitySpan element. -Tom |
#8
| |||
| |||
|
|
Ah, thank you for the explicit code! I learned something, that you can setup the entire Select element via the innerhtml change (which should be obvious |
|
after all this time, but...) We do that with a loop of " new Option= xxx" to populate each option of the Select element, and I wonder how much more efficient this one-shot method is? |
#9
| |||
| |||
|
|
Hi Chandru, Ah, thank you for the explicit code! I learned something, that you can setup the entire Select element via the innerhtml change (which should be obvious You are welcome. Note that the State and Country fields are also being created and populated by the PHP script. The Country is just being dummied in since it is a US Zip Code database. after all this time, but...) We do that with a loop of " new Option= xxx" to populate each option of the Select element, and I wonder how much more efficient this one-shot method is? Are you using js for the 'new Option=xxx' loop? If so I suspect that the server side processing will be quicker (but don't know that). Yes, something like: |
#10
| ||||
| ||||
|
|
Hi Ross, Ashamed to admit that I haven't found the time yet to look at Coyote |
|
but is the ASP approach the only one allowed? |
|
I would have assumed some simple PRINT, printf(), echo capability as opposed to outputting a complete page only? If this is a possibility then the method outlined here would work well with Coyote. Now I am going to have to make the time to take a look. |
|
And I agree about that being a good thing. May I respectfully request accuracy in communication? The 'developing AJAX frameworks for over a decade' statement implies that you somehow had a beta copy of IE 5 back when the rest of us were struggling with NCSA Mosaic. |
![]() |
| Thread Tools | |
| Display Modes | |
| |