<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
    >

<channel>
    <title>Webmonkey &#187; Ajax</title>
    <atom:link href="http://www.webmonkey.com/category/ajax/feed/" rel="self" type="application/rss+xml" />
    <link>http://www.webmonkey.com</link>
    <description>The Web Developer&#039;s Resource</description>
    <lastBuildDate>Mon, 06 May 2013 17:29:19 +0000</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <generator>http://wordpress.org/?v=3.4.2</generator>
    
    <item>
        <title>Beautify Broken Links With Catch404</title>
        <link>http://www.webmonkey.com/2010/07/beautify-broken-links-with-catch404/</link>
        <comments>http://www.webmonkey.com/2010/07/beautify-broken-links-with-catch404/#comments</comments>
        <pubDate>Wed, 21 Jul 2010 22:47:41 +0000</pubDate>

                <dc:creator>Michael Calore</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=48090</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[UI/UX]]></category>
		<category><![CDATA[404]]></category>
		<category><![CDATA[Catch404]]></category>
		<category><![CDATA[jQuery]]></category>
            <enclosure url="http://www.webmonkey.com/wp-content/uploads/2010/07/Catch404.jpg" type="image/jpeg" length="48000" />
                    <description><![CDATA[<div class="rss_thumbnail"><img src="http://www.webmonkey.com/wp-content/uploads/2010/07/Catch404.jpg" alt="Beautify Broken Links With Catch404" /></div>The 404 error is one of the bitter realities of the web. &#8220;The page you&#8217;ve requested does not exist.&#8221; So cold and unforgiving. Unlike a bad database connection or an unresponsive server, the 404 Page Not Found error has a finality to it &#8212; this link is dead and it&#8217;s never coming back. But now [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled -->
<p><a href="http://www.webmonkey.com/wp-content/uploads/2010/07/Catch404.jpg"><img src="http://www.webmonkey.com/wp-content/uploads/2010/07/Catch404.jpg" alt="" title="Catch404" /></a></p>
<p>The 404 error is one of the bitter realities of the web. </p>
<p>&#8220;The page you&#8217;ve requested does not exist.&#8221; So cold and unforgiving. Unlike a bad database connection or an unresponsive server, the 404 Page Not Found error has a finality to it &#8212; this link is dead and it&#8217;s never coming back.</p>
<p>But now we have <a href="http://addyosmani.com/blog/catch404/">Catch404</a> by Addy Osmani, a jQuery plug in that handles broken links with style. Deploy Catch404 on your site, and instead of seeing a page reporting a broken link, the user is presented with an Ajax modal window (also called a hop-up, or a lightbox) informing them the linked page isn&#8217;t there. The windows also offers some alternate destinations they might want to check out.</p>
<p>We&#8217;ve been trying to make 404s go down a little easier for years now. The <a href="http://www.plinko.net/404/area404.asp">custom 404 page</a> is a popular solution. It&#8217;s available on just about every web CMS out there. You can <a href="http://www.webmonkey.com/2010/02/create_custom_404_pages/">do it yourself</a>, too. Browsers are also taking it upon themselves to beautify the broken link with <a href="http://www.google.com/support/chrome/bin/answer.py?hl=en&#038;answer=95671">custom pages</a>, offering suggestions or inviting users to search for the page using a built-in search box.</p>
<p>Catch404 takes both of those ideas &#8212; the custom alert and the suggestions of what to do next &#8212; and places them into the user experience before the link is even loaded. The plugin, which requires the <a href="http://jquery.com/">jQuery framework</a>, sends the link off to Yahoo&#8217;s <a href="http://developer.yahoo.com/yql/">YQL engine</a> to check to make sure it&#8217;s alive. It only performs this check for external URLs; local URLs don&#8217;t require the check. The check is performed behind the scenes, using an Ajax request. If all is good, the user goes about his or her way. If the check results in a 404, the user sees the modal window.</p>
<p><a href="http://www.addyosmani.com/resources/catch404/catch404.html">Here&#8217;s a demo</a>.</p>
<p>You&#8217;ll notice one obvious downside, which is that your users will have to wait an extra half-second or so while the YQL call completes. So why use it? </p>
<p>When a user is browsing your site and clicks on a link you&#8217;ve provided, then sees a 404 error, it&#8217;s your problem whether you&#8217;re responsible or not. Linking to dead pages makes you look like a sloppy curator, and the user will place some, if not all, of the blame for that error on you. Catch404 is more helpful than an impersonal error.</p>
<p>If the speed hit from the cross-site link checking bothers you, consider adding Catch404 only to legacy content &#8212; those years-old pages filled with links that may or may not still be alive.</p>
<p>Activating Catch404 is simply a matter of assigning a class to the link, so you can invoke it only where it makes sense.</p>
<p>[via <a href="http://delicious.com/url/108e932c9bb78f60d8f2eff6090100e0">Delicious</a>]</p>
<p><b>See Also:</b></p>
<ul>
<li><a href="http://www.webmonkey.com/2010/02/get_started_with_jquery/">Get Started With JQuery</a></li>
<li><a href="http://www.webmonkey.com/2010/01/jquery_celebrates_4_years_on_the_web_with_jquery_1dot4/">JQuery Celebrates 4 Years on the Web With New Release</a></li>
<li><a href="http://www.webmonkey.com/2010/07/the-solar-system-rendered-in-css-and-html/">The Solar System, Rendered in CSS and HTML</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/07/beautify-broken-links-with-catch404/feed/</wfw:commentRss>
        <slash:comments>2</slash:comments>

        
    </item>
    
    <item>
        <title>Beautiful Websites: Slippy for Presentations</title>
        <link>http://www.webmonkey.com/2010/06/beautiful-websites-slippy-for-presentations/</link>
        <comments>http://www.webmonkey.com/2010/06/beautiful-websites-slippy-for-presentations/#comments</comments>
        <pubDate>Thu, 03 Jun 2010 19:47:44 +0000</pubDate>

                <dc:creator>Michael Calore</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=47588</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Apps]]></category>
		<category><![CDATA[beautiful websites]]></category>
		<category><![CDATA[jQuery]]></category>
            <enclosure url="http://www.webmonkey.com/wp-content/uploads/2010/06/slippy.jpg" type="image/jpeg" length="48000" />
                    <description><![CDATA[<div class="rss_thumbnail"><img src="http://www.webmonkey.com/wp-content/uploads/2010/06/slippy.jpg" alt="Beautiful Websites: Slippy for Presentations" /></div>Jordi Boggiano has created Slippy, a lightweight library for building animated, browser-based slideshow presentations. Slippy is very simple &#8212; check out a short demo and view the source code. Grab the code from github. It&#8217;s written in HTML and it uses JQuery for the interactions (touch the space bar, use the arrow keys, or click [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled --><a href="http://www.webmonkey.com/wp-content/uploads/2010/06/slippy.jpg"><img src="http://www.webmonkey.com/wp-content/uploads/2010/06/slippy.jpg" alt="" title="slippy" width="580" height="454" class="aligncenter size-full wp-image-47589" /></a></p>
<p>Jordi Boggiano has created <a href="http://seld.be/notes/introducing-slippy-html-presentations">Slippy</a>, a lightweight library for building animated, browser-based slideshow presentations. Slippy is very simple &#8212; check out a <a href="http://slides.seld.be/?file=2010-05-30+Example.html#1">short demo</a> and view the source code. Grab the code from <a href="http://github.com/Seldaek/slippy">github</a>.</p>
<p>It&#8217;s written in HTML and it uses <a href="http://jquery.com/">JQuery</a> for the interactions (touch the space bar, use the arrow keys, or click the mouse to go to the next slide). It also uses <a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter">Syntax Highlighter</a>, a bit of JavaScript that pretties up snippets of code &#8212; we use Syntax Highlighter for tutorials here on Webmonkey &#8212; so it&#8217;s especially useful for presentations where you&#8217;re showing code examples. Jordi points out that Slippy can run your scripts in pretty <code>alert()</code> boxes (rather than the standard, boring browser alerts) to show your examples in action.</p>
<p>Composing a presentation is simple. Just hack a basic HTML file. Each slide is in its own <code>&lt;div></code>, and all the markup beyond that is standard HTML. Bravo!</p>
<p><b>See Also:</b></p>
<ul>
<li><a href="http://www.webmonkey.com/2010/03/beautiful-websites-former-apple-designers-amazing-photo-gallery/">Beautiful Websites: Former Apple Designer&#8217;s Amazing Photo Gallery</a></li>
<li><a href="http://www.webmonkey.com/2010/02/get_started_with_jquery/">Get Started With JQuery</a></li>
<li><a href="http://www.webmonkey.com/2010/01/nyt_shows_off_real-time_tweet_tracker_during_stevenote/">NYT Shows Off Real-Time Tweet Tracker During Stevenote</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/06/beautiful-websites-slippy-for-presentations/feed/</wfw:commentRss>
        <slash:comments>8</slash:comments>

        
    </item>
    
    <item>
        <title>Ajax for Beginners</title>
        <link>http://www.webmonkey.com/2010/02/ajax_for_beginners/</link>
        <comments>http://www.webmonkey.com/2010/02/ajax_for_beginners/#comments</comments>
        <pubDate>Wed, 17 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=775</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[JavaScript has had the XMLHttpRequest object for almost a decade now, but it really only started getting wide attention in 2004. All this attention was mostly due to some showoff web applications that made every developer who saw them think, &#8220;I want my site to do that!&#8221; But it also has to do with the [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --></p><p>JavaScript has had the XMLHttpRequest object for almost a decade now, but it really only started getting wide attention in 2004. All this attention was mostly due to some showoff web applications that made every developer who saw them think, &#8220;I want my site to do that!&#8221; But it also has to do with the spiffy, spiffy name given to it by the folks at AdaptivePath, who named this asynchronized application <a href="http://www.adaptivepath.com/publications/essays/archives/000385.php" class="external text" title="http://www.adaptivepath.com/publications/essays/archives/000385.php" rel="nofollow">Ajax</a>. Maybe you&#8217;ve heard of it?

</p><p>A few high-profile Google applications in particular made a splash with Ajax: <a href="http://maps.google.com/" class="external text" title="http://maps.google.com/" rel="nofollow">Maps</a> and <a href="http://gmail.google.com/gmail" class="external text" title="http://gmail.google.com/gmail" rel="nofollow">Gmail</a> were first. It also powers some of the core functionality in the user interface of the ever-so-popular photo sharing site <a href="http://www.flickr.com" class="external text" title="http://www.flickr.com" rel="nofollow">Flickr</a>. By now, Ajax has become integral to the fabric of the web, especially in the era of real-time applications like <a href="http://www.twitter.com">Twitter</a>, <a href="http://www.google.com/buzz">Buzz</a> and <a href="http://www.google.com/wave">Wave</a> (all of which use Ajax extensively in their webapp front ends, for the record). Ajax may also lay claim to being the first JavaScript object with its own <a href="http://www.ajaxian.com/" class="external text" title="http://www.ajaxian.com/" rel="nofollow">fan website</a>. Date.com doesn&#8217;t count, although I did have a scintillating chat with a lady there once about the getTimeZoneoffset method.



</p><span id="more-775"></span><p><br />

</p>

<a name="What_is_Ajax.3F"></a><h3> <span class="mw-headline">What is Ajax?</span></h3>

<p>So what is this fancy object that everybody wants a piece of? In brief, it&#8217;s a solution to one of the big annoyances of web interfaces. Generally, the user inputs some data or makes a choice, and clicks a button that sends the data to the server. The server takes a look at the data and sends back a whole new web page, which is loaded into the browser. Reloading a page every time you want to do something is annoying, disjunctive and time-consuming for the user. XMLHttpRequest moves that browser-server interaction to behind the scenes, so the user can just keep on playing with the same page, even while elements on the page are talking to the server! Go take a look at <a href="http://www.google.com/webhp?complete=1" class="external text" title="http://www.google.com/webhp?complete=1" rel="nofollow">Google Suggest</a> if I&#8217;ve lost you &#8212; it&#8217;s a nice, eloquent example of this.

</p><p>JavaScript has always been able to sneakily trigger a server-side script without anything happening in the browser by using a few classic tricks. This one, for example:<tt>onSubmit='runascript = new Image(); runascript.src="<a href="http://www.wired.com/images/archiveyscript.php" class="external free" title="http://www.wired.com/images/archiveyscript.php" rel="nofollow">http://www.wired.com/images/archiveyscript.php</a>?" + this.value'</tt>. That sort of chicanery is good, maybe, for caching form data to a file on the server, but it doesn&#8217;t return any information to the JavaScript that calls it, so its usefulness is limited. Ajax, on the other hand, can get a full parcel of data back from the script it calls. Hence the &#8220;XML&#8221; part of the name  &#8211;  which really is just there for looks, kind of like the &#8220;Java&#8221; part of JavaScript, because the returned data can be plain text or whatever you like, if XML is overkill or just not your cup of tea.

</p><p>This opens up millions of exciting possibilities. Every form submission, every JavaScript event, and heaven knows what else, can now interact with server-side databases and processing power. Data retrieval, password authentication, image generation &#8211;  you name it, Ajax can trigger it.

</p>

<a name="Making_Your_Own"></a><h3> <span class="mw-headline">Making Your Own</span></h3>



<p>The potential of Ajax-enhanced web apps is limited only by your imagination &#8211;  and by browser support. Mozilla-based browsers can do it, and Safari, and newer versions of Explorer, and Opera 8 but not Opera 7. It&#8217;s best to incorporate a fallback way of doing things for users who aren&#8217;t as cutting edge as you&#8217;d like them to be. Also, Explorer does things somewhat differently (of course) from all the other browsers, so it&#8217;s necessary to fork the code to account for the irritating little 80-odd percent of the population who use IE.

</p><p>Let&#8217;s build a simple application that accepts input from the user, passes it to some PHP on the server that checks it against a database, and returns the result to the browser. It comes in three parts. First, we need an HTML form. This you&#8217;ve seen before:

</p><p><br />

</p>

 <pre class="brush: js">&lt;html&gt;

 &lt;head&gt;

 &lt;title&gt;Report&lt;/title&gt;

 &lt;script type='text/javascript' src='xhr.js'&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;form action="fallbackpage.php" method="post"&gt;



 &lt;p&gt;Welcome, student. Please enter your essay here:&lt;textarea name="essay" id="essay"&gt;

 &lt;/textarea&gt; &lt;input type="submit" name="submit" value="Submit" onClick="return

 grade(this.form.essay.value);"&gt;

 &lt;/p&gt;

 &lt;/form&gt;

 &lt;/body&gt;



 &lt;/html&gt;

</pre>

<p><br />

Note that, for users without support for our script (named xhr.js), the form will just submit to the fallback page at fallbackpage.php.

</p><p>Next comes the JavaScript. This is the exciting part, so we&#8217;ll take it slow.

</p>

 <pre class="brush: js"> function grade(essay) {

 </pre>

<p>First, we initialize the object. We have to do it two ways, for different browsers.

</p><p><br />

</p>

 <pre class="brush: js">    // Mozilla version

    if (window.XMLHttpRequest) {

        xhr = new XMLHttpRequest();

    }

    // IE version

    else if (window.ActiveXObject) {

        xhr = new ActiveXObject("Microsoft.XMLHTTP");

    }

 </pre>



<p>Then, we escape the user input to make it URL-safe:

</p>

 <pre class="brush: js">    essay=encodeURIComponent(essay);

 </pre>

<p>and use the <tt>open</tt> method of the object to open a connection to the PHP script:

</p>

 <pre class="brush: js">    xhr.open("POST","grade.php");

 </pre>

<p>The method requires two arguments:first, the HTTP method (GET or POST); second, the URL of the script.

</p><p>A quick HTTP header prepares the script for what it&#8217;s getting, and then the <tt>send</tt> method transmits the actual request:



</p>

 <pre class="brush: js"> xhr.setRequestHeader(

      'Content-Type',

      'application/x-www-form-urlencoded; charset=UTF-8'); xhr.send(essay); </pre>

<p>This last step isn&#8217;t necessary for GET requests, wherein all the data can be contained in the query string of the URL.

</p><p><br />

</p>

<a name="Getting_Results"></a><h3> <span class="mw-headline">Getting Results</span></h3>

<p>Now we&#8217;re ready to see if the HTTP request worked. The <tt>readyState</tt> property counts up from zero during the request, and shows 4 when the server page has loaded successfully.

</p>

 <pre class="brush: js"> xhr.onreadystatechange=function() {

      if (xhr.readyState==4) {

 </pre>



<p>If the request worked, then we can get the output of the server-side script by querying the <tt>responseText</tt> property, which contains a string. For more complex server script output, a <tt>responseXML</tt> property, which can hold a full document object of XML data, is also available.

</p>

 <pre class="brush: js">      grade = xhr.responseText;

      alert ("Nice essay. Your grade is " + grade);

    }

    return false;

 }

 </pre>

<p>Want to see all that in a pastable block? Here it is in a <a href="http://www.wired.com/wired/webmonkey/stuff/Ajax_for_Beginners_code1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/Ajax_for_Beginners_code1.html" rel="nofollow">separate file</a>.

</p><p>Finally, the third component is the PHP script, which lives on the server and waits patiently for the JavaScript to pass it some juicy data. This example uses PHP, but any language you like &#8212; Ruby, Perl, C, ASP &#8212; can do as well. The core of this example script is a natural-language function called <tt>grade_essay()</tt> that grades student essays from 1 to 100, but I will redact that part to conserve space.



</p>

 <pre class="brush: js"> &lt;?php

 function grade_essay($essay) {

      return strlen($essay);

 }

 $essay = urldecode(implode(file('php://input')));

 $grade = grade_essay($essay);

 echo $grade;

 ?&gt;



 </pre>

<p>The <tt>php://input</tt> grabs the POST data, which gets put into a string, decoded and passed to the ingenious grading algorithm. The algorithm returns a numeric grade. Lastly, we just output the grade with <tt>echo</tt>  &#8211;  ordinarily, this would display in the browser, but since the PHP script is running &#8220;behind the scenes,&#8221; the string output is simply returned to the JavaScript that called it. If you need structured data, an XML document would be output with an <tt>echo</tt> statement in just the same way, but the content-type of the output page must be set to <tt>text/xml</tt>.



</p><p>What the user sees is this:She types her essay into the text area in the browser, clicks Submit, and within instants an alert box pops up giving her a final grade on the essay. Invisibly, the essay has been sent to the server, read and evaluated by a team of PHP gnomes, and returned with a grade, without ever reloading the page. The user can modify her essay and resubmit it endlessly.

</p><p>And that&#8217;s the gist of the almost magical XMLHttpRequest object! The example is simple, but the uses of the object can be elaborately, multifariously clever. If you need further inspiration and edification, a burgeoning number of examples are dotted around the Web:

</p>

<ul><li> Ajax-powered start pages like <a href="http://www.google.com/ig" class="external text" title="http://www.google.com/ig" rel="nofollow">iGoogle</a>, <a href="http://www.pageflakes.com/" class="external text" title="http://www.pageflakes.com/" rel="nofollow">Pageflakes</a> and <a href="http://www.netvibes.com/" class="external text" title="http://www.netvibes.com/" rel="nofollow">Netvibes</a>

</li></ul>

<ul><li> Social news site <a href="http://digg.com" class="external text" title="http://digg.com" rel="nofollow">Digg</a>



</li></ul>

<ul><li> Movie rentals site <a href="http://www.netflix.com" class="external text" title="http://www.netflix.com" rel="nofollow">Netflix</a>

</li></ul>

<p><br />

But what data you send and receive with Ajax is up to you.

</p><p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/ajax_for_beginners/feed/</wfw:commentRss>
        <slash:comments>8</slash:comments>

        
    </item>
    
    <item>
        <title>Build Ajax Components With Spry</title>
        <link>http://www.webmonkey.com/2010/02/build_ajax_components_with_spry/</link>
        <comments>http://www.webmonkey.com/2010/02/build_ajax_components_with_spry/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=748</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Apparently, the pro-developer guiding principles of Macromedia continue to survive under the direction of Adobe. Ever since they acquired Macromedia, Adobe, the company that was previously all about PDFs and PSDs, has been releasing a healthy serving of web tools via Adobe Labs. The Adobe Labs site is quickly becoming a vital meeting place on [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Apparently, the pro-developer guiding principles of Macromedia continue to survive under the direction of Adobe. Ever since they acquired Macromedia, Adobe, the company that was previously all about PDFs and PSDs, has been releasing a healthy serving of web tools via <a href="http://labs.adobe.com/" class="external text" title="http://labs.adobe.com/" rel="nofollow">Adobe Labs</a>. The Adobe Labs site is quickly becoming a vital meeting place on the web where developers can share ideas and experiment with new technologies.

</p><p>Adobe&#8217;s Flash-meets-Ajax framework lets developers create dynamic interfaces and UI elements. Now they&#8217;ve unveiled a preview release of their new Ajax framework, <a href="http://labs.adobe.com/technologies/spry/" class="external text" title="http://labs.adobe.com/technologies/spry/" rel="nofollow">Spry</a>.

</p><p>In this article, I&#8217;ll walk you through making a very simple Spry application. I hesitate to even call it an application, because most of the heavy lifting is done in the framework itself. The code we&#8217;ll be writing will look an awful lot like HTML and CSS.
<br />
<span id="more-748"></span>
</p><p>Before we get to examples, let&#8217;s look at what Spry is and how it compares to the many <a href="http://ajaxpatterns.org/Ajax_Frameworks" class="external text" title="http://ajaxpatterns.org/Ajax_Frameworks" rel="nofollow">other Ajax frameworks</a> out there. If you&#8217;d like to know a little more about Ajax, read my article about <a href="/2010/02/Build_an_Ajax_Dropdown_Menu" title="Tutorial:Build an Ajax Dropdown Menu">how to build an Ajax dropdown menu</a>.



</p><p><b>What is Spry?</b>

</p><p>In Adobe&#8217;s own words, Spry is &#8220;a JavaScript library for web designers that provides functionality that allows designers to build pages that provide a richer experience for their users.&#8221; That doubles as a pretty good definition of Ajax, too. To provide a richer user experience, we retrieve fewer entire pages from the server. Instead, Spry and other Ajax frameworks let us insert just the content we need into the current web page. This eliminates full page refreshes and greatly increases browser responsiveness. Spry also offers event and transition effects.

</p><p>Since Spry is focused on designers and not programmers, it uses special tags inside the HTML. The code looks more like what designers and developers see than hard-core scripters. Web pages end up looking a lot like templates, with content holding places kept by special curly brackets like this: <code>{thingname}</code>. This is the same style used in server-side templating engines.

</p><p><b>What does Spry do differently?</b>

</p><p>Unlike Smarty and its ilk, Spry does not require a hefty programming language, special server software, or an over-paid coder. Instead, the framework reads in XML files with JavaScript. Its built-in functions can also dynamically load single items from the XML file and apply the same CSS already declared in your stylesheet.

</p><p>As I mentioned before, there are plenty of Ajax frameworks to choose from. Other popular choices include <a href="http://dojotoolkit.org/" class="external text" title="http://dojotoolkit.org/" rel="nofollow">Dojo</a>, <a href="http://prototype.conio.net/" class="external text" title="http://prototype.conio.net/" rel="nofollow">Prototype</a>, <a href="http://developer.yahoo.com/yui/" class="external text" title="http://developer.yahoo.com/yui/" rel="nofollow">Yahoo User Interface Library</a>, and <a href="http://code.google.com/webtoolkit/" class="external text" title="http://code.google.com/webtoolkit/" rel="nofollow">Google Web toolkit</a>. These other frameworks are more programming-centric. Spry stuffs most of the JavaScript away in a couple include files. At its very basic level, you only need one simple line of JavaScript to tell Spry which XML files to load.



</p><p>Your JavaScript knowledge can be next to nil and you can still use Spry. Plus, you won&#8217;t have to change the way you code up your pages. If you use Dreamweaver, then using Spry should be as easy as writing simple HTML. And if you&#8217;re a hand-coder, there&#8217;s no need to move to an editor.

</p><p><b>Drawbacks to Spry</b>

</p><p>Many quickly scolded Adobe for using custom attributes to fill in Spry pages with data. If you need pages to pass XHTML validators, Spry isn&#8217;t for you. Similarly, if accessibility is important, the pre-release version of Spry will cause all sorts of headaches. Both of these issues seem to be on Adobe&#8217;s radar. Keep in mind this is a very early release, so Adobe wants your feedback. I expect we&#8217;ll see many changes in later versions of Spry.

</p><p>Programmers might not like how much Spry does for them. With a few additions to normal HTML, Spry will not only load data from an XML file, but also respond to user clicks and hovers. This could be a little too &#8220;auto-magic&#8221; to someone who wants to control the technical aspects of a site. This drawback to super-coders will empower designers.

</p><p>Lastly, Adobe says Spry works with &#8220;all modern browsers.&#8221; You should be fine with IE6+, Mozilla-based browsers (such as Firefox) and Safari among others. If you&#8217;re looking to support older browsers like Netscape 4 or IE 5, you probably should forego all Ajax frameworks.

</p><p>Now, if Spry is for you, let&#8217;s look at a simple example. We&#8217;ll load in an XML file and react to user clicks. All without ever leaving a single web page.

</p>

<a name="Give_Spry_a_Try"></a><h4> <span class="mw-headline">Give Spry a Try</span></h4>

<p>As we&#8217;ve seen, Adobe&#8217;s pre-release of Spry provides an easy way for designers to dynamically load content onto a page from an XML file. All you have to do is include a couple JavaScript files and write one simple line of code to tell Spry where to find your XML. Then, a few custom attributes can be inserted into any HTML elements.

</p><p>For our example, I&#8217;ve altered one of Adobe&#8217;s samples: the <a href="http://labs.adobe.com/technologies/spry/demos/products/index.html" class="external text" title="http://labs.adobe.com/technologies/spry/demos/products/index.html" rel="nofollow">Spry Product Demo</a>. For our demo, we&#8217;ll use an XML feed of Webmonkey&#8217;s latest articles. See the <a href="http://www.wired.com/wired/webmonkey/stuff/spry_stuff/stories.xml" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/spry_stuff/stories.xml" rel="nofollow">raw feed</a>. And check out the <a href="http://www.wired.com/wired/webmonkey/stuff/spry_stuff/stories.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/spry_stuff/stories.html" rel="nofollow">working demo</a>.



</p><p>Click on a story name, and you&#8217;ll see its description appear on the right. Though there are only three stories, we could add as many as we want. Our code would still show all of the story names on the left and a description of the first (or the selected story) to the right.

</p><p>There are three important tasks that the code accomplishes:

</p>

<ol><li> Include the Spry code and choose a data source

</li><li> List the story names

</li><li> Show the description of the selected story

</li></ol>

<p>The fist step is to plug in Spry code and point to a data source:

</p>

<pre class="brush: js">&lt;script type="text/javascript" src="http://www.wired.com/images/archivepath.js"&gt;&lt;/script&gt;

 &lt;script type="text/javascript" src="http://www.wired.com/images/archivepryData.js"&gt;&lt;/script&gt;



 &lt;script type="text/javascript"&gt;

 &lt;!--

 var dsStories = new Spry.Data.XMLDataSet("stories.xml", "stories/story")

 --&gt;

&lt;/script&gt;

</pre>

<p>The Spry code is in the file <code>SpryData.js</code>. Before that, we also include <code>xpath.js</code> because Spry needs <a href="http://www.w3.org/1999/11/xslt-xpath-pr" class="external text" title="http://www.w3.org/1999/11/xslt-xpath-pr" rel="nofollow">XPath</a> to lookup specific items from our XML file. XPath is a simple way, used by other XML-related technologies like XSL, to retrieve data in a way that mimics Unix paths.



</p><p>The <code>Spry.Data.XMLDataSet</code> loads our data source. As an argument, the function receives an XML file and an XPath. The path we give it, <code>stories/story</code>, tells XPath to look at the root level (named <code>stories</code>) and find every <code>story</code> below it.

</p><p>This is all the JavaScript you need to write to get the functionality of the demo.

</p><p>Next, we list the story names:

</p>

<pre class="brush: js">&lt;div id="storylist"&gt;

 &lt;ul spryregion="dsStories" spryrepeatchildren="dsStories"&gt;



 &lt;li onclick="dsStories.setCurrentRow('{ds_RowID}');" spryhover="itemhover" spryselect="itemselected"&gt;{name}&lt;/li&gt;

 &lt;/ul&gt;

&lt;/div&gt;

</pre>

<p>Here, we have an unordered list within a single list item. In the attributes to the <code>ul</code> tag, we&#8217;ve identified the <code>spryregion</code> (set to the name of our DataSet, <code>dsStories</code>) and told Spry to repeat through that DataSet with <code>spryrepeatchildren="dsStories"</code>.



</p><p>Then, inside the list item, we set CSS classes for <code>spryhover</code> and <code>spryselect</code>. This allows us to use our normal stylesheet to determine how to show our list items when they are hovered over and selected. Also inside the list item, we set the <code>onclick event</code> (a standard JavaScript event) to set the current row. Spry will loop through and create a list item for each of the stories in our XML file. So, each <code>&lt;li&gt;</code> tag will have an onclick event that tells Spry which item we have selected.

</p><p>If you have Firefox, you can highlight our list of stories, right-click (Ctrl-click for the fellow Macheads with one-button mouses), and choose &#8220;View Selection Source.&#8221; This will show the code as it looks after Spry has created all the three list items. You&#8217;ll also notice that between the starting and ending <code>&lt;li&gt;</code> tag is a story name. This is created by the template code, <code>{name}</code>.



</p><p>Finally, we show the description of the selected story:

</p>

<pre class="brush: js">&lt;div id="storydescription" sprydetailregion="dsStories"&gt;

 &lt;b&gt;{name}&lt;/b&gt;



 {desc}



 &lt;a href="{storylink}"&gt;Read this article&lt;/a&gt;.

 &lt;/div&gt;



&lt;/div&gt;

</pre>

<p>This code simply shows the detail of the selected item. If nothing is selected, it shows the first item in the list. This logic is all determined by Spry, which is informed of the selected story from our onclick events.

</p><p>The rest of driven by the template code, which displays the <code>{name}</code>, <code>{desc}</code> (description), and <code>{storylink}</code> (the URL of the story).

</p><p>The biggest job that Spry does is grab the data from the XML file and place it on the page with limited direction from us. The CSS we loaded from a separate stylesheet determines how our page looks, including the connecting blue boxes.

</p><p>Adobe has limited the amount of JavaScript we have to write and, therefore, there is little programming crowding in on our HTML code. The juicy stuff goes on behind the scenes. Even the browser-specific code (for example, IE usually won&#8217;t listen to hover styles on non-links) is stuck away where we don&#8217;t have to worry about it.

</p><p>Of course, there is only so much that can be done with Spry in its current state, though Adobe has a pretty impressive <a href="http://labs.adobe.com/technologies/spry/demos/index.html" class="external text" title="http://labs.adobe.com/technologies/spry/demos/index.html" rel="nofollow">demo section</a>. Remember, this is a pre-release version of Spry. Expect Adobe to make significant improvements, such as the addition of user interface elements. This is similar to the way that the <a href="http://developer.yahoo.com/yui/" class="external text" title="http://developer.yahoo.com/yui/" rel="nofollow">Yahoo UI Library</a> blossomed.



</p><p>If you&#8217;re looking for a challenge, there are still a number of ways to improve upon the demo we created. Try adding a few more stories to the XML file and see them automatically incorporated into the stories list. Add more elements to each story (such as a date field or thumbnail image), or do something with the unused category element in our current XML feed.

</p><p>And if you&#8217;re feeling really spry, dig into the <a href="http://labs.adobe.com/technologies/spry/articles/data_set_overview.html" class="external text" title="http://labs.adobe.com/technologies/spry/articles/data_set_overview.html" rel="nofollow">DataSet documentation</a> to see what else you can do.

</p><p>Whatever you create with Spry, let us know!

</p><p><br />

</p><p><br />

<i>Did you love this article? Did you hate it? Think you can do better? Send us your <a href="mailto:webmonkey@wired.com?subject=spry" class="external text" title="mailto:webmonkey@wired.com?subject=spry" rel="nofollow">Feedback</a>. Feedback submitted here will be considered for publication on Webmonkey or Wired News, so if you don&#8217;t want us to print your comments, please say so in your email.</i>

</p><p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/build_ajax_components_with_spry/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Build an Ajax Dropdown Menu</title>
        <link>http://www.webmonkey.com/2010/02/build_an_ajax_dropdown_menu/</link>
        <comments>http://www.webmonkey.com/2010/02/build_an_ajax_dropdown_menu/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=754</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[If you hang out with designers and developers at all, then you&#8217;ve probably heard the term &#8220;Ajax&#8221; by now. It&#8217;s the official buzzword of Web 2.0. But it&#8217;s also an extremely useful web development technique. In the course of this tutorial, we&#8217;re going to look at what Ajax can do. Then we&#8217;ll use a JavaScript [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>If you hang out with designers and developers at all, then you&#8217;ve probably heard the term &#8220;Ajax&#8221; by now. It&#8217;s the official buzzword of Web 2.0. But it&#8217;s also an extremely useful web development technique.

</p><p>In the course of this tutorial, we&#8217;re going to look at what Ajax can do. Then we&#8217;ll use a JavaScript class to simplify your first steps toward the ultimate in speedy user interactivity.

</p><p>First, what is Ajax? It stands for <a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29" class="external text" title="http://en.wikipedia.org/wiki/Ajax_%28programming%29" rel="nofollow">Asynchronous JavaScript And XML</a>. In simple speak, Ajax allows us to use JavaScript to grab an XML file (or any other text) without reloading the whole web page.

</p><p>Ajax has been used for a lot of things, but it is most impressive when many small updates are needed in a short period. Think streaming stock quotes or draggable maps.

</p><span id="more-754"></span><p>In our example, we&#8217;ll use a pair of dropdown menu boxes (SELECT tags in HTML). A selection in the first box affects our list of choices in the second box. It&#8217;s not exactly cutting edge (Thau did <a href="/2010/02/JavaScript_Tutorial" title="Tutorial:JavaScript Tutorial"> something similar</a> using JavaScript), but it&#8217;s a proof of concept.



</p><p>Before we get started, here&#8217;s the stuff you&#8217;ll want in your toolbag:

</p><p>1. A love of extremely <a href="/2010/02/Make_an_HTML_Document" title="Tutorial:Make an HTML Document"> basic HTML</a>.

</p><p>2. Willingness to consult <a href="/2010/02/JavaScript_Tutorial" title="Tutorial:JavaScript Tutorial"> Thau&#8217;s Javascript Tutorial</a> if you get confused.

</p><p>3. &#8220;<a href="http://adamv.com/dev/javascript/http_request" class="external text" title="http://adamv.com/dev/javascript/http_request" rel="nofollow">Http</a>&#8220;, a caching XmlHttpRequest wrapper, which you can download to immediately make your life simpler. Plus, if you get into advanced Ajax programming, you may like the caching that is built into this Javascript class.

</p><p>But that&#8217;s the future. Let&#8217;s talk about now, alright? Ajax on three. One, two, three&#8230; Ajax!

</p><p>Before we do any JavaScript Ajax voodoo, let&#8217;s setup our HTML.

</p><p><br />

</p>



<pre class="brush: js">&lt;html&gt;

&lt;head&gt;

&lt;!--

	Javascript Ajax voodoo will go here

--&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;form name="frmSelect"&gt;

&lt;p&gt;

&lt;select name="country" onChange="handleOnChange(this);"&gt;

&lt;option&gt;Select country&lt;/option&gt;



&lt;option&gt;France&lt;/option&gt;

&lt;option&gt;Germany&lt;/option&gt;

&lt;option&gt;Spain&lt;/option&gt;

&lt;/select&gt;

&lt;/p&gt;&lt;p&gt;



&lt;select name="prez"&gt;

&lt;option&gt;Select head of government&lt;/option&gt;

&lt;/select&gt;

&lt;/p&gt;

&lt;/form&gt;

&lt;/body&gt;

&lt;/html&gt;

</pre>



<p>Here we have created an HTML form containing two dropdown menus. The dropdowns use the SELECT tag, which can contain several options.

</p><p>The first dropdown has four options: Select country, France, Germany, and Spain. Notice the onChange part of this dropdown:

</p><p><code>onChange="handleOnChange(this);" </code>

</p><p>This will become important later.

</p><p>The second dropdown has only one option: Select head of government.

</p><p>What we want to accomplish with our Ajax call is to get the three most recent heads of government for each country and load them into the second dropdown whenever the user changes the first dropdown.

</p><p>Sounds simple enough, but how are you on recent European presidents and chancellors? One great thing about Ajax is that we can grab content only when we need it. So, we&#8217;ll connect ourselves to some sort of feed that will give us the head of government for a particular country when we need it.

</p><p>For the purpose of this example, our feed will be plain text files stored in the same directory as our web page. So, copy the following lines to their own text files.

</p><p>France.txt:

</p><p><code>Valéry Giscard d'Estaing|François Mitterrand|Jacques Chirac</code>

</p><p>Germany.txt:

</p><p><code>|Helmut Kohl|Gerhard Schröder|Angela Merke</code>

</p><p>Spain.txt:

</p><p><code>|Felipe González Márquez|José María Aznar López|José Luis Rodríguez Zapatero</code>



</p><p>Notice how the lines contain names separated by vertical lines? Those lines are called &#8220;pipes,&#8221; and the pipe symbol has its own keystroke on your keyboard. Just hold Shift and look for the backslash (). So, the plan of attack is that whenever Germany is selected (for example), we&#8217;ll make an Ajax call to retrieve Germany.txt, get rid of those pipes, and put the names in the second dropdown box.

</p><p>Now that we&#8217;re ready for the Ajax voodoo, let&#8217;s get to the nitty gritty on the next page.

</p>

<a name="Packin.27_boxes"></a><h4> <span class="mw-headline">Packin&#8217; boxes</span></h4>

<p>If you haven&#8217;t downloaded request.js, the Ajax wrapper Javascript class, <a href="http://adamv.com/dev/javascript/http_request" class="external text" title="http://adamv.com/dev/javascript/http_request" rel="nofollow">grab it now</a> and put it in the same directory as the web page with the two dropdowns.

</p><p>Now, find this line in your document:

</p><p><code>&lt;!-- Javascript Ajax voodoo will go here --&gt; </code>

</p><p>And replace it with these lines:

</p><p><br />

</p>



<pre class="brush: js">&lt;script src="request.js"&gt;&lt;/script&gt;

&lt;script&gt;

function handleOnChange(dd1)

{

  var idx = dd1.selectedIndex;

  var val = dd1[idx].text;

  var par = document.forms["frmSelect"];

  var parelmts = par.elements;

  var prezsel = parelmts["prez"];

  var country = val;

  if (country&nbsp;!= "Select country")

  {

   var directory = ""+document.location;

   directory = directory.substr(0, directory.lastIndexOf('/'));



   Http.get({

		url: "./" +  country + ".txt",

		callback: fillPrez,

		cache: Http.Cache.Get

	}, [prezsel]);

  }

}

function fillPrez(xmlreply, prezelmt)

{

  if (xmlreply.status == Http.Status.OK)

  {

   var prezresponse = xmlreply.responseText;

   var prezar = prezresponse.split("|");

   prezelmt.length = 1;

   prezelmt.length = prezar.length;

   for (o=1; o &lt; prezar.length; o++)

   {

     prezelmt[o].text = prezar[o];

   }

  }

  else

  {

   alert("Cannot handle the Ajax call.");

  }

}

&lt;/script&gt;

</pre>

<p>Now that&#8217;s a big chunk of code.

</p><p>This line reads in the Ajax wrapper class that does the heavy lifting:

</p>

<pre class="brush: js">&lt;script src="http://www.wired.com/images/archiveequest.js"&gt;&lt;/script&gt;</pre>



<p>The <code>handleOnChange</code> function is called whenever the first dropdown is changed. Remember how I said that onChange stuff would be important?

</p><p>Lastly, the <code>fillPrez</code> function takes the output from the Ajax call and puts the names into the second dropdown.

</p><p>Let&#8217;s look through it a little closer.

</p><p>This sequence of Javascript looks through the first dropdown, finds which one is selected, and returns the country name into a variable named, appropriately, country:

</p>

<pre class="brush: js">var idx = dd1.selectedIndex;

var val = dd1[idx].text;

var par = document.forms["frmSelect"];

var parelmts = par.elements;

var prezsel = parelmts["prez"];

var country = val;

</pre>

<p>Then, if an actual country is selected, an Ajax call is made for the name of the country with .txt at the end. We supply our other function, <code>fillPrez</code>, to be the &#8220;callback&#8221; function. Whatever comes out of our Ajax call, we want it to go to <code>fillPrez</code>.



</p><p><br />

</p>

<pre class="brush: js">if (country&nbsp;!= "Select country")

  {

   var directory = ""+document.location;

   directory = directory.substr(0, directory.lastIndexOf('/'));



   Http.get({

		url: "./" +  country + ".txt",

		callback: fillPrez,

		cache: Http.Cache.Get

	}, [prezsel]);

}

</pre>

<p><br />

</p><p>We also pass along our second dropdown box, so that <code>fillPrez</code> will know which dropdown to fill.

</p><p>The first thing that happens in <code>fillPrez</code> is that we make sure that our Ajax call actually found the list of heads of government:

</p>

<pre class="brush: js">if (xmlreply.status == Http.Status.OK)</pre>



<p>If it didn&#8217;t, we let the user know there&#8217;s an error:

</p>

<pre class="brush: js">alert("Cannot handle the Ajax call.");</pre>

<p>If we&#8217;re good to go, then we grab the list of names and split it apart on those pipes:

</p><p><br />

</p>

<pre class="brush: js">var prezresponse = xmlreply.responseText;

var prezar = prezresponse.split("|");

</pre>

<p>We clear out the second dropdown, except for the first option (&#8220;Select head of government&#8221;):

</p><p><br />

</p>

<pre class="brush: js">prezelmt.length = 1;</pre>

<p><br />

Then we add each of the names into the dropdown:

</p><p><br />



</p>

<pre class="brush: js">prezelmt.length = prezar.length;

    for (o=1; o &lt; prezar.length; o++)

    {

      prezelmt[o].text = prezar[o];

}

</pre>

<p>You have now successfully created an Ajax call. Your Javascript code made a connection to your server, grabbed a text file, split apart the names in the file, and plopped the resulting data right into your dropdown box.

</p><p>See it in action and download the code <a href="http://duvinci.com/projects/ajax/dropdowns/" class="external text" title="http://duvinci.com/projects/ajax/dropdowns/" rel="nofollow">at my website</a>.

</p><p>There are a number of ways you could expand this code. A few examples:

</p><p>1. When someone chooses a head of government, you could redirect the user to the politician&#8217;s web page.

</p><p>2. You could show information about the head of government and their time in office. Extra points for using Ajax to grab the selected politician&#8217;s bio.

</p><p>3. You could also give up on the heads of government idea and instead fill the second dropdown with cities, states or provinces. Or maybe you could show fast food chain locations.

</p><p>You get the idea. There are a plethora of possibilities.

</p><p>Now, if you aren&#8217;t impressed since <a href="/2010/02/JavaScript_Tutorial" title="Tutorial:JavaScript Tutorial"> Thau did this in 1998</a> and he didn&#8217;t need no Ajax, remember this is a proof of concept. Rather than a text file, consider setting up a more dynamic feed using <a href="/2010/02/PHP_and_MySQL_Tutorial" title="Tutorial:PHP and MySQL Tutorial"> PHP and MySQL</a>.



</p><p>And if you really want to get more into the back end of providing data to Ajax calls, consider Paul&#8217;s article <a href="/2010/02/Building_With_Ajax_and_Rails" title="Tutorial:Building With Ajax and Rails"> Ajax It&#8217;s Good For What Rails You</a>.

</p><p><br />

</p><p><br />

<i>Did you love this article? Did you hate it? Think you can do better? Send us your <a href="mailto:webmonkey@wired.com?subject=nittygritty" class="external text" title="mailto:webmonkey@wired.com?subject=nittygritty" rel="nofollow">Feedback</a>. Feedback submitted here will be considered for publication on Webmonkey or Wired News, so if you don&#8217;t want us to print your comments, please say so in your email.</i>

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/build_an_ajax_dropdown_menu/feed/</wfw:commentRss>
        <slash:comments>6</slash:comments>

        
    </item>
    
    <item>
        <title>Building With Ajax and Rails</title>
        <link>http://www.webmonkey.com/2010/02/building_with_ajax_and_rails/</link>
        <comments>http://www.webmonkey.com/2010/02/building_with_ajax_and_rails/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=769</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[So, since the last time you brushed your teeth, Ruby on Rails has only grown in popularity. The list of web applications using the exciting new web framework has grown to such an enormous size, it has exceeded the 50K per page limit of the wiki used to host it. Lesser languages like Java and [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p><br />

So, since the last time you brushed your teeth, Ruby on Rails has only grown in popularity. The <a href="http://wiki.rubyonrails.com/rails/pages/RealWorldUsage" class="external text" title="http://wiki.rubyonrails.com/rails/pages/RealWorldUsage" rel="nofollow">list of web applications</a> using the exciting new web framework has grown to such an enormous size, it has exceeded the 50K per page limit of the wiki used to host it. Lesser languages like Java and PHP are copying the stylish efficiency of Rails with their own frameworks like <a href="https://trails.dev.java.net/" class="external text" title="https://trails.dev.java.net/" rel="nofollow">Trails</a>, <a href="http://phpontrax.com/" class="external text" title="http://phpontrax.com/" rel="nofollow">Trax</a> and <a href="https://trac.cakephp.org/" class="external text" title="https://trac.cakephp.org/" rel="nofollow">Cake</a>.

</p><p>In the tutorial <a href="/2010/02/Ruby_on_Rails_for_Beginners" title="Tutorial:Ruby on Rails for Beginners"> Ruby on Rails for Beginners</a>, we went over the very basic basics of Ruby and Rails:what it is, why it&#8217;s so mindblowingly cool, which celebrities are using it, and so forth. As soon as the article went live, letters flooded in, offering me book contracts, movie deals and exotic snacks &#8212; I haven&#8217;t gotten so much attention since my <a href="/2010/02/Ajax_for_Beginners" title="Tutorial:Ajax for Beginners"> Ajax for Beginners</a> article. In fact, <a href="http://www.lifehacker.com/software/poll/reader-poll-what-interests-geeks-116976.php" class="external text" title="http://www.lifehacker.com/software/poll/reader-poll-what-interests-geeks-116976.php" rel="nofollow">this poll</a> from the redoubtable Lifehacker.com says that Ruby on Rails and Ajax are among the two most popular things in the world, and plainly it pays to follow the trends, so what if we combined the two of them? No, that would be excessive. You don&#8217;t want to read about that. You do? Hmmmm, OK, I suppose we can take a quick look.



</p><span id="more-769"></span>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#You_Got_Ajax_In_My_Rails">You Got Ajax In My Rails</a></li>

<li><a href="#Adding_Prototype.js">Adding Prototype.js</a></li>



<li><a href="#Form_Of:A_Form.21">Form Of:A Form!</a></li>

<li><a href="#Moving_Onward">Moving Onward</a></li>

</ol>

</td></tr></tbody></table>



<p><br />

</p>

<a name="You_Got_Ajax_In_My_Rails"></a><h3> <span class="mw-headline">You Got Ajax In My Rails</span></h3>

<p>Let me just refresh my memory a little. Ajax (it seems like everyone&#8217;s calling it that now rather than my spiffy coinage, &#8220;XHR&#8221;) is the handy JavaScript technique that allows the browser to communicate with the server without reloading the current page, to do things like validate or save form input, refresh images and heaven knows what else.



</p><p>In the <a href="/2010/02/Ajax_for_Beginners" title="Tutorial:Ajax for Beginners"> Ajax for Beginners</a> article, we created those client-side dynamic functions by typing in a bunch of code by hand, but that goes against the make-it-quick-and-easy methodology of Rails. Instead, there are some pleasurably easy, automated ways to incorporate Ajax into a Rails-driven site. Rails ships with the <a href="http://prototype.conio.net/" class="external text" title="http://prototype.conio.net/" rel="nofollow">Prototype</a> JavaScript library, which provides a nice high-level toolkit for working with Ajax functions, and with <a href="http://script.aculo.us/" class="external text" title="http://script.aculo.us/" rel="nofollow">Script.aculo.us</a>, which builds additional bells and whistles onto Prototype. These two can be downloaded separately and used in non-Rails projects as well.

</p><p><br />

</p>

<a name="Adding_Prototype.js"></a><h3> <span class="mw-headline">Adding Prototype.js</span></h3>

<p>Let&#8217;s revisit the example site from the <a href="/2010/02/Ruby_on_Rails_for_Beginners" title="Tutorial:Ruby on Rails for Beginners"> Ruby on Rails for Beginners</a>  article. Maybe you&#8217;ve still got a copy of it lying around on your web server, or maybe you&#8217;d like to create it again from scratch. I&#8217;ll wait here.



</p><p>You&#8217;ll notice that the <tt>public/javascripts</tt> directory contains a file called &#8220;prototype.js&#8221; &#8212; that&#8217;s our friend Prototype! There isn&#8217;t much documentation for it, but if you read JavaScript fluently you can look at the file and see the basic methods it defines. In order to use the methods, first and foremost we need to activate them. That can be done one Ruby block at a time or for a whole page; let&#8217;s choose the latter. In the rHTML file that contains the page layout, namely <tt>app/views/layouts/bookmarks.rhtml</tt>, insert the line

</p>

<pre class="brush: js">&lt;%= javascript_include_tag&nbsp;:defaults&nbsp;%&gt;

</pre>

<p>right before the closing <tt>&nbsp;/head¢</tt> tag.

</p><p>Then we can get right down to creating our Ajax snazz. In our last session, we looked at HTTP links that used the Ruby function <tt>link_to()</tt>. Remember that? They looked like this (an example from <tt>app/views/bookmarks/list.rhtml</tt>):



</p>

<pre class="brush: js"> &lt;%= link_to 'Destroy', {:action =&gt; 'destroy',&nbsp;:id =&gt; bookmark},&nbsp;:confirm =&gt; "Are you sure?"&nbsp;%&gt;</pre>

<p>Well, <tt>link_to()</tt> has a buddy called <tt>link_to_remote()</tt>. It works in a similar fashion, except it takes an additional parameter, besides the name of the link and the action or URL it points to:a DOM element ID. The Ajax action will place any content it retrieves from the server into that element. So, if we wanted to rewrite our function above, so we could delete a bookmark from our list without reloading the whole page, we&#8217;d say:



</p>

<pre class="brush: js">&lt;%= link_to_remote 'Destroy', {:action =&gt; 'ajaxdestroy',&nbsp;:id =&gt; list,&nbsp;:update =&gt; 'bookmarks'},&nbsp;:confirm =&gt; "Are you sure?"&nbsp;%&gt;</pre>

<p>Notice the <tt>:update</tt> parameter &#8211; that&#8217;s the one that&#8217;s new. Now, when we click the Destroy link, it calls the <tt>ajaxdestroy</tt> action to delete the bookmark in question from the database, but instead of a page reload in the browser, the server will do the work behind the scenes and just return a new bookmark listing, which will be placed in the <tt>list</tt> DOM object. That DOM object corresponds to the list of bookmarks on the page. Now, that <tt>xhrdestroy</tt> action doesn&#8217;t exist yet. We have to create it, in <tt>app/controllers/bookmarks_controller.rb</tt>:



</p>

 <pre class="brush: js">

 def ajaxdestroy



  Bookmark.find(@params[:id]).destroy



  render&nbsp;:partial =&gt; "bookmarks"



 end



 </pre>

<p>The first line does the deleting:it looks at the @params array sent by the browser, which contains the ID of the bookmark to be deleted; finds the corresponding row in the database; and destroys it. Simple enough, I hope. The second line returns the response, using the very handy <a href="http://api.rubyonrails.com/classes/ActionController/Base.html#M000169" class="external text" title="http://api.rubyonrails.com/classes/ActionController/Base.html#M000169" rel="nofollow">render()</a> method. This method can be used to create and send a &#8220;partial,&#8221; or chunk of a web page, which it does here:the rendered list of bookmarks is returned and displayed without a full reload. It&#8217;d be wise to include fallback options for browsers that don&#8217;t support Ajax, but I leave that to you, my intelligent reader.

</p><p><br />

</p>

<a name="Form_Of:A_Form.21"></a><h3> <span class="mw-headline">Form Of:A Form!</span></h3>



<p>In our <a href="/2010/02/Ajax_for_Beginners" title="Tutorial:Ajax for Beginners"> Ajax for Beginners</a> lesson, we wrote a PHP/JavaScript function that would automatically grade essays and return the numeric grade in an alert window. To do the same with Rails, we&#8217;d use a method called <tt>form_remote_tag()</tt>, which submits a form to a server-side handler via XMLHTTPRequest. This is an Ajax version of the more familiar <tt>form_tag()</tt>.

</p>

 <pre class="brush: js">

 &lt;%= form_remote_tag(:url =&gt; {:action =&gt; 'grade'},&nbsp;:update



 =&gt; result)&nbsp;%&gt;



        Enter your essay here:



        &lt;%= text_area_tag "essay"&nbsp;%&gt;



        &lt;%= submit_tag "What's my grade?"&nbsp;%&gt;



        Result:



        &lt;%= text_field_tag "result"&nbsp;%&gt;



      &lt;%= end_form_tag&nbsp;%&gt;



 </pre>

<p>The user types their little essay into the text area created by <tt>text_area_tag</tt>. The form content is submitted to the controller action &#8220;grade,&#8221; which we will define in a minute. That action grades the essay and sends a numeric grade back to the form, which displays it in the &#8220;result&#8221; text field &#8212; all without reloading the page. (I know, it&#8217;s less and less thrilling every time I say that. Still a little cool though, right?) The grading action, which lives in the <tt>app/controllers</tt> directory, looks like this. Feel free to substitute your own more-rigorous, essay-grading algorithm:

</p>

 <pre class="brush: js">



 def grade



  puts params[:essay].strip.squeeze.split(/s/).size



 end



 </pre>

<p>OK, that &#8220;grading&#8221; function really just does a word count, using Ruby&#8217;s redoubtable string methods. I&#8217;ve used it to grade my students&#8217; papers though and it seems to work just fine.

</p><p><tt>puts</tt> is the Ruby equivalent of <tt>echo</tt> or <tt>print</tt>. Ruby, unlike some languages you may know, doesn&#8217;t need values to be explicitly returned from its methods. Instead, the final output of the method is automatically returned to the method&#8217;s caller. <tt>params</tt> is the array containing the entire submitted form, <tt>params[:essay]</tt> is the essay, <tt>strip</tt> removes leading and trailing white space, <tt>squeeze</tt> removes multiple repeating characters so double spaces aren&#8217;t counted twice, <tt>split</tt> breaks the string at every remaining space into an array, and <tt>size</tt> returns the number of elements in that array, i.e. the word count.



</p><p><br />

</p>

<a name="Moving_Onward"></a><h3> <span class="mw-headline">Moving Onward</span></h3>

<p>Those two methods give you plenty to work with, Ajax-on-Rails-wise (&#8220;Rajax&#8221;? Would that catch on, you think?) There are a dozen or so more, though, documented <a href="http://api.rubyonrails.com/classes/ActionView/Helpers/JavaScriptHelper.html" class="external text" title="http://api.rubyonrails.com/classes/ActionView/Helpers/JavaScriptHelper.html" rel="nofollow">here</a>. <tt>observe_field</tt> and <tt>observe_form</tt> create event handlers that make Ajax calls when a field changes. Very handy for autocompletion. <tt>draggable_element</tt> makes a DOM object draggable. It can then be dropped on an element specified with <tt>drop_receiving_element</tt>. For flashier stuff, you can check out some of the <a href="http://wiki.script.aculo.us/scriptaculous/show/Demos" class="external text" title="http://wiki.script.aculo.us/scriptaculous/show/Demos" rel="nofollow">demos</a> at script.aculo.us.



</p><p>Now that it&#8217;s so easy to create snazzy Ajaxy database-driven websites, the next step is for some of you to go out there and actually make <i>good</i> ones. I look forward to clicking your buttons and dragging your elements!

</p><p><br /><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/building_with_ajax_and_rails/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Ajax Essay Grader</title>
        <link>http://www.webmonkey.com/2010/02/ajax_essay_grader/</link>
        <comments>http://www.webmonkey.com/2010/02/ajax_essay_grader/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=436</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[This automatic essay grader is a simple example of an Ajax (XMLHttprequest) interaction from Paul Adams&#8217; Ajax for Beginners tutorial on Webmonkey. function grade(essay) { // Mozilla version if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } // IE version else if (window.ActiveXObject) { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } essay=encodeURIComponent(essay); xhr.open("POST","grade.php"); xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); xhr.send(essay); [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>This automatic essay grader is a simple example of an Ajax (XMLHttprequest) interaction from Paul Adams&#8217; <a href="/2010/02/Ajax_for_Beginners" title="Tutorial:Ajax for Beginners"> Ajax for Beginners</a> tutorial on Webmonkey.

</p><p><br />
<span id="more-436"></span>
</p>

<pre class="brush: js">function grade(essay) {



	// Mozilla version



	if (window.XMLHttpRequest) {



		xhr = new XMLHttpRequest();



	}



	// IE version



	else if (window.ActiveXObject) {



		xhr = new ActiveXObject("Microsoft.XMLHTTP");



	}



	essay=encodeURIComponent(essay);



	xhr.open("POST","grade.php");



	xhr.setRequestHeader(



		'Content-Type',



		'application/x-www-form-urlencoded; charset=UTF-8');



	xhr.send(essay);



	xhr.onreadystatechange=function() {



		if (xhr.readyState==4) {



			grade = xhr.responseText;



			alert ("Nice essay. Your grade is " + grade);



		}



	}



	return false;



}



</pre><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/ajax_essay_grader/feed/</wfw:commentRss>
        <slash:comments>4</slash:comments>

        
    </item>
    
    <item>
        <title>Ajax Drop-down Menu</title>
        <link>http://www.webmonkey.com/2010/02/ajax_drop-down_menu/</link>
        <comments>http://www.webmonkey.com/2010/02/ajax_drop-down_menu/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=439</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[This code, which was written by Adam Duvander, will create a simple Ajax drop-down menu. First, the JavaScript. Copy this code and save is as request.js /* XmlHttpRequest Wrapper Version 1.2.2 29 Jul 2005 adamv.com/dev/ */ var Http = { ReadyState: { Uninitialized: 0, Loading: 1, Loaded:2, Interactive:3, Complete: 4 }, Status: { OK: 200, [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>This code, which was written by Adam Duvander, will create a simple Ajax drop-down menu.</p>
<p><br />
<span id="more-439"></span>
</p><p>First, the JavaScript. Copy this code and save is as <code>request.js</code>

</p>

<pre class="brush: js">/*

	XmlHttpRequest Wrapper

	Version 1.2.2

	29 Jul 2005

	adamv.com/dev/

*/



var Http = {

	ReadyState: {

		Uninitialized: 0,

		Loading: 1,

		Loaded:2,

		Interactive:3,

		Complete: 4

	},



	Status: {

		OK: 200,



		Created: 201,

		Accepted: 202,

		NoContent: 204,



		BadRequest: 400,

		Forbidden: 403,

		NotFound: 404,

		Gone: 410,



		ServerError: 500

	},



	Cache: {

		Get: 1,

		GetCache: 2,

		GetNoCache: 3,

		FromCache: 4

	},



	Method: {Get: "GET", Post: "POST", Put: "PUT", Delete: "DELETE"},



	enabled: false,

	logging: false,

	_get: null,	// Reference to the XmlHttpRequest object

	_cache: new Object(),



	Init: function(){

		Http._get = Http._getXmlHttp()

		Http.enabled = (Http._get&nbsp;!= null)

		Http.logging = (window.Logging&nbsp;!= null);

	},



	_getXmlHttp: function(){

	/*@cc_on @*//*@if (@_jscript_version &gt;= 5)

		try { return new ActiveXObject("Msxml2.XMLHTTP"); }

		catch (e) {}

		try { return new ActiveXObject("Microsoft.XMLHTTP"); }

		catch (e) {}

	@end @*/

		try { return new XMLHttpRequest();}

		catch (e) {}



		return null;

	},



/*

	Params:

		url: The URL to request. Required.

		cache: Cache control. Defaults to Cache.Get.

		callback: onreadystatechange function, called when request is completed. Optional.

		method: HTTP method. Defaults to Method.Get.

*/

	get: function(params, callback_args){

		if (!Http.enabled) throw "Http: XmlHttpRequest not available.";



		var url = params.url;

		if (!url) throw "Http: A URL must be specified";



		var cache = params.cache || Http.Cache.Get;

		var method = params.method || Http.Method.Get;

		var callback = params.callback;



		if ((cache == Http.Cache.FromCache) || (cache == Http.Cache.GetCache))

		{

			var in_cache = Http.from_cache(url, callback, callback_args)



			if (Http.logging){

				Logging.log(["Http: URL in cache: " + in_cache]);

			}



			if (in_cache || (cache == Http.Cache.FromCache)) return in_cache;

		}



		if (cache == Http.Cache.GetNoCache)

		{

			var sep = (-1 &lt; url.indexOf("?"))&nbsp;? "&amp;"&nbsp;: "?"

			url = url + sep + "__=" + encodeURIComponent((new Date()).getTime());

		}



		// Only one request at a time, please

		if ((Http._get.readyState&nbsp;!= Http.ReadyState.Uninitialized) &amp;&amp;

			(Http._get.readyState&nbsp;!= Http.ReadyState.Complete)){

			this._get.abort();



			if (Http.logging){

				Logging.log(["Http: Aborted request in progress."]);

			}

		}



		Http._get.open(method, url, true);



		Http._get.onreadystatechange =  function() {

			if (Http._get.readyState&nbsp;!= Http.ReadyState.Complete) return;



			if (Http.logging){

				Logging.log(["Http: Returned, status: " + Http._get.status]);

			}



			if ((cache == Http.Cache.GetCache) &amp;&amp; (Http._get.status == Http.Status.OK)){

				Http._cache[url] = Http._get.responseText;

			}



			if (callback_args == null) callback_args = new Array();



			var cb_params = new Array();

			cb_params.push(Http._get);

			for(var i=0;i&lt;callback_args.length;i++)

				cb_params.push(callback_args[i]);



			callback.apply(null, cb_params);

		}



		if(Http.logging){

			Logging.log(["Http: StartedntURL: " + url + "ntMethod: " + method + "; Cache: " + Hash.keyName(Http.Cache,cache)])

		}



		Http._get.send(params.body || null);

	},



	from_cache: function(url, callback, callback_args){

		var result = Http._cache[url];



		if (result&nbsp;!= null) {

			var response = new Http.CachedResponse(result)



			var cb_params = new Array();

			cb_params.push(response);

			for(var i=0;i&lt;callback_args.length;i++)

				cb_params.push(callback_args[i]);



			callback.apply(null, cb_params);



			return true

		}

		else

			return false

	},



	clear_cache: function(){

		Http._cache = new Object();

	},



	is_cached: function(url){

		return Http._cache[url]!=null;

	},



	CachedResponse: function(response) {

		this.readyState = Http.ReadyState.Complete

		this.status = Http.Status.OK

		this.responseText = response

	}

}



Http.Init()



function json_response(response){

	var js = response.responseText;

	try{

		return eval(js);

	} catch(e){

		if (Http.logging){

			Logging.logError(["json_response: " + e]);

		}

		else{

			alert("Error: " + e + "n" + js);

		}

		return null;

	}

}



function getResponseProps(response, header){

	try {

		var s = response.getResponseHeader(header || 'X-Ajax-Props');

		if (s==null || s=="")

			return new Object()

		else

			return eval("o="+s)

	} catch (e) { return new Object() }

}



</pre>

<p><br />

Next, save each of these three bits of text as their own <code>txt</code> files.

</p><p>Save this one as France.txt

</p>

<pre class="brush: js">|Valery Giscard d'Estaing|Francois Mitterrand|Jacques Chirac

</pre>

<p><br />

Save this one as Germany.txt

</p>

<pre class="brush: js">|Helmut Kohl|Gerhard Schroder|Angela Merke

</pre>

<p><br />

And save this one as Spain.txt



</p>

<pre class="brush: js">|Felipe Gonzalez Marquez|Jose Maria Aznar Lopez|Jose Luis Rodriguez Zapatero

</pre>

<p><br />

Finally, the HTML to tie it all together. Copy and paste this code and save it as an HTML document, then place all five files into the same directory and run the HTML file in your browser to see it work.

</p>

<pre class="brush: js">&lt;html&gt;

&lt;head&gt;

&lt;script src="request.js"&gt;&lt;/script&gt;

&lt;script&gt;

function handleOnChange(dd1)

{

  var idx = dd1.selectedIndex;

  var val = dd1[idx].text;

  var par = document.forms["frmSelect"];

  var parelmts = par.elements;

  var prezsel = parelmts["prez"];

  var country = val;

  if (country&nbsp;!= "Select country")

  {

 	Http.get({

		url: "./" +  country + ".txt",

		callback: fillPrez,

		cache: Http.Cache.Get

	}, [prezsel]);

  }

}



function fillPrez(xmlreply, prezelmt)

{

  if (xmlreply.status == Http.Status.OK)

  {

    var prezresponse = xmlreply.responseText;

    var prezar = prezresponse.split("|");

    prezelmt.length = 1;

    prezelmt.length = prezar.length;

    for (o=1; o &lt; prezar.length; o++)

    {

      prezelmt[o].text = prezar[o];

    }

  }

  else

  {

    alert("Cannot handle the AJAX call.");

  }

}



&lt;/script&gt;

&lt;/head&gt;

&lt;body&gt;



&lt;form name="frmSelect"&gt;

&lt;p&gt;

&lt;select name="country" onChange="handleOnChange(this);"&gt;

&lt;option&gt;Select country&lt;/option&gt;



&lt;option&gt;France&lt;/option&gt;

&lt;option&gt;Germany&lt;/option&gt;

&lt;option&gt;Spain&lt;/option&gt;

&lt;/select&gt;

&lt;/p&gt;&lt;p&gt;



&lt;select name="prez"&gt;

&lt;option&gt;Select head of government&lt;/option&gt;

&lt;/select&gt;

&lt;/p&gt;

&lt;/form&gt;



&lt;/body&gt;

&lt;/html&gt;



</pre><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/ajax_drop-down_menu/feed/</wfw:commentRss>
        <slash:comments>3</slash:comments>

        
    </item>
    
    <item>
        <title>Google Ajax Search</title>
        <link>http://www.webmonkey.com/2010/02/google_ajax_search/</link>
        <comments>http://www.webmonkey.com/2010/02/google_ajax_search/#comments</comments>
        <pubDate>Mon, 15 Feb 2010 20:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=443</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Here is some code you can use to add Google&#8217;s search functionality to your website. You can add both a standard Google search box that will search the web at large (the first example) or a site-specific search box that will search only pages within a specific URL (the second example). If you want to [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Here is some code you can use to add Google&#8217;s search functionality to your website. You can add both a standard Google search box that will search the web at large (the first example) or a site-specific search box that will search only pages within a specific URL (the second example). If you want to restrict searches to your own site, use the second example and provide your site&#8217;s URL as the searchable domain.
<br />
<span id="more-443"></span>
</p><p>You&#8217;ll need an API key from Google. They are freely available for non-commercial applications.

</p><p><br />

General Google Search:

</p>

<pre class="brush: js">&lt;!DOCTYPE html&gt;

&lt;head&gt;

&lt;meta charset="utf-8" /&gt;



		&lt;title&gt;My GAjax Search&lt;/title&gt;

		&lt;script src="http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key=YOURKEYHERE" type="text/javascript"&gt;&lt;/script&gt;



		&lt;script language="Javascript" type="text/javascript"&gt;

    	//&lt;![CDATA[



    	function OnLoad() {

      	// Create a search control

      	var searchControl = new GSearchControl();



      	// create a search object

      	searchControl.addSearcher(new GwebSearch());

      	// tell Google where to draw the searchbox

      	searchControl.draw(document.getElementById("search-box"));



    	}

    	GSearch.setOnLoadCallback(OnLoad);



    	//]]&gt;



		&lt;/script&gt;

	&lt;/head&gt;

&lt;body&gt;



		&lt;!-- Search box --&gt;



		&lt;div id="search-box"&gt;



		&lt;/div&gt;



&lt;/body&gt;

&lt;/html&gt;

</pre>

<p><br />

Site Specific Google Search:

</p>

<pre class="brush: js">

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;

&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;



	&lt;head&gt;

		&lt;title&gt;My GAjax Site Search&lt;/title&gt;

		&lt;script src="http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key=YOURKEYHERE" type="text/javascript"&gt;&lt;/script&gt;







		&lt;script language="Javascript" type="text/javascript"&gt;

    	//&lt;![CDATA[



    	function OnLoad() {

      	// Create a search control

      	var searchControl = new GSearchControl();



     	// create a search object

      	var siteSearch = new GwebSearch();

	  	siteSearch.setUserDefinedLabel("YourSite");

	  	siteSearch.setUserDefinedClassSuffix("siteSearch");

	  	siteSearch.setSiteRestriction("example.com");

	  	searchControl.addSearcher(siteSearch);

      	// tell Google where to draw the searchbox

      	searchControl.draw(document.getElementById("search-box"));



    	}

    	GSearch.setOnLoadCallback(OnLoad);



    	//]]&gt;

		&lt;/script&gt;

	&lt;/head&gt;

	&lt;body&gt;



		&lt;!-- Search box --&gt;



		&lt;div id="search-box"&gt;



		&lt;/div&gt;



	&lt;/body&gt;

&lt;/html&gt;



</pre><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/google_ajax_search/feed/</wfw:commentRss>
        <slash:comments>3</slash:comments>

        
    </item>
    
    <item>
        <title>JQuery Celebrates 4 Years on the Web With New Release</title>
        <link>http://www.webmonkey.com/2010/01/jquery_celebrates_4_years_on_the_web_with_jquery_1dot4/</link>
        <comments>http://www.webmonkey.com/2010/01/jquery_celebrates_4_years_on_the_web_with_jquery_1dot4/#comments</comments>
        <pubDate>Tue, 19 Jan 2010 11:46:26 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/blog/jquerycelebrates4yearsonthewebwithnewrelease</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
        <description><![CDATA[Popular Ajax library jQuery is celebrating its fourth birthday with a major new release &#8212; JQuery 1.4. JQuery has long had a devoted following among interface designers. Proponents tout its speed and lightweight structure which make it easy to integrate complex effects with only a few lines of code. Google, Microsoft, Amazon and independent web [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled --><img class="blogimg" src="http://www.wired.com/images_blogs/epicenter/2010/01/jquery.jpg" />Popular Ajax library <a href="http://jquery.com/">jQuery</a> is celebrating its fourth birthday with a major new release &#8212; JQuery 1.4.</p>
<p>JQuery has long had a devoted following among interface designers. Proponents tout its speed and lightweight structure which make it easy to integrate complex effects with only a few lines of code. Google, Microsoft, Amazon and independent web developers everywhere have turned to jQuery to handle Ajax, JavaScript animations and other hallmarks of the modern web.</p>
<p>The latest version of jQuery boasts some impressive speed gains and represents a ground up refactoring of much of jQuery&#8217;s underlying code. According the jQuery&#8217;s developers this release is significantly faster across browsers and eliminates much of the redundancy in jQuery&#8217;s internal functions.</p>
<p>Other nice changes in this release include support for HTML5 elements in serialization calls, the ability to test for specific rendering engines (for example, target WebKit with <code>jQuery.browser.webkit</code>) and support for per-property easing in your animations.</p>
<p>For full details on everything that&#8217;s new, check out the <a href="http://jquery14.com/day-01/jquery-14">jQuery blog post</a> and be sure to look over the <a href="http://jquery14.com/day-01/jquery-14#backwards">backwards-incompatible changes</a> before you attempt to upgrade any of your jQuery projects.</p>
<p>As always you can grab both the <a href="http://jquery.com/">minified and full source versions of jQuery</a> from the download page or simply include the Google hosted version in your projects by including the URL, <a href="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js">http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js</a>, in your projects.</p>
<p><strong>See Also:</strong></p>
<ul>
<li><a href="http://www.webmonkey.com/blog/Microsoft_Gets_a_Clue__Adopts_jQuery">Microsoft Gets a Clue, Adopts jQuery</a></li>
<li><a href="http://www.webmonkey.com/blog/Have_a_jQuery_Halloween">Have a jQuery Halloween</a></li>
<li><a href="http://www.webmonkey.com/blog/Drag_And_Drop_Your_Tables_Like_Netflix">Drag And Drop Your Tables Like Netflix</a></li>
<li><a href="http://www.webmonkey.com/blog/jQuery_Javascript_Library_Turns_One">jQuery Javascript Library Turns One</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>
]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/01/jquery_celebrates_4_years_on_the_web_with_jquery_1dot4/feed/</wfw:commentRss>
        <slash:comments>6</slash:comments>

        
    </item>
    </channel>
</rss>
