Skip to main content
Engineering LibreTexts

14.8: A Quick Look at AJAX

  • Page ID
    43219
    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    AJAX (Asynchronous JavaScript and XML) is a technique to make web applications more interactive by exploiting JavaScript functionality on the client side.

    Two well-known JavaScript libraries are Prototype (http://www.prototypejs.org) and script.aculo.us (http://script.aculo.us). Prototype provides a framework to ease writing JavaScript. script.aculo.us provides some additional features to support animations and drag-and-drop on top of Prototype. Both frameworks are supported in Seaside through the package Scriptaculous.

    All ready made images have the Scriptaculous package extensions already loaded. The latest version is available from http://www.squeaksource.com/Seaside. An online demo is available at http://scriptaculous.seasidehosting.st. Alternatively, if you have a enabled image running, simply go to http://localhost:8080/javascript/scriptaculous.

    The Scriptaculous extensions follow the same approach as Seaside itself — simply configure Pharo objects to model your application, and the needed Javascript code will be generated for you.

    Let us look at a simple example of how client-side Javascript support can make our RPN calculator behave more naturally. Currently every keystroke to enter a digit generates a request to refresh the page. We would like instead to handle editing of the display on the client-side by updating the display in the existing page.

    To address the display from JavaScript code, we must first give it a unique id.

    Update the calculator’s rendering method as follows. (If you have not implemented the tutorial example yourself, you can simply load the complete example (PBE-SeasideRPN) from http://www.squeaksource.com/PharoByExample and apply the suggested changes to the classes RPN* instead of My*.

    MyCalculator >> renderContentOn: html
        html div id: 'keypad'; with: keypad.
        html div id: 'display'; with: display.
    

    To be able to re-render the display when a keyboard button is pressed, the keyboard needs to know the display component.

    Add a display instance variable to MyKeypad, an initialize method MyKeypad>>setDisplay:, and call this from MyCalculator>>initialize. Now we are able to assign some JavaScript code to the buttons by updating MyKeypad>>renderStackButton:callback:colSpan:on: as follows:

    MyKeypad >> renderStackButton: text callback: aBlock colSpan: anInteger
            on: html
        html tableData
            class: 'key';
            colSpan: anInteger;
            with: [
                html anchor
                    callback: aBlock;
                    onClick:    "handle Javascript event"
                        (html scriptaculous updater
                            id: 'display';
                            callback: [ :r |
                                aBlock value.
                                r render: display ];
                            return: false);
                    with: [ html html: text ] ]
    

    onClick: specifies a JavaScript event handler. html updater returns an instance of PTUpdater, a Smalltalk object representing the JavaScript AJAX Updater object (http://www.prototypejs.org/api/ajax/updater). This object performs AJAX requests and updates a container’s contents based on the response text. id: tells the updater what HTML DOM element to update, in this case the contents of the div element with the id ’display’. callback: specifies a block that is triggered when the user presses the button. The block argument is a new renderer r, which we can use to render the display component. (Note: Even though HTML is still accessible, it is not valid anymore at the time this callback block is evaluated). Before rendering the display component we evaluate aBlock to perform the desired action.

    return: false tells the JavaScript engine to not trigger the original link callback, which would cause a full refresh. We could instead remove the original anchor callback:, but like this the calculator will still work even if JavaScript is disabled.

    Try the calculator again, and notice how a full page refresh is triggered every time you press a digit key. (The URL of the web page is updated at each keystroke.)

    Although we have implemented the client-side behavior, we have not yet activated it. Now we will enable the Javascript event handling.

    Click on the Configure link in the toolbar of the calculator.

    Configure the Libraries attribute under the General section. (You may need to enable the modification of this attribute, by first selecting Modify). From the list of available libraries, select PTDevelopmentLibrary and apply the changes.

    Instead of manually adding the library, you may also do it programmatically when you register the application:

    MyCalculator class >> initialize
        (WAAdmin register: self asApplicationAt: self applicationName)
            addLibrary: PTDevelopmentLibrary
    

    For this example the PTDevelopmentLibrary is sufficient, but for the full set of the scriptaculous extensions you need to add the SUDevelopmentLibrary, too.

    Try the revised application. Note that the feedback is much more natural. In particular, a new URL is not generated with each keystroke.

    Seaside AJAX processing diagram.
    Figure \(\PageIndex{1}\): Seaside AJAX processing (simplified).

    You may well ask, yes, but how does this work? Figure \(\PageIndex{1}\) shows how the RPN applications would both without and with AJAX. Basically AJAX short-circuits the rendering to only update the display component. Javascript is responsible both for triggering the request and updating the corresponding DOM element. Have a look at the generated source-code, especially the JavaScript code:

    new Ajax.Updater(
        'display',
        'http://localhost/seaside/RPN+Calculator',
        {'evalScripts': true,
            'parameters': ['UNDERSCOREs=zcdqfonqwbeYzkza',
                'UNDERSCOREk=jMORHtqr','9'].join('&')});
    return false
    

    For more advanced examples, have a further look at http://localhost:8080/javascript/scriptaculous.

    Hints

    In case of server side problems use the Debugger. In case of client side problems use FireFox (http://www.mozilla.com) with the JavaScript debugger FireBug (http://www.getfirebug.com/) plugin enabled.


    This page titled 14.8: A Quick Look at AJAX is shared under a CC BY-SA 3.0 license and was authored, remixed, and/or curated by via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.