<?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/tag/ajax/feed/" rel="self" type="application/rss+xml" />
    <link>http://www.webmonkey.com</link>
    <description>The Web Developer&#039;s Resource</description>
    <lastBuildDate>Fri, 05 Apr 2013 20:20:46 +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>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>Get Local Search Results From Yahoo</title>
        <link>http://www.webmonkey.com/2010/02/get_local_search_results_with_yahoo_maps_api/</link>
        <comments>http://www.webmonkey.com/2010/02/get_local_search_results_with_yahoo_maps_api/#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=907</guid>
        		<category><![CDATA[APIs]]></category>
		<category><![CDATA[Location]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
		<category><![CDATA[Yahoo]]></category>
        <description><![CDATA[Online maps are a popular way to spice up a site. To get the most use out of them, you need data to plot: addresses from a database, location clicks from the user or at least coordinates for the map&#8217;s center. With any map, you have to start somewhere. If you&#8217;re low on data, you [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Online maps are a popular way to spice up a site. To get the most use out of them, you need data to plot: addresses from a database, location clicks from the user or at least coordinates for the map&#8217;s center. With any map, you have to start somewhere.

</p><p>If you&#8217;re low on data, you can fill in the map with local listings, such as those you&#8217;d find in the Yellow Pages. You can show coffee shops or pizza joints right along your other data, or even on its own.

</p><p>In this tutorial I&#8217;ll show how to use Yahoo Local to search for nearby businesses and landmarks, then plot those locations on a Yahoo Map using the Ajax API.

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

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

<ol>



<li><a href="#What_You_Need">What You Need</a></li>

<li><a href="#Start_With_a_Basic_Map">Start With a Basic Map</a>

<ol>

<li><a href="#Add_Your_App_ID">Add Your App ID</a></li>

</ol>

</li>

<li><a href="#Find_Nearby_Burritos">Find Nearby Burritos</a>



<ol>

<li><a href="#Performing_the_Search">Performing the Search</a></li>

<li><a href="#Placing_the_Markers">Placing the Markers</a></li>

</ol>

</li>

<li><a href="#Accept_User_Input">Accept User Input</a>

<ol>

<li><a href="#Calling_Out_The_Callbacks">Calling Out The Callbacks</a></li>



</ol>

</li>

<li><a href="#Where_to_go_From_Here">Where to go From Here</a>

<ol>

<li><a href="#Mashup_Direction">Mashup Direction</a></li>

<li><a href="#Academic_Direction">Academic Direction</a></li>

<li><a href="#Location_Direction">Location Direction</a></li>



</ol>

</li>

</ol>

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

<a name="What_You_Need"></a><h2> <span class="mw-headline">What You Need</span></h2>

<ul><li> Knowledge of JavaScript, CSS and HTML

</li><li> A Yahoo account and <a href="http://developer.yahoo.com/wsregapp/" class="external text" title="http://developer.yahoo.com/wsregapp/" rel="nofollow">Yahoo Application ID</a>. Yahoo will ask for some information from you, but the good news is you get an ID right away.

</li><li> A little familiarity with Yahoo Maps

</li></ul>



<a name="Start_With_a_Basic_Map"></a><h2> <span class="mw-headline">Start With a Basic Map</span></h2>

<p>As a starting place for getting Yahoo Local data into your map, we&#8217;ll use a basic map from Webmonkey&#8217;s <a href="/2010/02/Get_Started_With_the_Yahoo_Maps_API/" class="external text" title="/2010/02/Get_Started_With_the_Yahoo_Maps_API/" rel="nofollow">introduction to Yahoo Maps</a>. Add this code to a new HTML file:

</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 Yahoo Map&lt;/title&gt;



		&lt;script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.8&amp;appid=appidhere"&gt;&lt;/script&gt;

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

		function initialize_ymap()

		{

			// Create a map object

			var map = new YMap(document.getElementById('ymap'));

			// Display the map centered on a geocoded location

			map.drawZoomAndCenter("San Francisco", 6);

		}

		&lt;/script&gt;

		&lt;style&gt;

		div#ymap {

			width: 500px;

			height: 300px;

		}

		&lt;/style&gt;



	&lt;/head&gt;

	&lt;body onload="initialize_ymap()"&gt;

		&lt;h1&gt;My Yahoo Map&lt;/h1&gt;

		&lt;div id="ymap"&gt;&lt;/div&gt;

	&lt;/body&gt;



&lt;/html&gt;

</pre>

<p><br />

</p>

<a name="Add_Your_App_ID"></a><h3> <span class="mw-headline">Add Your App ID</span></h3>

<p>Before you continue to the next section, you need to add your Yahoo Application ID. Find this call to api.maps.yahoo.com and replace <code>appidhere</code> with your own Application ID:

</p>

<pre class="brush: js">&lt;script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.8&amp;appid=appidhere"&gt;&lt;/script&gt;



</pre>

<p><br />

Once you make the change, save the file. Load it in your browser and you should see a map of San Francisco, like this:

</p><p><iframe src="http://www.wired.com/wired/archive/webmonkey/Yahoolocal/basic.html" name="Page1" align="middle" frameborder="0" height="400" scrolling="no" width="600"></iframe>

</p><p><br />

</p>

<a name="Find_Nearby_Burritos"></a><h2> <span class="mw-headline">Find Nearby Burritos</span></h2>

<p>Now that your map is loading, it&#8217;s time to fill it with local goodness. Do you know something else filled with goodness? Burritos. Because I believe in beating bad analogies to death, in this section I&#8217;ll show how you can take your blank map tortilla, add some data cheese, then finish off with rice and beans in the form of markers on the map.

</p><p>Okay, in plain English: I&#8217;ll be showing you how to search Yahoo Local, in this case for &#8220;burritos,&#8221; and plotting the results on our Yahoo Map. Here&#8217;s the finished product I&#8217;ll show you how to create:

</p><p><iframe src="http://www.wired.com/wired/archive/webmonkey/Yahoolocal/staticsearch.html" name="Page1" align="middle" frameborder="0" height="400" scrolling="no" width="600"></iframe>

</p><p><br />

We&#8217;ll start with the blank map of San Francisco from the previous section. The first thing we need to do is add a button, which will be used to activate the local search. Place this HTML below the &#8220;ymap&#8221; div:

</p>



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

		&lt;input type="submit" value="Search for burritos" onclick="javascript:doLocalSearch('burritos'); return false;" /&gt;

	&lt;/form&gt;

</pre>

<p>Notice that we have a form with a single submit button. When the button is clicked, it calls a JavaScript function <b>doLocalSearch</b> and passes the string &#8216;burritos&#8217; to it. We&#8217;ll need to make that function next.

</p><p>First a note about the <code>return false</code> line that comes at the end of the bit of JavaScript inside the submit button. That tells the browser not to actually submit the form to the server. JavaScript works in the browser without submitting a form.



</p>

<a name="Performing_the_Search"></a><h3> <span class="mw-headline">Performing the Search</span></h3>

<p>Now that we can call the search with the form button, we need to write the code for the search. Add this function just above the &lt;/script&gt; tag near the top of your document:

</p>

<pre class="brush: js">		function doLocalSearch(keyword)

		{

			map.searchLocal(map.getCenterLatLon(), keyword, 1, 5);

			YEvent.Capture(map, EventsList.onEndLocalSearch, addMarkers);

		}

</pre>

<p>There are two parts to this new function. The first passes four things off to Yahoo&#8217;s searchLocal function:

</p>

<ol><li> The center of our map (a YGeoPoint object)

</li><li> The keyword we&#8217;re searching for, burritos



</li><li> The radius of search results, in miles

</li><li> The number of search results, 1-20.

</li></ol>

<p>Since the search uses Ajax, the results are asynchronous. Unlike many functions that return results immediately, there is a delay for local search. It&#8217;s sort of like placing an order at a restaurant. Say you want a burrito, so you let the cashier know. Unless you&#8217;re at the airport, you don&#8217;t get your burrito right away. Instead, you have to wait for your order to come up. Sometimes you&#8217;re even given a number, so you&#8217;ll know immediately that your food is ready.

</p><p>The second line of our new function is where we tell the browser that we care about doing something with the results as soon as they come back. This is often referred to as a callback function. In Yahoo Maps, we enlist the callback function by &#8220;capturing&#8221; an event with the <b>YEvent.Capture</b> function. In this case, we told the browser to send the results of the search to the addMarkers function.

</p>

<a name="Placing_the_Markers"></a><h3> <span class="mw-headline">Placing the Markers</span></h3>

<p>The results of our local search are being sent to the <b>addMarkers</b> function, so we need to create that function. Add this just above the &lt;/script&gt; tag near the top of your document (just below the closing curly brace from the previous function):



</p>

<pre class="brush: js">		function addMarkers(result)

		{

			if (result.Data)

			{

				var places = result.Data.ITEMS;

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

				{

					var thisplace = places[i];

					var marker = new YMarker(new YGeoPoint(thisplace.LATITUDE, thisplace.LONGITUDE));

					marker.addAutoExpand(thisplace.TITLE + '&lt;br /&gt;' + thisplace.ADDRESS);

					map.addOverlay(marker);

				}

			}

		}

</pre>

<p>There are just a few lines in here that do the actual work of adding the marker to the page. The rest ensures that there was data that returned from the search, and iterates through those results.

</p><p>The <code>places</code> variable is one I created to take the array of results objects from the search. Each object contains the data about the results, such as latitude, longitude, place name (title), and address.

</p><p>Now that we have received results from a search we hard-coded, let&#8217;s look at how we can accept input and let users search our map.

</p>

<a name="Accept_User_Input"></a><h2> <span class="mw-headline">Accept User Input</span></h2>



<p>With the map we created in the previous section, we can search for burritos in San Francisco. What if someone wanted to search for something else somewhere else? Let&#8217;s add some ways to accept user input and use it in a local search.

</p><p>Here&#8217;s the example we&#8217;ll be working towards:

</p><p><iframe src="http://www.wired.com/wired/archive/webmonkey/Yahoolocal/usersearch.html" name="Page1" align="middle" frameborder="0" height="400" scrolling="no" width="600"></iframe>

</p><p>We can start with the version in the previous section, the static search for burritos. Instead of the single button to start the search, we need a couple input boxes and a new button. In fact, you can scrap the form in the previous section and replace it with this new one:

</p>

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

		Search for: &lt;input type="text" name="kw" /&gt;

		in &lt;input type="text" name="loc" value="San Francisco, CA" /&gt;



		&lt;input type="submit" value="Search Map" onclick="javascript:searchLocation(document.forms[0].loc.value, document.forms[0].kw.value); return false;" /&gt;

	&lt;/form&gt;

</pre>

<p>Instead of calling the doLocalSearch function directly, our new button calls <b>searchLocation</b>, a new function we&#8217;ll need to create. It passes the two values inside the input boxes to the function, so our new function needs to accept the name of a place and the keyword we&#8217;re searching.

</p><p>Add the searchLocation function to the file, just above the &lt;/script&gt; line:

</p>

<pre class="brush: js">		function searchLocation(placename, keyword)

		{

			map.drawZoomAndCenter(placename, 6);

			YEvent.Capture(map, EventsList.onEndGeoCode, function()

			{

				doLocalSearch(keyword);

			});

		}



</pre>

<p><br />

</p><p>Much of the code in this function will look similar to what we wrote in previous sections. We&#8217;ve used the drawZoomAndCenter call since the first empty map. Before, we set the map on San Francisco. Now we&#8217;re zooming and centering into whatever place the user types in.

</p><p>YEvent.Capture may also look familiar, from our doLocalSearch function. There we were capturing the onEndLocalSearch event. Here, we need to capture onEndGeoCode event. Why? Because whenever we look up a city (such as with drawZoomAndCenter), Yahoo needs to make an Ajax call to its geocoder. Since the result isn&#8217;t available immediately, we need to &#8220;place an order&#8221; so that something can happen as soon the geocoding is done.

</p><p>When the geocoding is done, we want to perform the local search. In order to get the keyword passed correctly, we need to wrap the call in an anonymous function. It&#8217;s a little confusing if you haven&#8217;t seen it before, but that&#8217;s a common programming pattern with JavaScript callbacks.

</p><p><br />

</p>

<a name="Calling_Out_The_Callbacks"></a><h3> <span class="mw-headline">Calling Out The Callbacks</span></h3>

<p>Speaking of callbacks, there are two that go on every time the user searches the map in this example.

</p><p><b>Callback one</b>: After calling drawZoomAndCenter, which needs to geocode the location. When this is complete, the first callback initiates the search function.

</p><p><b>Callback two</b>: After calling searchLocal, which needs to perform the local search. When this is complete, the second callback plots the markers on the page.

</p>

<a name="Where_to_go_From_Here"></a><h2> <span class="mw-headline">Where to go From Here</span></h2>



<p>You now have the basics down for plotting local data on a Yahoo Map. There are more directions to go than there are results for sushi in San Francisco.

</p>

<a name="Mashup_Direction"></a><h3> <span class="mw-headline">Mashup Direction</span></h3>

<p>What data do you have about your city? In addition to city locations, Yahoo Maps can look up specific addresses and landmarks. Armed with just park names, for example, you could show pet stores near parks.

</p><p>To see this in action, just return to the search example in the previous section and search for &#8220;pet stores&#8221; and use &#8220;Buena Vista Park San Francisco, CA&#8221; as the location.

</p>

<a name="Academic_Direction"></a><h3> <span class="mw-headline">Academic Direction</span></h3>

<p>Though I was mainly showing you how to use Yahoo Maps local search, you also received an introduction into more advanced JavaScript with callbacks. Now is the time to keep moving forward with your education by testing yourself. Can you edit the static search example to load automatically, eliminating the need for the search button?

</p><p>Hint: you&#8217;ll need to capture an event inside the initialize_maps function.

</p>

<a name="Location_Direction"></a><h3> <span class="mw-headline">Location Direction</span></h3>



<p>Use some JavaScript to grab the user&#8217;s location as a starting point. Luckily, we have a <a href="/2010/02/Track_User_Geolocation_With_JavaScript" class="external text" title="/2010/02/Track_User_Geolocation_With_JavaScript" rel="nofollow">JavaScript geolocation tutorial</a>. Go for it!

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

        
    </item>
    
    <item>
        <title>Same as it Ever Was: The History of HTML is a Conversation, Not a Spec</title>
        <link>http://www.webmonkey.com/2009/11/same_as_it_ever_was_the_history_of_html_is_a_conversation__not_a_spec/</link>
        <comments>http://www.webmonkey.com/2009/11/same_as_it_ever_was_the_history_of_html_is_a_conversation__not_a_spec/#comments</comments>
        <pubDate>Tue, 03 Nov 2009 14:10:53 +0000</pubDate>

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

        <guid isPermaLink="false">http://www.webmonkey.com/blog/sameasiteverwasthehistoryofhtmlisaconversationnotaspec</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTML]]></category>
        <description><![CDATA[Developer Mark Pilgrim has posted a fascinating look at how the HTML img tag came into existence. The history Pilgrim digs up &#8212; mailing list conversations between the creators of the first web browsers like Marc Andreessen and the webs early pioneers like Tim Berners-Lee &#8212; show that far from being a carefully planned specification, [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled -->
<p><img class="blogimg" src="http://www.webmonkey.com/mediawiki/images/090908_wm_html5_w.jpg" />Developer Mark Pilgrim has posted a fascinating look at how the HTML <code>img</code> tag came into existence. The history Pilgrim digs up &#8212; mailing list conversations between the creators of the first web browsers like Marc Andreessen and the webs early pioneers like Tim Berners-Lee &#8212; show that far from being a carefully planned specification, the lingua franca of the web evolved a bit like the early universe &#8212; out of <a href="http://diveintomark.org/archives/2009/11/02/why-do-we-have-an-img-element">a murky chaos</a>.</p>
<p>That from the chaos we got a workable &#8212; some would argue good &#8212; solution for creating the web is proof on some level that conversations and not abstracts, proposals and design by committee are the key to HTML&#8217;s success.</p>
<p>As Pilgrim writes:</p>
<blockquote>
<p>HTML has always been a conversation between browser makers, authors, standards wonks, and other people who just showed up and liked to talk about angle brackets. Most of the successful versions of HTML have been &#8220;retro-specs,&#8221; catching up to the world while simultaneously trying to nudge it in the right direction. </p>
</blockquote>
<p>You might be wondering, why did <code>img</code> succeed where other proposals, like an <code>include</code> or an <code>icon</code> tag failed? The answer is simple, because Marc Andreessen shipped code &#8212; Netscape Navigator &#8212; while those backing the other proposals, for most part, did not.</p>
<p>Of course that doesn&#8217;t mean that just shipping code is always good plan. Shipping code before a standard doesn&#8217;t necessarily produce the best solutions, as Pilgrim says. Or, put another way by a commentator on Pilgrim&#8217;s post, &#8220;shipping doesn&#8217;t mean you win, but not shipping means you lose.&#8221;</p>
<p>From those who shipped without the official blessing of a standard, we&#8217;ve come to have an img tag, the basis for AJAX, all of the HTML5 tools available in browsers today and much more.</p>
<p>Critics of HTML&#8217;s disorganized evolution will be quick to note that we&#8217;ve also come to have the <a href="http://www.montulli.org/theoriginofthe%3Cblink%3Etag">blink tag</a>, cross-browser rendering issues and other pains of web development. </p>
<p>Indeed we&#8217;re not suggesting that shipping features without at least engaging in the conversation is a good idea, but, when it comes to the future of HTML, if browser makers don&#8217;t ship HTML5 features before the standard is official we&#8217;ll be <a href="http://www.webmonkey.com/blog/HTML_5_Won_t_Be_Ready_Until_2022DOT_Yes__2022DOT">waiting until 2022</a> to use the new tools.</p>
<p>But while the future of HTML5 might be moving at a rather slow and convoluted pace. Pilgrim&#8217;s post is reminder that HTML has always progressed that way.</p>
<p>Perhaps the truly remarkable part is that, for all its flaws and convoluted evolution the core tech behind the web remains essentially the same now as it was then. &#8220;HTML is an unbroken line&#8230; a twisted, knotted, snarled line, to be sure&#8230; but still&#8230; Here we are, in 2009, and web pages from 1990 still render in modern browsers.&#8221;</p>
<p><strong>See Also:</strong><br/></p>
<ul>
<li><a href="http://www.webmonkey.com/blog/How_HTML_5_Is_Already_Changing_the_Web">How HTML 5 Is Already Changing the Web</a></li>
<li><a href="http://www.webmonkey.com/blog/What_HTML_5_is_and_What_it_is_Not">What HTML 5 is and What it is Not</a></li>
<li><a href="http://www.webmonkey.com/blog/HTML_5_Won_t_Be_Ready_Until_2022DOT_Yes__2022DOT">HTML 5 Won&#8217;t Be Ready Until 2022. Yes, 2022.</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>
]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2009/11/same_as_it_ever_was_the_history_of_html_is_a_conversation__not_a_spec/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Google Looks Me-Too As Suggest Launches</title>
        <link>http://www.webmonkey.com/2008/09/google_looks_me-too_as_suggest_launches/</link>
        <comments>http://www.webmonkey.com/2008/09/google_looks_me-too_as_suggest_launches/#comments</comments>
        <pubDate>Tue, 02 Sep 2008 21:27:24 +0000</pubDate>

                <dc:creator>Adam Duvander</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/blog/googlelooksmetooassuggestlaunches</guid>
        		<category><![CDATA[Software & Tools]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[search]]></category>
        <description><![CDATA[Did you hear about the news from Google? Okay, so the Chrome browser is big news, but there&#8217;s something else we wanted to bring to your attention: Last week Google Suggest graduated to the front page of Google.com. The feature finds possible matches to search terms as the user types. While it may seem old [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled -->
<p>Did you hear about the news from Google? Okay, so the <a href="http://www.webmonkey.com/blog/Google_Takes_On_IE__Firefox_With_Chrome_Web_Browser">Chrome browser</a> is big news, but there&#8217;s something else we wanted to bring to your attention: Last week Google Suggest <a href="http://googleblog.blogspot.com/2008/08/at-loss-for-words.html">graduated to the front page of Google.com</a>.</p>
<p><img class="blogimg" src="http://howto.wired.com/mediawiki/images/Google_suggest.png" alt="Google Suggest on the home page" class="full" /></p>
<p>The feature finds possible matches to search terms as the user types. While it may seem old now, it was a Google innovation. Suggest was first created in 2004 and made developers clamor to figure out how it was done. This was before the term &#8220;Ajax&#8221; was coined and well before it was overused.</p>
<p>Google does not make a homepage change lightly. For this reason, many assumed Suggest would never be made the default experience of most users who go directly to Google.com to search.</p>
<p>The feature was incorporated into many other tools over the years, including the Firefox search bar. Yahoo <a href="http://www.webmonkey.com/blog/Yahoo_s_New_Suggested_Search_Feature_Is_Half-Baked">added a similar feature to its homepage</a> over a year ago.</p>
<p><strong>See also:</strong></p>
<ul>
<li><a href="http://www.webmonkey.com/blog/Google_Experimental_Search_Adds_Personalized_Page_Ranking">Google Experimental Search Adds Personalized Page Ranking</a></li>
<li><a href="http://www.webmonkey.com/blog/WeatherMole">WeatherMole Uses Google Suggest</a></li>
<li><a href="http://www.webmonkey.com/blog/Yahoo_Search_Makeover_Improves_Multimedia_Results">Yahoo Search Makeover Improves Multimedia Results</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>
]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2008/09/google_looks_me-too_as_suggest_launches/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Microsoft Steers Developers to Ajax Roadmap</title>
        <link>http://www.webmonkey.com/2008/07/microsoft_steers_developers_to_ajax_roadmap/</link>
        <comments>http://www.webmonkey.com/2008/07/microsoft_steers_developers_to_ajax_roadmap/#comments</comments>
        <pubDate>Thu, 03 Jul 2008 21:26:45 +0000</pubDate>

                <dc:creator>Adam Duvander</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/blog/microsoftsteersdeveloperstoajaxroadmap</guid>
        		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[asp]]></category>
		<category><![CDATA[Microsoft]]></category>
        <description><![CDATA[In an effort to improve its Ajax features in ASP.NET, Microsoft announced its Ajax roadmap. The document lays out new features, many of which are available in third party JavaScript frameworks. Among the most exciting proposed features slated for the next version are DOM manipulation APIs, which make it easy to access any elements in [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled --><img class="blogimg" src="http://howto.wired.com/mediawiki/images/Aspnetajax.png" alt="ASP.NET Ajax" /></p>
<p>In an effort to improve its Ajax features in ASP.NET, Microsoft announced its <a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14924">Ajax roadmap</a>. The document lays out new features, many of which are available in third party JavaScript frameworks.</p>
<p>Among the most exciting proposed features slated for the next version are DOM manipulation APIs, which make it easy to access any elements in a web page. The company also plans to translate some server-side controls to be accessible via client-side calls. For example, a templating control could retrieve data from the server and place it into a page based on a local template without refreshing.</p>
<p>On the list of nice-to-haves, Microsoft includes animation and drag &amp; drop. These popular features are a major part of effects libraries such as Scriptaculous, Moo and JQuery.</p>
<p>Developers attempting to use non-Microsoft tools have long had difficulty fitting in with the ASP.NET framework. For example, ASP.NET changes the ID of any server-manipulated page element. The DOM features alone in the proposed update to Microsoft&#8217;s Ajax tools will simplify client-side access.</p>
<p>Some web purists may criticize Microsoft for not working to support third-party JavaScript frameworks. The company has long forged their own path with ASP.NET and to their credit each version is better than the previous.</p>
<p>If you want a peak at what the code will look like in the future version of ASP.NET Ajax, <a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=14924">download the roadmap</a>.</p>
<p><strong>See also:</strong></p>
<ul>
<li><a href="/2010/02/AspNet_Webforms_for_Beginners">ASP.NET Webforms for Beginners </a></li>
<li><a href="/2010/02/Use_Master_Pages_in_ASP">Use Master Pages in ASP.NET</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>
]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2008/07/microsoft_steers_developers_to_ajax_roadmap/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Run Ajax Apps on Bare S3</title>
        <link>http://www.webmonkey.com/2008/05/run_ajax_apps_on_bare_s3/</link>
        <comments>http://www.webmonkey.com/2008/05/run_ajax_apps_on_bare_s3/#comments</comments>
        <pubDate>Mon, 19 May 2008 19:21:34 +0000</pubDate>

                <dc:creator>Paul Adams</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/blog/runajaxappsonbares32</guid>
        		<category><![CDATA[Software & Tools]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[howto]]></category>
        <description><![CDATA[Amazon&#8217;s Simple Storage Service is designed to host data, not entire applications. It&#8217;s made to just serve as the backend to an app server &#8212; typically in Amazon&#8217;s cloud. Tom Evslin has worked out a way to host dynamic Ajax applications directly in the storage, with no intermediate server. Very cool. See Also: Is Facebook [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled -->
<p><img class="blogimg" src="http://g-ecx.images-amazon.com/images/G/01/00/10/00/14/19/27/100014192753._V46777512_.gif" alt="S3" style="float:right;" />Amazon&#8217;s Simple Storage Service is designed to host data, not entire applications. It&#8217;s made to just serve as the backend to an app server &#8212; typically in Amazon&#8217;s cloud.  </p>
<p>Tom Evslin has worked out a way to host dynamic Ajax applications directly in the storage, with no intermediate server. <a href="http://blog.tomevslin.com/2008/03/amazon-s3-backs.html ">Very cool.</a></p>
<p><strong>See Also:</strong><br/></p>
<ul>
<li><a href="http://blog.wired.com/monkeybites/2007/09/is-facebook-pla.html#previouspost">Is Facebook Planning To Offer Online Storage?</a></li>
<li><a href="http://blog.wired.com/monkeybites/2007/08/google-ups-onli.html#previouspost">Google Ups Online Storage Ante With Fee-Based Options</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>
]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2008/05/run_ajax_apps_on_bare_s3/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

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