The exampleThis example implements a simple Ajax input autocompleter and dynamic page update. For the autocompleter, as soon as you enter a few letters into the input, it provides a list of matching terms. As soon as you select a term, the page is dynamically updated with associated data, as in the following screenshot:
For the purposes of the demonstration, the content is information on the countries of the world, obtained from the CIA World Factbook.
Ajax.Autocompleterassociated with the
autocomplete_choicesdiv sends inputs to
- The Arc handler sends back a formatted list of autocomplete candidates, e.g.
Ajax.Autocompleterdisplays the candidates in the
- When an autocompletion is selected, the
Ajax.Updaterinstances, which send an Ajax request to URL
/getcontents?field=population&name=value, and similarly for area and capital in parallel.
- The Arc handler for
getcontentsreturns the desired contents.
Ajax.Updaterputs the contents into the
- The Arc handler for
Running the exampleFirst set up the necessary files.
- Download ajax.zip and uncompress it into the
same directory that Arc runs in. This zip file provides
- Download the script.aculo.us library files from script.aculo.us. Copy the
srcinto the same directory that Arc runs in.
ajax.arcfile, and start the web server.
arc> (load "ajax.arc") arc> (thread (serve 8080)) arc> ready to serve port 8080Then go to http://localhost:8080/ajax.html. (Unfortunately I don't have a live demo on a public machine. If anyone sets one up, let me know and I'll add a link here.)
Start typing in the box, and you should see a dropdown with autocompleted choices. Click one, and the code will be displayed below asynchronously.
The Arc codeThe Arc server code is in
ajax.arc. Two Arc handlers are implemented to provide the client-side Ajax support. The first,
auto_completereceives the current input contents and returns a list of up to 10 autocompletion candidates formatted in HTML. The second handler,
getcontentsreturns the dynamic content for the page, from the
databasetable. Note that the handlers do nothing particularly special to make them "Ajax"; they are standard Arc web handlers based on
defopand can be accessed directly through the browser. See Arc Web Server for more information on web serving with Arc.
(defop auto_complete req (let prefix (downcase (arg req "prefix")) (prn (to-html-list (cut (startselts prefix keylist) 0 10))))) (defop getcontents req (with (field (arg req "field") name (arg req "name")) (if (is field "population") (prn ((database name) 1)) (is field "area") (prn ((database name) 2)) (is field "capital") (prn ((database name) 3)))))The handlers use a couple helpers;
startseltsreturns the elements that match the autocomplete prefix and
to-html-listwraps the elements in HTML list tags.
; Returns a list of elements that start with prefix (def startselts (prefix seq) (rem [no (begins (downcase _) prefix)] seq)) ; Wraps elts in HTML list tags (def to-html-list (elts) (tostring (prall elts "<ul><li>" "</li><li>") (pr "</li></ul>")))The actual content is obtained from
data.arc, which contains the information on each country as a list of lists.
("United States" "301,139,947" "9,826,630" "Washington, DC")Some simple code converts the list into a table called
databaseindexed by country for easy lookup, and generates a sorted list of countries for use in autocompletion:
(= database (table)) (w/infile inf "data.arc" (let datalist (sread inf nil) (each elt datalist (= (database (elt 0)) elt)))) (= keylist (mergesort < (keys database)))
For some reason, the default Arc web server
srv.arc doesn't support
.js files. The
ajax.arc file modifies the server slightly to support these files:
The Arc code can be debugged in several ways. The first is to access the handlers directly. The autocomplete handler http://localhost:8080/auto_complete?prefix=a should return a bullet list of autocomplete suggestions. The contents handler: http://localhost:8080/getcontents?field=area&name=Algeria should return the dynamic contents value.
The Arc code can also be debugged by strategically inserting print statements such as:
(write req (stderr))This will display the request on the Arc console.