info343/lectures/intro-to-ajax/index.shtml

<!--#include virtual="../s5/commontop.html" -->
      <title>Lecture 11: Intro to Ajax — INFO 343 Autumn 2012</title>
   </head>

   <body>
      <div class="layout">
         <div id="controls"><!-- DO NOT EDIT --></div>
         <div id="currentSlide"><!-- DO NOT EDIT --></div>
         <div id="header"></div>
         <div id="footer">
            <h1>INFO 343 Lecture 11</h1>
            <h2>Intro to Ajax</h2>
         </div>
      </div>

      <div class="presentation">
         <div class="slide">
            <h1>Intro to Ajax</h1>
            <h3>Lecture 11</h3>
            <!-- <h4>Reading: 10.1–10.2</h4> -->

            <p class="license">
               Copyright 2010–2012 Marty Stepp, Jessica Miller, and/or Morgan Doocy.
            </p>

            <div class="w3c">
               <a href="http://validator.w3.org/check/referer"><img src="../s5/images/w3c-xhtml11.png" alt="Valid XHTML 1.1" /></a>
               <a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="../s5/images/w3c-css.png" alt="Valid CSS!" /></a>
            </div>
         </div>
         
         
         
         <div class="slide">
            <h1>
               Synchronous web communication
               <span class="readingsection">(10.1)</span>
            </h1>

            <div class="centerfigure">
               <img src="images/figure_1_synchronous.png" alt="synchronous communication" style="width: 60%;" />
            </div>

            <ul>
               <li><span class="term">synchronous</span>: user must wait while new pages load
                  <ul>
                     <li>
                        the typical communication pattern used in web pages (click, wait, refresh)
                     </li>
                  </ul>
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1><a href="http://en.wikipedia.org/wiki/Web_application">Web applications</a> and Ajax</h1>

            <div class="rightfigure">
               <img src="images/ajax_bleach.gif" alt="Ajax bleach" />
            </div>

            <ul>
               <li>
                  <span class="term">web application</span>: a dynamic web site that mimics the feel of a desktop app
                  <ul>
                     <li>
                        presents a continuous user experience rather than disjoint pages
                     </li>
                     <li>
                        examples: 
                        <a href="http://mail.google.com/">Gmail</a>,
                        <a href="http://maps.google.com/">Google Maps</a>,
                        <a href="http://docs.google.com/">Google Docs and Spreadsheets</a>,
                        <a href="http://www.flickr.com/">Flickr</a>,
                        <a href="http://www.a9.com/">A9</a>
                     </li>
                  </ul>
               </li>

               <li>
                  <span class="term">Ajax</span>: Asynchronous JavaScript and XML
                  <ul>
                     <li>not a programming language; a particular way of using JavaScript</li>
                     <li>downloads data from a server in the background</li>
                     <li>allows dynamically updating a page without making the user wait</li>
                     <li>avoids the &quot;click-wait-refresh&quot; pattern</li>
                     <li>
                        example: <a href="http://suggest.google.com/">Google Suggest</a>
                     </li>
                  </ul>
               </li>
         </div>



         <div class="slide">
            <h1>Asynchronous web communication</h1>

            <div class="centerfigure">
               <img src="images/figure_2_asynchronous.png" alt="synchronous communication" style="width: 60%;" />
            </div>

            <ul>
               <li><span class="term">asynchronous</span>: user can keep interacting with page while data loads
                  <ul>
                     <li>
                        communication pattern made possible by Ajax
                     </li>
                  </ul>
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1><a href="http://www.w3schools.com/XML/xml_http.asp"><code>XMLHttpRequest</code></a> (and why we won't use it)</h1>

            <ul>
               <li>JavaScript includes an <code>XMLHttpRequest</code> object that can fetch files from a web server
                  <ul>
                     <li>supported in IE5+, Safari, Firefox, Opera, Chrome, etc. (with minor compatibilities)</li>
                  </ul>
               </li>
               <!--
               Internet Explorer uses an ActiveXObject, while other browsers uses the built-in JavaScript object called XMLHttpRequest.
               -->

               <li>it can do this <span class="term">asynchronously</span> (in the background, transparent to user)</li>
               <li>the contents of the fetched file can be put into current web page using the DOM</li>
               
               <li style="margin-top: 2em">sounds great!...</li>
               <li class="incremental">... but it is clunky to use, and has various browser incompatibilities</li>
               <li class="incremental">jQuery provides a better wrapper for Ajax, so we will use that instead</li>
            </ul>
         </div>



         <div class="slide">
            <h1>A typical Ajax request</h1>

            <div class="rightfigure">
               <img src="images/ajax_request.png" alt="request" style="width: 100%" />
            </div>

            <ol class="compressed">
               <li>user clicks, invoking an event handler</li>
               <li class="incremental">handler's code creates an <code>XMLHttpRequest</code> object</li>
               <li class="incremental"><code>XMLHttpRequest</code> object requests page from server</li>
               <li class="incremental">server retrieves appropriate data, sends it back</li>
               <li class="incremental"><code>XMLHttpRequest</code> fires an event when data arrives
                  <ul>
                     <li>this is often called a <span class="term">callback</span></li>
                     <li>you can attach a handler function to this event</li>
                  </ul>
               </li>
               <li class="incremental">your callback event handler processes the data and displays it</li>
            </ol>
         </div>



         <div class="slide">
            <h1>
               jQuery’s Ajax model
               <!-- <span class="readingsection">(10.2.4)</span> -->
            </h1>

            <pre class="syntaxtemplate js">
$.ajax(&quot;<var>url</var>&quot;, {
   <var>option</var> : <var>value</var>,
   <var>option</var> : <var>value</var>,
   <var>option</var> : <var>value</var>,
   ...
});
</pre>

            <ul>
               <li>construct a jQuery <code>jqXHR</code> object to request a page from a server using Ajax</li>
               
               <li>constructor accepts 2 parameters:
                  <ol>
                     <li>the <strong>URL</strong> to fetch, as a String,</li>
                     <li>
                        a set of <a class="popup" href="http://api.jquery.com/jQuery.ajax/"><strong>options</strong></a>, as an array of <var>key</var> : <var>value</var> pairs in <code>{}</code> braces
                        <span class="aside">(an anonymous JS object)</span>
                     </li>
                  </ol>
               </li>
               <li>hides icky details of the raw <code>XMLHttpRequest</code>; works well in all browsers</li>
            </ul>
         </div>
         
         
         <div class="slide">
            <h1>A basic Ajax request with <code>$.ajax()</code></h1>
<pre class="syntaxtemplate js">
$.ajax(&quot;<var>url</var>&quot;, {
   success: <var>callback</var>,
   error: <var>callback</var>
});
</pre>

<pre class="examplecode js">
$.ajax(<em>'widget.html'</em>, {
   success: <em>injectWidget</em>,
   error: <em>ajaxError</em>
});

function injectWidget(<em>data</em>) {
   $('#widget').html(<em>data</em>);
}
</pre>
            <ul>
               <li>Makes request to <samp>quote.php</samp>; server responds with data</li>
               <li>jQuery passes data to callback function specified by <code>success</code></li>
               <li>If there was an error, jQuery calls <code>error</code> function instead</li>
            </ul>
         </div>
         
         
         <div class="slide">
            <h1>jQuery’s Ajax options</h1>
            
            <table class="standard">
               <tr>
                  <th>option</th>
                  <th>description</th>
               </tr>

               <tr>
                  <td>
                     <code>type</code>
                  </td>
                  <td>
                     how to fetch the request from the server (default <code>&quot;get&quot;</code>)
                  </td>
               </tr>

               <tr>
                  <td>
                     <code>data</code>
                  </td>
                  <td>
                     query parameters to pass to the server, if any (as a string or object)
                  </td>
               </tr>

               <tr>
                  <td>
                     <code>async</code>
                  </td>
                  <td>
                     should request be sent asynchronously in the background? (default <code>true</code>)
                  </td>
               </tr>

               <tr>
                  <td colspan="2" style="font-size: smaller;">
                     others: <code>contentType</code>, <!-- <code>encoding</code>, -->
                     <code>headers</code>, <code>ifModified</code>, <code>timeout</code>
                  </td>
               </tr>
            </table>

            <pre class="syntaxtemplate js">
$.ajax(&quot;bar.txt&quot;, {
   <em>data: { name: "Ed Smith", age: 29 },</em>   <span class="comment">// "name=Ed+Smith&amp;age=29"</span>
   <var>...</var>
});
</pre>
         </div>



         <div class="slide">
            <h1>jQuery’s Ajax callback functions</h1>
            
            <table class="standard">
               <tr>
                  <th>event</th>
                  <th>description</th>
               </tr>

               <tr>
                  <td>
                     <code>success</code></strong>
                  </td>
                  <td>
                     request completed successfully
                  </td>
               </tr>
               
               <tr>
                  <td>
                     <code>error</code></strong>
                  </td>
                  <td>
                     request was unsuccessful or there was a syntax/security error
                  </td>
               </tr>
               
               <tr>
                  <td>
                     <code>complete</code></strong>
                  </td>
                  <td>
                     request completed, successfully or not
                  </td>
               </tr>
               
               <tr>
                  <td colspan="2" style="font-size: smaller;">
                     others: <code>beforeSend</code>, <!-- <code>complete</code>, -->
                     <code>statusCode</code> (for per-code callbacks)
                  </td>
               </tr>
            </table>

            <pre class="syntaxtemplate js">
$.ajax(&quot;http://www.example.com/foo.php&quot;, {
   data: { username: 'foobar', password: 'abcdef' },   <span class="comment">// "password=abcdef"</span>
   <em>success: loginSuccess</em>,
   <em>error: loginFailure</em>,
   <em>complete: dismissDialog</em> <span class="comment">// will be called in either case</span>
});
</pre>
         </div>



         <!-- <div class="slide">
            <h1>Basic jQuery Ajax template</h1>

            <pre class="syntaxtemplate js">
$.ajax(&quot;<var>url</var>&quot;, {
   success: <var>functionName</var>
});
...

function <var>functionName</var>(<em>data</em>) {
   <var>do something with <em>data</em></var>;
}
</pre>

            <ul>
               <li>attach a handler to the request's <code>onSuccess</code> event</li>
               <li>the handler takes an <a href="http://www.prototypejs.org/api/ajax/response">Ajax response object</a>, which we'll name <code>ajax</code>, as a parameter</li>
            </ul>
         </div> -->



         <!-- <div class="slide">
            <h1><a href="http://www.prototypejs.org/api/ajax/response">Ajax response</a> object's properties</h1>
            
            <table class="standard">
               <tr>
                  <th>property</th>
                  <th>description</th>
               </tr>

               <tr>
                  <td>
                     <code>status</code>
                  </td>
                  <td>
                     the request's HTTP error code (200 = OK, etc.)
                  </td>
               </tr>

               <tr>
                  <td>
                     <code>statusText</code>
                  </td>
                  <td>
                     HTTP error code text
                  </td>
               </tr>

               <tr>
                  <td>
                     <code>responseText</code>
                  </td>
                  <td>
                     the entire text of the fetched file, as a <code>String</code>
                  </td>
               </tr>

               <tr>
                  <td>
                     <code>responseXML</code>
                  </td>
                  <td>
                     the entire contents of the fetched file, as a DOM tree (seen later)
                  </td>
               </tr>
            </table>
            
            <pre class="examplecode js">
function handleRequest(ajax) {
   alert(<em>ajax.responseText</em>);
}
</pre>

            <ul>
               <li>most commonly used property is <code>responseText</code>, to access the fetched text content</li>
            </ul>
         </div> -->



         <div class="slide">
            <h1>
               <code>XMLHttpRequest</code> security restrictions
            </h1>

            <div class="centerfigure">
               <img src="images/ajax_security_error.png" alt="Ajax security error" />
            </div>

            <ul>
               <li>cannot be run from a web page stored on your hard drive</li>
               <li>can only be run on a web page stored on a web server</li>
               <li>can only fetch files from the same server that the page is on
                  <ul>
                     <li><code>http://www.foo.com/a/b/c.html</code> can only connect to <code>www.foo.com</code></li>
                  </ul>
               </li>
            </ul>
         </div>
         
         

         <div class="slide">
            <h1>Handling Ajax errors</h1>

<pre class="syntaxtemplate js" style="font-size: 60%; float: left; width: 60%">
$.ajax(&quot;<var>url</var>&quot;, {
   success: <var>functionName</var>,
   <em>error: ajaxError</em>,
});
...
<em>function ajaxError(jqxhr, type, error) {</em>
   var msg = "An Ajax error occurred!\n\n";
   if (type == 'error') {
      if (jqxhr.readyState == 0) {
         // Request was never made - security block?
         msg += "Looks like the browser security-blocked the request.";
      } else {
         // Probably an HTTP error.
         msg += 'Error code: ' + jqxhr.status + "\n" + 
                'Error text: ' + error + "\n" + 
                'Full content of response: \n\n' + jqxhr.responseText;
      }
   } else {
      msg += 'Error type: ' + type;
      if (error != "") {
         msg += "\nError text: " + error;
      }
   }
   alert(msg);
}</pre>

            <ul style="margin-left: 65%">
               <li>for user's (and developer's) benefit, show an error message if a request fails</li>
               <li>the above function is fairly robust; feel free to use it for your assignments</li>
            </ul>
         </div>



         <div class="slide">
            <h1>Debugging Ajax code</h1>

            <div class="centerfigure">
               <img src="images/firebug_ajax.png" alt="Firebug Ajax" style="max-width: 70%;" />
            </div>

            <ul>
               <li><strong>Net</strong> tab shows each request, its parameters, response, any errors</li>
               <li>expand a request with <span class="term" style="border: 1px solid black;">+</span> and look at <span class="term">Response</span> tab to see Ajax result</li>
            </ul>
         </div>



         <!-- <div class="slide">
            <h1>Creating a <code>POST</code> request</h1>
            
<pre class="syntaxtemplate js">
$.ajax(&quot;<var>url</var>&quot;, {
   <em>type: &quot;post&quot;,</em>   <span class="comment">// optional</span>
   <em>parameters: { <var>name</var>: <var>value</var>, <var>name</var>: <var>value</var>, ..., <var>name</var>: <var>value</var> },</em>
   onSuccess: <var>functionName</var>,
   onFailure: <var>functionName</var>,
   onException: <var>functionName</var>
});
</pre>

            <ul>
               <li><code>method</code> should be changed to <code>&quot;post&quot;</code> (or omitted; <code>post</code> is default)</li>
               <li>any query parameters should be passed as a <code>parameters</code> parameter
                  <ul>
                     <li>written between <code>{}</code> braces as a set of <var>name</var> : <var>value</var> pairs <span class="aside">(another anonymous object)</span></li>
                     <li><code>get</code> request parameters can also be passed this way, if you like</li>
                  </ul>
               </li>
            </ul>
         </div> -->



         <div class="slide">
            <h1>Ajax quick-loader: <code>.load()</code></h1>

<pre class="syntaxtemplate js">
<var>$obj</var>.load(&quot;<var>url</var>&quot;);
</pre>

<pre class="examplecode js">
$('#mission')<em>.load('content/mission_statement.html')</em>;
</pre>
            
            <hr/>
            
            <ul>
               <li><code>.load()</code></a> injects a file’s contents directly into an element (as <code>innerHTML</code>)</li>
               <li>Eliminates the callback function!</li>
               <!-- <li>additional (1st) parameter specifies the <code>id</code> of element to inject into</li> -->
               <!-- <li><code>success</code> handler not needed (but <code>onFailure</code>, <code>onException</code> handlers may still be useful)</li> -->
            </ul>
         </div>

         
         <!-- <div class="slide">
            <h1>PeriodicalUpdater</h1>

            <pre class="syntaxtemplate js">
new Ajax.PeriodicalUpdater(&quot;<var>id</var>&quot;, &quot;<var>url</var>&quot;,
   {
      frequency: <var>seconds</var>,
      <var>name</var>: <var>value</var>, ...
   }
);
</pre>

            <hr />

            <ul>
               <li><a href="http://www.prototypejs.org/api/ajax/periodicalupdater"><code>Ajax.PeriodicalUpdater</code></a> repeatedly fetches a file at a given interval and injects its content into an element as <code>innerHTML</code></li>
               <li><code>onSuccess</code> handler not needed (but <code>onFailure</code>, <code>onException</code> handlers may still be useful)</li>
            </ul>
         </div> -->



         <div class="slide">
            <h1><code>$.ajaxSetup()</code></h1>

<pre class="syntaxtemplate js">
$.ajaxSetup({
   complete: <var>functionName</var>,
   error: <var>functionName</var>,
   ...
});
</pre>

            <hr />

            <ul>
               <li>sets up default handlers for all Ajax requests</li>
               <li>useful for attaching error handler to all requests at once</li>
            </ul>
         </div>



         <div class="slide">
            <h1>Shorter requests: <code>$.ajaxSetup()</code> and <code>$.get()</code></h1>

<pre class="syntaxtemplate js">
$.get(<var>url</var>, <var>success function</var>);
</pre>

<pre class="examplecode js">
$.ajaxSetup({ <em>error: ajaxError</em> });

<em>$.get('foo.txt', function(data) {</em>
   <span class="comment">// do something with data</span>
});
</pre>
            
            <ul>
               <li>If you set up an error handler in advance, using the shorter <code>$.get()</code> syntax is more concise</li>
            </ul>
         </div>
         




<!--#include virtual="../s5/commonbottom.html" -->