<?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; wiki</title>
    <atom:link href="http://www.webmonkey.com/tag/wiki/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>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>CPC</title>
        <link>http://www.webmonkey.com/2010/02/cpc/</link>
        <comments>http://www.webmonkey.com/2010/02/cpc/#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=83</guid>
        		<category><![CDATA[Glossary]]></category>
		<category><![CDATA[advertising]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Cost per click (CPC) is a method of charging advertisers for the user clicks their advertisements have received. Cost per click is the going method for charging for targeted advertising, such as search ads, while cost per impression (CPM) is largely associated to branding advertisements, such as banner ads. Cost per acquisition (CPA) charges only [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Cost per click (CPC) is a method of charging advertisers for the user clicks their advertisements have received.

</p><p>Cost per click is the going method for charging for targeted advertising, such as search ads, while cost per impression (CPM) is largely associated to branding advertisements, such as banner ads. Cost per acquisition (CPA) charges only for users who have committed a transaction or <a href="/2010/02/Conversion" title="Reference:Conversion">conversion</a>.

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

        
    </item>
    
    <item>
        <title>Hover</title>
        <link>http://www.webmonkey.com/2010/02/hover/</link>
        <comments>http://www.webmonkey.com/2010/02/hover/#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=154</guid>
        		<category><![CDATA[Glossary]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Much like standing behind your co-worker while she slaves away, hover implies standing by but not doing anything. In dHTML, it refers specifically to when the user has positioned her cursor over a link but not yet clicked anything. The style will not change if the cursor is simply passed over the link, but you [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Much like standing behind your co-worker while she slaves away, hover implies standing by but not doing anything. In dHTML, it refers specifically to when the user has positioned her cursor over a link but not yet clicked anything. The style will not change if the cursor is simply passed over the link, but you can set an action to take place after a predetermined amount of hovering.

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

        
    </item>
    
    <item>
        <title>Write Symbols and Special Characters in HTML</title>
        <link>http://www.webmonkey.com/2010/02/write_symbols_and_special_characters_in_html/</link>
        <comments>http://www.webmonkey.com/2010/02/write_symbols_and_special_characters_in_html/#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=223</guid>
        		<category><![CDATA[HTML]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[When you type regular letters, numbers, and characters from your keyboard into the body of an HTML document, they show up on your Web pages just as you typed them. But things aren&#8217;t so easy in non-English speaking countries (and such places do exist &#8211; honest). Languages such as French, German, and Icelandic often use [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>When you type regular letters, numbers, and characters from your keyboard into the body of an HTML document, they show up on your Web pages just as you typed them. But things aren&#8217;t so easy in non-English speaking countries (and such places do exist &#8211; honest). Languages such as French, German, and Icelandic often use characters that are not found on your typical keyboard. Even in English, accents can distinguish a &#8220;résumé&#8221; from a &#8220;resume.&#8221;



</p><p>So how do you make special characters and accented letters show up on your pages? You use a special set of codes called <b>character entities</b>, which you insert into your HTML code and which your browser will display as the corresponding symbols or characters you want.



</p><span id="more-223"></span><p>The most common character entities have been collected by the International Organization for Standardization and compiled in the Special Characters ISO Latin Alphabet No. 1 table, which includes special characters, letters with diacritical marks (accents, umlauts, etc.), and scientific and currency symbols. The Latin-1 table contains 255 characters.



</p><p>There are two kinds of entities here: text and numeric. Both kinds begin with an ampersand (<tt>&amp;</tt>) and end with a semicolon (<tt>;</tt>).



</p><p>The text entities use letters to represent a character, and they&#8217;re designed to be easy to remember. So say you wanted to have the following sentence appear on your Web page:

</p>



<pre class="brush: js">"The © symbol stands for 'copyright.'"</pre>



<p>Your HTML code would look like this:</p>



<pre class="brush: js">"The &amp;copy; symbol stands for 'copyright.'"</pre>



<p>Numeric entities are similar to text ones, but should be written in this form:<tt>&amp;#x;</tt> &#8211; where the &#8220;x&#8221; represents a number between 0 and 255. It is very important to make sure that the <tt>#</tt> symbol precedes the number, or the entity will not work. So to make &#8220;The © symbol stands for &#8216;copyright.&#8217;&#8221; with a numeric entity, your HTML would look like this:</p>



<pre class="brush: js">"The &amp;#169; symbol stands for 'copyright.'"</pre>



<p>As you can see, some characters (like ©) can be represented by either a text or a numeric entity.



</p><p>A note of caution here:Many computers let you use keyboard shortcuts to create accented letters and special characters (for example, typing <tt>option</tt> + <tt>e</tt> will produce &#8220;é&#8221;). Beware, the shortcuts may not always work. The browser may read the character you created differently or not at all. This occurs because the code that is used to represent the character on the keyboard does not directly translate into Latin-1 and probably won&#8217;t be read by your Web browser.



</p><p>Sometimes, case can also be important. For example, <tt>&amp;eacute;</tt> produces the <tt>é</tt> character, while <tt>&amp;Eacute;</tt> results in <tt>É</tt>.



</p><p>So, that&#8217;s entities in a nutshell. Keep in mind that not all entities are recognized by older browsers. You may want to bookmark our <a href="/2010/02/Special_Characters" title="Reference:Special Characters"> ISO entities</a> page for future reference.</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/write_symbols_and_special_characters_in_html/feed/</wfw:commentRss>
        <slash:comments>2</slash:comments>

        
    </item>
    
    <item>
        <title>Python</title>
        <link>http://www.webmonkey.com/2010/02/python/</link>
        <comments>http://www.webmonkey.com/2010/02/python/#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=288</guid>
        		<category><![CDATA[Glossary]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Python is an interpreted, object-oriented programming language that runs on several operating systems, including Unix, Windows, OS/2 and Macintosh. The language is relatively easy to learn, and can be used for developing apps, or for more mundane tasks such as system administration, code generation and graphical user interfaces. Python was created by Guido van Rossum, [...]]]></description>

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

Python is an interpreted, object-oriented programming language that runs on several operating systems, including Unix, Windows, OS/2 and Macintosh. The language is relatively easy to learn, and can be used for developing apps, or for more mundane tasks such as system administration, code generation and graphical user interfaces. Python was created by Guido van Rossum, whose favorite comedy group was, you guessed it, Monty Python&#8217;s Flying Circus. Python is copyrighted, but the source code is freely available and can be commercially re-sold.

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

        
    </item>
    
    <item>
        <title>Tags (HTML)</title>
        <link>http://www.webmonkey.com/2010/02/tags_-_html/</link>
        <comments>http://www.webmonkey.com/2010/02/tags_-_html/#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=354</guid>
        		<category><![CDATA[Glossary]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Tags are commands written into a document that specifies how it should be formatted. In HTML, a tag is represented as &#60;TAG&#62;. For example, an HTML file can tell a browser to render text as boldfaced if in the text is written as &#60;b&#62;text&#60;/b&#62;. Note how the slash in the second tag closes the bookended [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled -->Tags are commands written into a document that specifies how it should be formatted. In HTML, a tag is represented as <pre class="brush: js">&lt;TAG&gt;</pre>. For example, an HTML file can tell a browser to render text as boldfaced if in the text is written as <pre class="brush: js">&lt;b&gt;text&lt;/b&gt;</pre>. Note how the slash in the second tag closes the bookended tags.<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/tags_-_html/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Live Thumbnails</title>
        <link>http://www.webmonkey.com/2010/02/live_thumbnails/</link>
        <comments>http://www.webmonkey.com/2010/02/live_thumbnails/#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=434</guid>
        		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[UI/UX]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[This is the JavaScript example from the Webmonkey tutorial Make Images Grow and Shrink With JavaScript. This script will allow you to put &#8220;live thumbnails&#8221; of images on your website. The thumbnails will grow and shrink when users click on them. &#60;script type="text/javascript"&#62; var links = document.getElementsByTagName('a'); for (var i = 0; i &#60; links.length; [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>This is the JavaScript example from the Webmonkey tutorial <a href="/2010/02/Make_Images_Grow_and_Shrink_With_JavaScript" title="Tutorial:Make Images Grow and Shrink With JavaScript"> Make Images Grow and Shrink With JavaScript</a>. This script will allow you to put &#8220;live thumbnails&#8221; of images on your website. The thumbnails will grow and shrink when users click on them.

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

<pre class="brush: js">&lt;script type="text/javascript"&gt;



var links = document.getElementsByTagName('a');



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

	if (links[i].className == 'livethumbnail')

	{

		var img = links[i].getElementsByTagName('img')[0];

		img.state = 'small';

		img.smallSrc = img.getAttribute('src');

		img.smallWidth = parseInt(img.getAttribute('width'));

		img.smallHeight = parseInt(img.getAttribute('height'));

		img.largeSrc = links[i].getAttribute('href');

		img.largeWidth = parseInt(img.getAttribute('largewidth'));

		img.largeHeight = parseInt(img.getAttribute('largeheight'));

		img.ratio = img.smallHeight / img.smallWidth;

		links[i].onclick = scale;

	}



function scale()

{

	var img = this.getElementsByTagName('img')[0];

	img.src = img.smallSrc;



	if (! img.preloaded)

	{

		img.preloaded = new Image();

		img.preloaded.src = img.largeSrc;

	}



	var interval = window.setInterval(scaleStep, 10);

	return false;



	function scaleStep()

	{

		var step = 10;

		var width = parseInt(img.getAttribute('width'));

		var height = parseInt(img.getAttribute('height'));



		if (img.state == 'small')

		{

			width += step;

			height += Math.floor(step * img.ratio);



			img.setAttribute('width', width);

			img.setAttribute('height', height);



			if (width &gt; img.largeWidth - step)

			{

				img.setAttribute('width', img.largeWidth);

				img.setAttribute('height', img.largeHeight);

				img.setAttribute('src', img.largeSrc);

				window.clearInterval(interval);

				img.state = 'large';

			}

		}

		else

		{

			width -= step;

			height -= Math.floor(step * img.ratio);



			img.setAttribute('width', width);

			img.setAttribute('height', height);



			if (width &lt; img.smallWidth + step)

			{

				img.setAttribute('width', img.smallWidth);

				img.setAttribute('height', img.smallHeight);

				img.src = img.smallSrc;

				window.clearInterval(interval);

				img.state = 'small';

			}

		}

	}

}





&lt;/script&gt;

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

        
    </item>
    
    <item>
        <title>Site Optimization Tutorial &#8211; Lesson 2</title>
        <link>http://www.webmonkey.com/2010/02/site_optimization_tutorial_-_lesson_2/</link>
        <comments>http://www.webmonkey.com/2010/02/site_optimization_tutorial_-_lesson_2/#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=643</guid>
        		<category><![CDATA[CSS]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[In Lesson 1 of this tutorial, we learned how to manipulate images to reduce your download time. Now, it&#8217;s time to dig even deeper into the fine art of slimming down those pages. We&#8217;re going to talk about page layout, and that means talking about HTML tables, first and foremost. First, because table-based layouts are [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>In <a href="/2010/02/Site_Optimization_Tutorial_-_Lesson_1" title="Tutorial:Site Optimization Tutorial - Lesson 1"> Lesson 1</a> of this tutorial, we learned how to manipulate images to reduce your download time. Now, it&#8217;s time to dig even deeper into the fine art of slimming down those pages.

</p><p>We&#8217;re going to talk about page layout, and that means talking about HTML tables, first and foremost. First, because table-based layouts are the <i>de facto</i> web standard, and foremost because table-heavy designs have a nasty reputation for poor performance.

</p><p>And CSS layout? It&#8217;s faster, better, and smarter. We&#8217;ll cover it later. Now, you&#8217;re welcome to skip ahead, but The House bets that you&#8217;ll keep reading.

</p><p>CSS is cooler than tables. And smaller. And in the long run, its better. But some CSS-2 layout standards still aren&#8217;t showing up the same in every browser. So let&#8217;s face it &#8212; sometimes right-now compatability trumps future-compatability.

</p><p>Tables aren&#8217;t all bad, anyways. Most designers are taught to design with a grid, so dropping things into a table comes naturally. We&#8217;re also fond of their duality; variable-width tables can both define a layout and respond to the unpredictable elements of a page. Being a web designer means coping with unpredictability, and striking a compromise between your design and the user&#8217;s flexibility. (Users should be afforded the ability to make fonts larger, for instance). Unfortunately, tables also increase the time it takes to display a web page, and sometimes by a substantial amount.



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

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

<ol>

<li><a href="#Tables:_Past_Performance.2C_Future_Returns">Tables: Past Performance, Future Returns</a></li>

<li><a href="#Bring_it_to_the_Table">Bring it to the Table</a></li>

<li><a href="#Better_Structure.2C_Faster_Page">Better Structure, Faster Page</a></li>



<li><a href="#CSS:An_Overview_for_Optimizers">CSS:An Overview for Optimizers</a></li>

<li><a href="#Code_Size">Code Size</a></li>

</ol>

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

<a name="Tables:_Past_Performance.2C_Future_Returns"></a><h4> <span class="mw-headline">Tables: Past Performance, Future Returns</span></h4>

<p>Historically, browsers needed to understand a table&#8217;s structure before drawing the table&#8217;s contents, so that nothing was put on-screen until all of the table&#8217;s content was downloaded. How dumb! Even with 99% of a page downloaded, some stubborn browsers wouldn&#8217;t even think about laying out a table, until receiving a concluding <tt>&lt;/table&gt;</tt> tag. This foot-dragging was the anathema of dial-up modem users everythwere. Well, back in &#8217;96, it might&#8217;ve briefly been celebrated as &#8220;cyber&#8221; foot-dragging.



</p><p>Since the advent of IE 5.x, Mozilla 1, and Netscape 6.x, this performance pitfall is automatically avoided. Today&#8217;s newer browsers use progressive or &#8220;incremental&#8221; rendering by default, and will attempt to render tables on a row-by-row basis, rather than pausing and waiting for the <tt>&lt;/table&gt;</tt> tag to begin the process. If a page&#8217;s source code relies heavily on tables, and the page downloads in fits and starts, modem users at least have a decent chance of seeing some content on the screen quickly.

</p><p>Tables perform lamely for another reason, though. As tables get bigger, and nested into one another, the amount of info that needs processing increases exponentially. On mobiles and slower computers, all this processing-intensive work doesn&#8217;t come easy, and serious time can pass before a table renders to the screen.

</p><p>But don&#8217;t fool yourself &#8212; circa-2003 operating systems require more CPU overhead, and the codebase of today&#8217;s web browsers sure ain&#8217;t getting smaller. Even Firefox, once a browser, is suddenly a &#8220;platform&#8221;. And don&#8217;t forget the flyweight &#8220;thin clients&#8221;, web-enabled phones and game consoles, valiantly attempting to take on the wild web. They lack CPU muscle, and don&#8217;t show much spirit for parsing table-heavy layouts. Basically, if you&#8217;re going to use tables, you still need to do whatever you can to optimize the code. Or, better yet, avoid it altogether.

</p><p><b>Accelerating fixed-width tables</b>

</p><p>If you&#8217;ve got a fixed-width table where you&#8217;ve explicitly set the TABLE WIDTH attribute to so-and-so many pixels, check this out:

</p><p>Appling a CSS-1 style of <tt>table layout:fixed</tt> to a fixed-width table speeds up the display process. With <tt>layout:fixed</tt> present, browsers use a simpler, faster rendering method to draw a table&#8217;s contents, trusting your assertion that everything&#8217;s been properly sized-up, already.

</p><p>Here&#8217;s a code example of <tt>layout:fixed</tt> applied to a table:



</p>

<pre class="brush: js">

&lt;table style="table-layout:fixed" width="600"&gt;

 &lt;tr height="30"&gt;

 &lt;td width="150"&gt;happy&lt;/td&gt;

 &lt;td width="200"&gt;happy&lt;/td&gt;



 &lt;td width="250"&gt;happy&lt;/td&gt;

 &lt;/tr&gt;

</pre>

<p>Now, don&#8217;t go abusing the browser&#8217;s trust! If you apply the <tt>table layout:fixed</tt> style incorrectly, with widths that don&#8217;t quite add up, the browser will catch the error during the rendering process and start things over from scratch. Do that, and your tables will appear slower, not faster.

</p>

<a name="Bring_it_to_the_Table"></a><h4> <span class="mw-headline">Bring it to the Table</span></h4>



<p>Here&#8217;s another nugget of truth: Browsers prefer easy-chew tables. One old-school trick works, though &#8211; remembering that lots of little tables appear to render faster than one big, many-rowed table.

</p><p>If you&#8217;ve got a nine-row table that fills a few screens full of information, go ahead and break it into three smaller tables of three rows each. This strategy is particularly beneficial if your web pages require a lot of vertical scrolling. Your audience can read the contents of your first table as other tables continue to load down in the nether regions of your page.

</p><p><b>Don&#8217;t Trust WYSIWYG Editors</b>

</p><p>Tables can be a pain, which is one big reason WYSIWYG HTML editors became popular in the first place. However, while HTML editors make it easier to create tables, they can produce amazingly inefficient code.

</p><p>The layout windows of WYSIWYG editors often make it tough to spot unnecessarily nested tables, improperly sized table elements, or strange, roundabout HTML code. So if you want your tables to be as slim and efficient as possible, but you still want to use your WYSIWYG editor, then budget some time at the end to validate and clean up your code. Once everything looks the way you want it, jump to &#8220;Code View&#8221; in the WYSIWYG editor, or drop the dirty HTML into a text-editing app and pick over your code until it is nice and clean.

</p><p><b>Nested Tables &#8211; the old taboo!</b>

</p><p>One notorious culprit associated with slow-to-the-screen web pages has always been the nested table. A nested table is created when one table is put inside the cell of another table. Of course, with ever-faster computer hardware, nested tables may not get such a bad rap these days. Well, go ahead and call us old-timers, but nested tables are still sucky in our book.

</p><p>Why the legendary performance hit with nested tables? For starters, browsers have to work double-time on tables. Unlike most page elements, tables absolutely require two passes of browser &#8220;reflow&#8221; (layout code-crunching), due to their auto-sizing shrink-wrap behavior. Pass #1 assesses what size each table cell would like to be, and Pass #2 determines how big they actually can be, once other elements on the page have been accounted for.

</p><p>And there&#8217;s the rub. A single-nested table requires two passes, plus one more, because the inner table must be partially re-rendered during outer table&#8217;s rendering process. Nest three tables inside one another, and that makes for five passes of reflow. Nest five levels deep, and the browser loops through reflow routines nine times.

</p><p>Fun Fact: Some tables may even require a third reflow pass when put in tricky situations like specified-percentage-height table cells squatting in an un-sized parent table. Woah! Wait &#8211; did we just say &#8220;Fact&#8221; or &#8220;Fun Fact&#8221;? Oh. Umm, we meant to say &#8220;Fact&#8221;.

</p><p>So avoid using nested tables whenever possible, even if it means making minor alterations or simplifications to page layout. (Remind your design team that Photoshop is an image editor, not a HTML-prototyping application) If you must use nested tables, at least keep them simple &#8212; try not to nest more than a few levels deep. Even though table rendering speed issues are less problematic on modern PC hardware, table layouts still hamper screen readers and other accessibility-enhanced browsers. Nested tables doubly so. We&#8217;re building web pages here, not those little Russian dolls.

</p>

<a name="Better_Structure.2C_Faster_Page"></a><h4> <span class="mw-headline">Better Structure, Faster Page</span></h4>



<p>Below is the classic web page layout. You&#8217;ll notice the branding across the top, navigation down the left side, and content in the remaining part of the page. It&#8217;s pretty common for such pages to be constructed using a large table which defines the entire grid. With the branding, navigation, and content tables nested within the overall framework table, this can be a difficult page for the browser to render.

</p><p><b>Examples</b>

</p><p><iframe src="http://www.wired.com/wired/webmonkey/stuff/siteoptimization2_tableexample.html" name="Page1" align="middle" frameborder="0" height="530" scrolling="yes" width="80%"></iframe>

</p><p>By making each table independent and concise, any browser can render each element as soon as it finishes reading it. So the first elements of the page appear faster, and the user can take advantage of the features at the top of the page immediately. (Remember, &#8220;perceived speed&#8221; and &#8220;visual accessibility&#8221;.)

</p><p>In the second example, the branding table loads first on the page, followed by the navigation table. And, since we set the alignment of the navigation table to &#8220;left&#8221;, the content loads next, positioned to the right. The page appears to load faster, and the user has something to see and use almost immediately.

</p><p>So, as with images, to get the best results with your tables, you need to play around with a variety of solutions until you get a layout that both you and your users can live with. It may seem like a lot of effort just to shave a few seconds off a page&#8217;s load time, but competition for user loyalty is fierce, and those seconds can be all that stand between your visitors and the Back button.

</p>

<a name="CSS:An_Overview_for_Optimizers"></a><h4> <span class="mw-headline">CSS:An Overview for Optimizers</span></h4>

<p>Tired of tables yet? (You&#8217;re free to shout &#8216;Hellzyeeeaahh, G!&#8217;, without impinging the previous portion of this humble web development narrative.) After all, debugging cross-browser table display issues, or parsing content buried under a mishmash of <tt>&lt;td&gt;</tt>s, <tt>&lt;tr&gt;</tt>s and <tt>&lt;font&gt;</tt> tags gets old, fast.



</p><p>Hence the hooplah over CSS.

</p><p>Cascading Style Sheets is a smart <a href="http://www.w3.org/TR/REC-CSS2/" class="external text" title="http://www.w3.org/TR/REC-CSS2/" rel="nofollow">standard</a>, promising precise control over the looks and the layout of websites. Idyllic stuff, indeed, for jaded web workers. Well, CSS isn&#8217;t quite Utopia, yet &#8211; cross-browser snags and snafus still exist. But it&#8217;s a solid leap ahead, especially if you&#8217;re keen on creating speedy web sites.

</p><p>We&#8217;ll refrain from re-hashing the many treatises on why separating content from markup code is the bee&#8217;s knees (i.e. here, here, and here), but we will repeat this much:It is far easier to redesign or repurpose web content that has been built as such using technologies like CSS, XML, and XHTML. This matters for us speed freaks (in the positive, HTML-optimization sense), because serving different versions of a site is a serious consideration. &#8220;Optimized&#8221; is relative term for broadband users and mobile phone surfers, for example, and one page format is unlikely to satisfy both audiences. Once you&#8217;ve separated the content from a page&#8217;s architecture, you can publish to multiple formats or designs without doubling or tripling your workload.

</p><p>Great resources for getting familiarized with CSS (a.k.a stealing code snippets) include <a href="/2010/02/Mulders_Stylesheets_Tutorial" title="Tutorial:Mulders Stylesheets Tutorial"> Mulders Stylesheets Tutorial</a> right here on Webmonkey, as well as <a href="http://glish.com/" class="external text" title="http://glish.com/" rel="nofollow">glish.com</a>, <a href="http://bluerobot.com/" class="external text" title="http://bluerobot.com/" rel="nofollow">bluerobot.com</a>, and Jeffrey Zeldman&#8217;s <a href="http://www.zeldman.com/" class="external text" title="http://www.zeldman.com/" rel="nofollow">musings</a> on the topic. To see a kick-ass example of a commercial site that pioneered web-standards-compliant code, look no further than Webmonkey&#8217;s sister-site <a href="http://www.wired.com/" class="external text" title="http://www.wired.com/" rel="nofollow">Wired</a>, which uses CSS absolute and relative positioning for almost all of its layout concerns.



</p><p>Like we said, though, this tutorial focuses on optimization &#8211; why CSS layout is faster than table layout, and how to make it seem faster still.

</p>

<a name="Code_Size"></a><h4> <span class="mw-headline">Code Size</span></h4>

<p>Reduced code size probably accounts for 95% of the performance gains you see when jumping from an intricate table-based layout to a smart CSS design. When your source code is shedding kilobytes by the dozen, rendering speed and the like become academic issues.

</p><p>A CSS layout and text-styling combo is invariably bound to create a smaller page than one laid out with deprecated <tt>&lt;table&gt;</tt> and <tt>&lt;font&gt;</tt> tags. That&#8217;s because with CSS, you type fewer characters to create the file, so unsurprisingly, the user downloads fewer characters to get the file.

</p><p>How big of a difference does this make in the end? That depends on a lot of variables, like how complex a particular page is, but it&#8217;s probably worth a good 10K on average. Now, I use the rule of thumb that 2K of code represents one second of download/render/latency time, so we&#8217;re talking roughly five seconds. Five whole seconds otherwise wasted staring slack-jawed at a computer screen. Remember, for that great majority of people surfing sober, five seconds can be a palpably dull period of time.

</p><p>CSS helps webmasters determine the order in which page elements are downloaded and when they appear on the screen. This is fantastic for boosting a site&#8217;s visual accessibility and perceived speed. For example, a news site can load the story element first, load decorative page elements next, and finally, load the advertisement, regardless of where these items appear on the page.

</p><p>The user will still take note of a site&#8217;s design quality, as well as the advertisement. What they won&#8217;t notice, though, are frustrating delays in loading the page. Remember, if a user senses it&#8217;s the sponsorships or fancy decorative elements that make a page sluggish, it&#8217;s often the sponsors and the site&#8217;s image which suffer most.

</p><p>How do you prioritize what elements get loaded first with CSS? Just put it at the top of the source code, no matter where it&#8217;s positioned on the page. Fisher-Price easy.



</p><p>You don&#8217;t need to go the whole Harley with CSS layout to reap the benefits. Simply using CSS styles on your text, in lieu of <tt>&lt;font&gt;</tt> tags, saves significant space. If you&#8217;re reluctant to migrate a tried-and-tested table layout to CSS-positioning, but mellow with the idea of serving unstyled text to the odd out-of-date browser, give this method a test drive.

</p><p>By the way, this CSS+tables compromise works best for pages with text content spread across many table cells. Since long-winded font tags (<tt>&lt;font face="blah, blah, blah" size="blah"&gt;</tt>) must be repeated in every single table cell, the minimal notation of CSS styles gets leveraged to full effect. A simple &#8220;<tt>&lt;p&gt;</tt>&#8221; does the trick via CSS. Of course, try to use a sensible shorthand when naming CSS classes, and don&#8217;t explicitly add class attributes to tags if avoidable &#8211; why add more characters to your source code than necessary? Imagine those antiquated font declarations repeated thirty times and it&#8217;s easy to imagine the space savings.

</p><p><b>The Compromise Method</b>

</p><p>If you&#8217;re still straddling the fence between CSS and tables and you have a minimal number of pages to manage, you might consider serving different page formats to different browsers via browser-detection and server-side scripting. Of course, this immediately doubles the amount of coding, testing, and debugging work that&#8217;ll need doing, but it may be worthwhile on a small scale, such as on your site&#8217;s homepage or a few heavily-trafficked pages.

</p><p><br />

<span id="title_name_el" class="wm_hidden_meta_class" title="Site Optimization Tutorial" style="visibility: hidden;"> <span id="page_path_el" class="wm_hidden_meta_class" title="/webmonkey/98/26/" style="visibility: hidden;"> <span id="author_el" class="wm_hidden_meta_class" title="smudge" style="visibility: hidden;"> <span id="creation_date_el" class="wm_hidden_meta_class" title="Updated 2002-12-13T24:00:00Z" style="visibility: hidden;"> </span></span></span></span>



</p>

<div id="series">

<div class="series_hdr">Site Optimization Tutorial</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><a href="/2010/02/Site_Optimization_Tutorial" title="Tutorial:Site Optimization Tutorial"> Site Optimization Tutorial</a><br />

<a href="/2010/02/Site_Optimization_Tutorial_-_Lesson_1" title="Tutorial:Site Optimization Tutorial - Lesson 1"> Site Optimization Tutorial &#8211; Lesson 1</a><br />

<strong class="selflink"> Site Optimization Tutorial &#8211; Lesson 2</strong><br />

<a href="/2010/02/Site_Optimization_Tutorial_-_Lesson_3" title="Tutorial:Site Optimization Tutorial - Lesson 3"> Site Optimization Tutorial &#8211; Lesson 3</a><br />



<a href="/2010/02/Site_Optimization_Tutorial_-_Lesson_4" title="Tutorial:Site Optimization Tutorial - Lesson 4"> Site Optimization Tutorial &#8211; Lesson 4</a>

</p>

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

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

        
    </item>
    
    <item>
        <title>JavaScript Tutorial &#8211; Lesson 5</title>
        <link>http://www.webmonkey.com/2010/02/javascript_tutorial_-_lesson_5/</link>
        <comments>http://www.webmonkey.com/2010/02/javascript_tutorial_-_lesson_5/#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=715</guid>
        		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Multimedia]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[thau]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Now that you&#8217;ve mastered the basics of computer programming, it&#8217;s time to refocus on the Document Object Model (DOM). We&#8217;ve already seen that the DOM hierarchy starts with a Window object. Inside each Window object is a Document object. We&#8217;ll be spending this lesson going through the Document object and seeing how it can be [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Now that you&#8217;ve mastered the basics of computer programming, it&#8217;s time to refocus on the Document Object Model (DOM). We&#8217;ve already seen that the DOM hierarchy starts with a Window object. Inside each Window object is a Document object. We&#8217;ll be spending this lesson going through the Document object and seeing how it can be used to get all kinds of information from your users and to dynamically present new information.</p>
<br />
<span id="more-715"></span>

<p>We&#8217;ve already had a good look at one of the properties of the Document object, the Images array. If you remember back to Lesson 4, the first image in a document can be modified by changing its src property. For example,</p>
<pre class="brush: js"> window.document.images[0].src='some_new_picture.gif';
</pre>
<p>will change the first image in a document to the GIF called <code>some_new_picture.gif</code>. As you might have guessed, each Image in the Image array is itself an object in the DOM. That&#8217;s why <code>images[0].src</code> works. It&#8217;s saying, get the Image object <code>image[0]</code> from the Images array and set its src property. The whole statement above reads in English, &#8220;get the document property of this window, get the first image from the document&#8217;s image array, and change its source property to <code>some_new_picture.gif</code>.&#8221;</p>
<p>The Image object has lots of other interesting properties. For example, you can have your JavaScript check to see if an image has been completely loaded before doing anything. However, these interesting properties will have to wait for later lessons. Gotta keep you coming back somehow, right? Today, we&#8217;ll be focusing entirely on forms and how to use them in JavaScript.</p>
<table id="toc" class="toc" summary="Contents">
<tbody>
<tr>
<td>
<div id="toctitle">
<h2>Contents</h2>
</p></div>
<ol>
<li><a href="#Introduction_to_Forms">Introduction to Forms</a></li>
<li><a href="#Manipulating_the_Value_of_a_Text_Field">Manipulating the Value of a Text Field</a></li>
<li><a href="#Text_Field_Events">Text Field Events</a></li>
<li><a href="#Form_Handlers">Form Handlers</a></li>
<li><a href="#Text_Field_Exercise">Text Field Exercise</a></li>
<li><a href="#Checkboxes">Checkboxes</a></li>
<li><a href="#Radio_Buttons">Radio Buttons</a></li>
<li><a href="#Selects">Selects</a></li>
<li><a href="#onChange_in_Select_Form_Elements">onChange in Select Form Elements</a></li>
<li><a href="#Review_of_Lesson_5">Review of Lesson 5</a></li>
</ol>
</td>
</tr>
</tbody>
</table>
<p></p>
<p><a name="Introduction_to_Forms"></a><br />
<h4> <span class="mw-headline">Introduction to Forms</span></h4>
<p>Forms are part of the HTML 1.0 specification. Many people don&#8217;t know about them, however, because there&#8217;s a misconception that they&#8217;re only useful if you (or someone you know) can do server-side CGI programming. As June points out in her <a href="/2010/02/Add_HTML_Forms_to_Your_Site" title="Tutorial:Add HTML Forms to Your Site">forms tutorial</a>, forms can be fun even if you aren&#8217;t a CGI programmer. More important for this tutorial, JavaScript can be used to add all sorts of functionality to forms without the help of server-side CGI.</p>
<p>If you don&#8217;t know how forms work, check out <a href="/2010/02/Add_HTML_Forms_to_Your_Site" title="Tutorial:Add HTML Forms to Your Site">Jay&#8217;s tutorial</a> and try writing some forms yourself. I&#8217;m going to assume that you know the basics.</p>
<p>The first thing you need to know about forms and JavaScript is that forms, like images, are stored in an array of objects. Just like you can refer to the first image on a page by calling it <code>window.document.images[0]</code>, you can refer to the first form on a page using <code>window.document.forms[0]</code>. Similarly, just like you can name images, you can name forms. For an example if <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms1.html" rel="nofollow">this form</a> is written like this,</p>
<pre class="brush: js"> &lt;form name="first_form"&gt;

 &lt;input type="text" name="first_text" size="40"

 value="Power to the primates!"&gt;

 &lt;/form&gt;
</pre>
<p>You can refer to the form in either of these two ways:</p>
<pre class="brush: js"> var the_form = window.document.forms[0];

 var the_same_form = window.document.first_form;
</pre>
<p>Although being able to refer to forms is sometimes useful, more often you want to refer to elements inside of forms, such as the text field in the last example. Here&#8217;s an example of manipulating the value of a text field.</p>
<p><a name="Manipulating_the_Value_of_a_Text_Field"></a><br />
<h4> <span class="mw-headline">Manipulating the Value of a Text Field</span></h4>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms2.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms2.html" rel="nofollow">Click here</a> and mouse over the links below the text field and see what happens.</p>
<p>This magic is performed by changing the value of the text field. The form looks like the one in the last example:</p>
<pre class="brush: js"> &lt;form name="first_form"&gt;

 &lt;input type="text" name="first_text" value="Are you happy?"&gt;

 &lt;/form&gt;
</pre>
<p>The links that change the text field are:</p>
<pre class="brush: js"> &lt;a href="#" onMouseOver="window.document.first_form.first_text.value=

 'Clap clap!';"&gt;Yes, and I know it.&lt;/a&gt;

 &lt;a href="#" onMouseOver="window.document.first_form.first_text.value=

 'Sour puss!';"&gt;No!&lt;/a&gt;
</pre>
<p>These are normal mouseovers; the important part is:<code>window.document.first_form.first_text.value='Clap clap!'</code>. This says, &#8220;find the form called <code>first_form</code> in the document, find the form element called <code>first_text</code>, and set its value to &#8216;Clap clap!&#8217;.&#8221; The second line works similarly. This is very much like changing the src of an image. Instead of having a src, text fields have values.</p>
<p>Other types of form elements can be affected by messing with their values &#8211; for example, textareas:</p>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms3.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms3.html" rel="nofollow">Click here</a>.</p>
<p>The forms and links here are very similar to those above. The form is:</p>
<pre class="brush: js">&lt;form name="form_two"&gt;

 &lt;textarea name="the_textarea" rows=10 cols=60&gt;

 Mouse over below to see the first verse of

 The Webmonkey song, adapted from

 "I Wanna Be Like You" (The Monkey Song)

 from Walt Disney's &lt;cite&gt;The Jungle Book&lt;/cite&gt;

 written by Richard M. Sherman and Robert B. Sherman

 &lt;/textarea&gt;

 &lt;/form&gt;
</pre>
<p>Notice that the form has a name, <code>form_two</code>, and the textarea has a name as well, <code>the_textarea</code>.</p>
<p>The links are basically the same as what you saw in the text field example:</p>
<pre class="brush: js">&lt;a href="#" onMouseOver="window.document.form_two.the_textarea.value=

first_part;"&gt;Part 1&lt;/a&gt;

&lt;a href="#" onMouseOver="window.document.form_two.the_textarea.value=

second_part;"&gt;Part 2&lt;/a&gt;
</pre>
<p>The only difference is that instead of assigning a string to the value of the textareas, I assigned variables that I defined in the header. View Source to see that they&#8217;re there. I only did this for the sake of neatness, to get those long strings out of the HTML. A well-groomed monkey is a happy monkey. Here&#8217;s one of the strings:</p>
<pre class="brush: js"> var first_part = "Now I'm the king of the swingersnOh, the jungle VIPnI've reached the top and had to stopnAnd that's what botherin' me";
</pre>
<p>Notice the <code>"n"</code>. This is standard computerese for new lines. In general, because you&#8217;re working with HTML, the new line isn&#8217;t important. But if you&#8217;re writing something in a <code>&lt;pre&gt;</code> tag, or you&#8217;re writing into a textarea, the <code>"n"</code> comes in handy.</p>
<p>In addition to changing the values of form elements, JavaScript allows you to detect events that go on inside of them. Here&#8217;s an example of detecting events inside a text field.</p>
<p><a name="Text_Field_Events"></a><br />
<h4> <span class="mw-headline">Text Field Events</span></h4>
<p>Text fields understand <code>onBlur</code>, <code>onFocus</code>, and <code>onChange</code>. The <code>onFocus</code> event occurs when someone clicks inside a text field. <code>onBlur</code> happens when somebody moves out of a text field by clicking outside of it, or hitting &#8220;tab.&#8221; <code>onChange</code> happens when somebody changes what&#8217;s in the text field and then moves outside the text field.</p>
<p>Try doing these things in the text field and see what happens in the textarea below it.</p>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms4.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms4.html" rel="nofollow">Click here</a>.</p>
<p>Here&#8217;s how this works. The text field looks like this:</p>
<pre class="brush: js">&lt;input type="text" name="first_text"

   onFocus="writeIt('focus');"

   onBlur="writeIt('blur');"

   onChange="writeIt('change');"&gt;
</pre>
<p>Each of the event handlers calls the function <code>writeIt()</code>, which I&#8217;ve defined in the header. The header looks like this:</p>
<pre class="brush: js">&lt;head&gt;

 &lt;title&gt;Text Field Events&lt;/title&gt;

 &lt;script language="JavaScript"&gt;

 &lt;!-- hide me

 function writeIt(the_word)

 {

   var word_with_return = the_word + "n";

   window.document.first_form.the_textarea.value +=

     word_with_return;

 }

 // show me --&gt;

 &lt;/script&gt;

 &lt;/head&gt;
</pre>
<p>This should all look pretty familiar to you. The first few lines are the typical JavaScript preamble and the function definition. The first line in the body of the function &#8230;</p>
<pre class="brush: js"> var word_with_return = the_word + "n";
</pre>
<p>&#8230;. initializes a new variable, <code>word_with_return</code>, and sets it equal to the string that was passed into the function concatenated with a <code>"n"</code>. (Remember, the <code>"n"</code> is standard computerese for &#8220;new line.&#8221;)</p>
<p>The next line &#8230;</p>
<pre class="brush: js"> window.document.first_form.the_textarea.value += word_with_return;
</pre>
<p>&#8230;. says, &#8220;set the value of the textarea to its current value plus the new variable.&#8221; This shortcut was covered when we learned about loops. It&#8217;s the same as saying:<code>window.document.first_form.the_textarea.value =</p>
<p></code></p>
<pre class="brush: js">  window.document.first_form.the_textarea.value + word_with_return;

 It just takes less time. So far, we've seen a property of text fields and textareas (the value) and some events that they can handle. The remaining thing to know about these elements is the methods that they can handle:<code>blur()</code>, <code>focus()</code>, and <code>select()</code>.
</pre>
<p>Here are some links to show you how <code>focus()</code> and <code>select()</code> work. Beware that they sometimes stop working after the first time:</p>
<p></p>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms5.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms5.html" rel="nofollow">Click here</a>.</p>
<p></p>
<p>Here are the form and the two links:</p>
<pre class="brush: js"> &lt;form name="method_form"&gt;

 &lt;input type="text" name="method_text" size=40 value="Hey, hey, we're the monkeys"&gt;

 &lt;/form&gt;  &lt;a href="#" onMouseOver="window.document.method_form.method_text.focus();"&gt;Mouseover to focus&lt;/a&gt;

 &lt;a href="#" onMouseOver="window.document.method_form.method_text.select();"&gt;Mouseover to select&lt;/a&gt;
</pre>
<p>Accessing the methods of a text field is just like accessing the methods of any object:<code>object_name.method()</code>. The name of a text field is <code>window.document.form_name.text_field_name</code>. So, to call the <code>focus()</code> method on the text field above, we call:</p>
<pre class="brush: js"> window.document.method_form.method_text.focus();
</pre>
<p>That&#8217;s pretty much all there is to know about text fields and textareas. We&#8217;re about ready to try the first exercise for this lesson. First, however, there&#8217;s one more thing you need to know about form handlers before you can do the exercise.</p>
<p><a name="Form_Handlers"></a><br />
<h4> <span class="mw-headline">Form Handlers</span></h4>
<p>Forms are objects; they have their own methods, properties, and event handlers. One event handler that you should know about is <code>onSubmit</code>. <code>onSubmit</code> gets called in two situations:if a user clicks on a Submit button, or if a user hits Return in a text field. If these actions are not handled in some way, your JavaScript may behave differently than expected. Try clicking on</p>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms6.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms6.html" rel="nofollow">Submit</a> and see what happens.</p>
<p>In Netscape, clicking on an unhandled Submit button generally leads to reloading the page. In general, you won&#8217;t want this. In order to block this behavior, you need to do this:</p>
<pre class="brush: js">&lt;form onSubmit="return false;"&gt;

 &lt;input type="submit" value="Submit"&gt;

 &lt;/form&gt;
</pre>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms7.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms7.html" rel="nofollow">Try it</a></p>
<p>Generally, <code>return false</code> is a way that JavaScript stops your browser from doing what it would otherwise do. Another example of this is stopping an <code>href</code> from going to the URL assigned to it. For example, the link &#8230;</p>
<pre class="brush: js"> &lt;a href="http://www.webmonkey.com/" onClick="return false;"&gt;mattmarg!&lt;/a&gt;
</pre>
<p>&#8230;. won&#8217;t go anywhere because you&#8217;ve returned false on the onClick. <a href="http://www.webmonkey.com/" class="external text" title="http://www.webmonkey.com/" rel="nofollow">Click on this dead link</a>, if you don&#8217;t believe me.</p>
<p>This may seem like a weird thing to do, but actually it&#8217;s quite common, especially in the case of forms. Here&#8217;s an example of using a form to get input from a user. Type something into <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms8.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms8.html" rel="nofollow">this text field</a> and hit Return.</p>
<p></p>
<p>Here&#8217;s the form:</p>
<pre class="brush: js"> &lt;form name="text_entry_form" onSubmit="monkeyLove(); return false;"&gt;

 &lt;b&gt;Who does the monkey love:&lt;/b&gt;

 &lt;input type="text" name="monkey_love" size="30"&gt;

 &lt;/form&gt;
</pre>
<p>When you hit Return in the text field, the <code>onSubmit</code> handler gets called. It executes the function <code>monkeyLove()</code>, which changes the value in the text field.</p>
<p>If the <code>return false</code> wasn&#8217;t in the <code>onSubmit</code> handler, the function <code>monkeyLove()</code> would execute, changing the text field, but then the page would reload, changing the text field back to what it was. To stop this from happening, you need to have that <code>return false</code> in the <code>onSubmit</code>.</p>
<p>Here&#8217;s the <code>monkeyLove()</code> function for your perusal:</p>
<pre class="brush: js">function monkeyLove()

 {

   var who_it_is = window.document.text_entry_form.monkey_love.value;

   who_it_is = 'The monkey loves ' + who_it_is;

   window.document.text_entry_form.monkey_love.value = who_it_is;

 }
</pre>
<p>And here&#8217;s an example of the <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms9.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms9.html" rel="nofollow">same form</a> without the return false, just so you can see what happens.</p>
<p>Once you&#8217;ve convinced yourself of the merits of <code>return false</code>, it&#8217;s time to try a text-field exercise.</p>
<p><a name="Text_Field_Exercise"></a><br />
<h4> <span class="mw-headline">Text Field Exercise</span></h4>
<p>This exercise is an extension of one we did in Lesson 4. The exercise is to get this textarea to behave like a browser&#8217;s Location box. If you type in <code><a href="http://www.webmonkey.com/" class="external free" title="http://www.webmonkey.com/" rel="nofollow">http://www.webmonkey.com/</a></code> or just <code>www.webmonkey.com</code>, it&#8217;ll spawn a window that displays the Mattmarg.com Web site.</p>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms10.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/forms10.html" rel="nofollow">Click here</a>.</p>
<p>Try getting this to work before viewing source to see a solution. When you&#8217;re done, it&#8217;s time to move on to checkboxes and radio buttons.</p>
<p><a name="Checkboxes"></a><br />
<h4> <span class="mw-headline">Checkboxes</span></h4>
<p>Text fields and textareas are just two types of form elements. Others that we&#8217;ll look at in this lesson are checkboxes, radio buttons, and selects. Let&#8217;s discuss checkboxes first.</p>
<p>Checkboxes have one main property of interest: <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/checkbox1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/checkbox1.html" rel="nofollow">checked</a>.</p>
<p>If you have a form named <code>the_form</code> and a checkbox named <code>the_checkbox</code> you can see if the checkbox has been checked like this:</p>
<pre class="brush: js">var is_checked = window.document.the_form.the_checkbox.checked;

 if (is_checked == true)

 {

   alert("Yup, it's checked!");

 } else {

   alert("Nope, it's not checked.");

 }
</pre>
<p>As you can see, if a checkbox is checked, the checked property will be <code>true</code>. <code>true</code> is a built-in JavaScript datatype, so you don&#8217;t have to put it in quotes when checking it. If the checkbox is not checked, the checked property will be false (also a built-in datatype).</p>
<p>Just like you can read the checked property, you can set the checked property. Here&#8217;s an example of checking and <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/checkbox2.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/checkbox2.html" rel="nofollow">setting the checked property of a checkbox</a>.</p>
<p>Here&#8217;s the code for the above:</p>
<pre class="brush: js">&lt;form name="form_1"&gt;

 &lt;input type="checkbox" name="check_1"&gt;Checkbox 1

 &lt;/form&gt;

 &lt;a href="#" onClick="window.document.form_1.check_1.checked=true;

 return false;"&gt;Click to check Checkbox 1&lt;/a&gt;

 &lt;a href="#" onClick="window.document.form_1.check_1.checked=false;

 return false;"&gt;Click to uncheck Checkbox 1&lt;/a&gt;

 &lt;a href="#" onClick="alert(window.document.form_1.check_1.checked);

 return false;"&gt;Click to see the value of Checkbox 1&lt;/a&gt;
</pre>
<p>Notice that I&#8217;m sticking the <code>return false</code> in the <code>href</code>. It stops the page from bouncing around when you click on a link.</p>
<p>Checkboxes have one interesting event handler:<code>onClick</code>. When someone clicks on a checkbox, the <code>onClick</code> event handler goes into action. Here&#8217;s an example of it in use.</p>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/lightswitch.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/lightswitch.html" rel="nofollow">Click here to check out the Light Switch</a></p>
<p>This example introduces a few new things. First, there&#8217;s form that introduces the <code>onClick</code> checkbox handler:</p>
<pre class="brush: js">&lt;form name="form_2"&gt;

 &lt;input type="checkbox" name ="check_1"

 onClick="switchLight();"&gt;The Light Switch

 &lt;/form&gt;
</pre>
<p>When someone clicks on the checkbox, the <code>onClick</code> handler gets triggered and executes the <code>switchLight()</code> function. Here&#8217;s the <code>switchLight()</code> function (it&#8217;s in the header of this page):</p>
<pre class="brush: js">function switchLight()

 {

   var the_box = window.document.form_2.check_1;

   var the_switch = "";

   if (the_box.checked == false) {

     alert("Hey! Turn that back on!");

     document.bgColor='black';

   } else {

     alert("Thanks!");

     document.bgColor='white';

   }

 }
</pre>
<p>The interesting thing here is the first line:</p>
<pre class="brush: js"> var the_box = window.document.form_2.check_1;
</pre>
<p>This line assigns the checkbox object to a variable. This a handy way to cut down on your typing. It&#8217;s also a good way to pass objects as parameters to functions. We&#8217;ll see a lot more of that in later lessons.</p>
<p>That&#8217;s most of what you have to know about checkboxes. Now let&#8217;s learn about  radio buttons.</p>
<p><a name="Radio_Buttons"></a><br />
<h4> <span class="mw-headline">Radio Buttons</span></h4>
<p>Happily, radio buttons are almost exactly like checkboxes with respect to JavaScript. The only real difference is in the HTML. Checkboxes are on/off devices. If a checkbox is checked, you can uncheck it. If it&#8217;s unchecked, you can check it. Radio buttons are different. Once a radio button is on, it stays on until another one is selected. Then the first one goes off. Here&#8217;s a typical radio button set:</p>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/radio1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/radio1.html" rel="nofollow">Click here</a>.</p>
<p></p>
<p>As you can see, you can&#8217;t simply unselect a radio button, you have to choose a new one. With that in mind we can re-do the light switch example with two radio buttons instead of one checkbox:</p>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/radio2.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/radio2.html" rel="nofollow">Click here</a>.</p>
<p>This example looks very much like the checkbox example. The form is:</p>
<pre class="brush: js"> &lt;form name="form_1"&gt;

 &lt;input type="radio" name ="radio_1" onClick="offButton();"&gt;Light off

 &lt;input type="radio" name ="radio_2" onClick="onButton();" checked&gt;Light on

 &lt;/form&gt;
</pre>
<p>When the first radio button is clicked, the <code>offButton()</code> function is called. That function is:</p>
<pre class="brush: js">function offButton()

 {

   var the_box = window.document.form_1.radio_1;

   if (the_box.checked == true)

   {

     window.document.form_1.radio_2.checked = false;

     document.bgColor='black';

     alert("Hey! Turn that back on!");

   }

 }
</pre>
<p>This is pretty much just like the checkbox example earlier. The main difference is this line:</p>
<pre class="brush: js"> window.document.form_1.radio_2.checked = false;
</pre>
<p>This tells JavaScript to turn off the other button when this button has been clicked. The function that is run when the other button is clicked is similar to this one:</p>
<pre class="brush: js"> function onButton()

 {

   var the_box = window.document.form_1.radio_2;

   if (the_box.checked == true) {

     window.document.form_1.radio_1.checked = false;

     document.bgColor='white';

     alert("Thanks!");

   }

 }
</pre>
<p>There are a few more details about checkboxes and radio buttons, but those can wait until the next set of tutorials. Right now, let&#8217;s look at the last type of form element, selects.</p>
<p><a name="Selects"></a><br />
<h4> <span class="mw-headline">Selects</span></h4>
<p>Selects are the strangest of the form elements we&#8217;ll cover in this lesson. There are two primary kinds, pulldown selects and list selects. Here are examples of each:</p>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/select1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/select1.html" rel="nofollow">Click here</a>.</p>
<p>The thing that makes select objects strange is that the whole select is named, but none of the select&#8217;s options is. For example, the HTML for the first select looks like this:</p>
<pre class="brush: js"> &lt;select name="pulldown_1" size=1&gt;

 &lt;option&gt;probiscus

 &lt;option&gt;spider

 &lt;option&gt;lemur

 &lt;option&gt;chimp

 &lt;option&gt;gorilla

 &lt;option&gt;orangutan

 &lt;/select&gt;
</pre>
<p>Notice that the whole select is named <code>pulldown_1</code>, but the individual options aren&#8217;t named. This makes it difficult to access individual options.</p>
<p>Luckily, through the magic of arrays and objects, there&#8217;s a way to access and change the options of a select. If you wanted to change the second option of the pulldown menu, you&#8217;d type:</p>
<pre class="brush: js"> window.document.form_1.pulldown_1.options[1].text = 'new_text';
</pre>
<p>This works because the select element has an options property that is an array of all the select&#8217;s options. You can grab one of the options in the array and change its text property. Try it &#8211; <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/select2.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/select2.html" rel="nofollow">change the select</a> and then scroll up to see that the pulldown menu actually changed. The second option in the pulldown select should now be <code>*thau*</code>.</p>
<p>In addition to the options property, selects have a property called <code>selectedIndex</code>. When one option in a select has been chosen, the <code>selectedIndex</code> property of the select will be the array number of the selected option. To test this, select one of the options in the list select (the second one) and then <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/select3.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/select3.html" rel="nofollow">check the index</a>. Remember that the first option in the array is option <code>0</code>. The line I used to check this was:</p>
<pre class="brush: js"> &lt;a href="#" onClick="alert('index is:' + window.document.form_1.list_1.selectedIndex); return false;"&gt;check the index.&lt;/a&gt;
</pre>
<p>The form is named <code>form_1</code>, the list select is named <code>list_1</code>. To get the <code>selectedIndex</code>, I looked at <code>window.document.form_1.list_1.selectedIndex</code>. If you want, you can set the <code>selectedIndex</code> like this &#8230;</p>
<pre class="brush: js"> window.document.form_1.list_1.selectedIndex = 1;
</pre>
<p>&#8230;. and highlight the second option in the <code>list_1</code> select.</p>
<p>Once you know the index number of the selected option, you can find out what it is:</p>
<pre class="brush: js"> var the_select = window.document.form_1.list_1;

 var the_index = the_select.selectedIndex;

 var the_selected = the_select.options[the_index].text;
</pre>
<p>The <code>selectedIndex</code> property is great when you only have one option selected. What happens when you have more than one option selected? Well, that gets slightly stranger. If you want to know, here&#8217;s some information about <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/multiple_selects.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/multiple_selects.html" rel="nofollow">multiple selects</a>.</p>
<p>Just like the other form elements, the select element has a handler:<code>onChange()</code>. This handler gets called whenever there&#8217;s a change to the select. Here&#8217;s the example from Lesson 1 to show you how  <code>onChange</code> works with a select.</p>
<p><a name="onChange_in_Select_Form_Elements"></a><br />
<h4> <span class="mw-headline">onChange in Select Form Elements</span></h4>
<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/select4.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/select4.html" rel="nofollow">Play with this example</a> and then read the blow-by-blow description.</p>
<p>This is a fairly complicated JavaScript, so let&#8217;s go through it slowly. First, let&#8217;s look at the form itself (<b>note</b> that your browser might wrap that <code>onChange</code> line, but it should be on one line, no spaces, inyour code):</p>
<pre class="brush: js"> &lt;form name="the_form"&gt;

 &lt;select name="choose_category"

   onChange="swapOptions

   (window.document.the_form.choose_category.

   options[selectedIndex].text);"&gt;

 &lt;option selected&gt;Dogs

 &lt;option&gt;Fish

 &lt;option&gt;Birds

 &lt;/select&gt;

 &lt;select name="the_examples" multiple&gt;

 &lt;option&gt;poodle

 &lt;option&gt;puli

 &lt;option&gt;greyhound      .

 &lt;/select&gt;

 &lt;/form&gt;
</pre>
<p>This form has two elements, a pulldown select and a list select. The pulldown select has an <code>onChange</code> handler that calls a function called <code>swapOptions()</code>. <code>swapOptions()</code>, which is defined in the header, has one parameter &#8211; the selected animal type.</p>
<p>Now let&#8217;s check out the header. The first thing that happens is I define a few arrays:</p>
<pre class="brush: js"> var dogs = new Array("poodle","puli","greyhound");

 var fish = new Array("trout", "mackerel", "bass");

 var birds = new Array("robin", "hummingbird", "crow");
</pre>
<p>Notice that the arrays are named the same thing as the animals in the pulldown select. You&#8217;ll see why soon. Now let&#8217;s look at the function that gets called when the pulldown select is changed:</p>
<pre class="brush: js"> function swapOptions(the_array_name)

 {

   var numbers_select = window.document.the_form.the_examples;

   var the_array = eval(the_array_name);

   setOptionText(window.document.the_form.the_examples, the_array);

 }
</pre>
<p>The function definition includes one parameter:<code>the_array_name</code>. If you pulled the pulldown select to &#8220;Fish,&#8221; <code>the_array_name</code> will equal the string &#8220;Fish.&#8221;</p>
<p>The first line in the body of the function sets a variable to refer to the second form element, the list select.</p>
<p>The second line introduces something new:<code>eval()</code>. <code>eval()</code> is a little weird and better left for later lessons. The end result of the second line is that the variable <code>the_array</code> will equal one of the arrays defined earlier. If <code>the_array_name</code> is &#8220;Fish,&#8221; <code>the_array</code> will equal the Fish array. If you want a description of how this happens, <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/eval.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/eval.html" rel="nofollow">study up on eval</a>.</p>
<p>The third line of the function calls another function called <code>setOptionText()</code>. <code>setOptionText()</code> does the work of setting the values of the list select to the contents of <code>the_array</code>. Here it is:</p>
<pre class="brush: js"> function setOptionText(the_select, the_array)

 {

   for (loop=0; loop &lt; the_select.options.length; loop++)

   {

     the_select.options[loop].text = the_array[loop];

   }

 }
</pre>
<p>This function takes two parameters, a reference to a select element and an array. The first line of the function sets up a for loop, which loops through all the options in the select element. Remember that the options property of a select element is an array of all that select&#8217;s options. Because it&#8217;s an array, you can find out how many options are in a select using the length property of arrays. That&#8217;s how the loop works.</p>
<p>The first time you hit the loop, the loop variable equals 0. The body of the loop then reads:</p>
<pre class="brush: js"> the_select.options[0].text = the_array[0];
</pre>
<p>If you chose &#8220;Fish&#8221; in the pulldown, <code>the_array[0]</code> will be &#8220;trout,&#8221; so this line will change the first option in the list select to &#8220;trout.&#8221; The next time through the loop, loop will equal 1, and the second option in the list select will equal &#8220;mackerel.&#8221;</p>
<p>There&#8217;s one caveat to all this. When you change the text of an option, the size of the select won&#8217;t change. So if you change an option&#8217;s text to something really long, it&#8217;ll probably get cut off.</p>
<p>One way to get around this is to stretch out the select when you first go to it. For example, I did this:</p>
<pre class="brush: js"> &lt;option&gt;greyhound      .
</pre>
<p>Note the period I used to stretch out my select box. It&#8217;s sort of cheesy, but it works.</p>
<p>OK, that was a mouthful. If you understand how this example works, you understand a lot of JavaScript, and you&#8217;ll have no problem doing your <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/JST_homework5.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/JST_homework5.html" rel="nofollow">homework assignment</a> for this lesson. Once you&#8217;ve done the example and viewed source to see how I did it, go on to this lesson&#8217;s review.</p>
<p><a name="Review_of_Lesson_5"></a><br />
<h4> <span class="mw-headline">Review of Lesson 5</span></h4>
<p>Today we focused on forms and what you can do with them. We learned:</p>
<dl>
<dt> Forms and their elements can be named</p>
</dt>
<dd>You can refer to a form element like this:<code>window.document.form_name.element_name</code></p>
</dd>
<dt> Text field and textarea form elements have value properties</p>
</dt>
<dd>Refer to the value property like this:<code>window.document.form_name.element_name.value</code>; you can set the value by equating it to something, or get the value</p>
</dd>
<dt> Text field and textarea elements understand <code>focus()</code>, <code>blur()</code>, and <code>change()</code> event handlers</p>
</dt>
<dd>When you click on a text field or textarea, the focus event handler triggers; clicking out of one of these elements triggers the blur event handler; if you hit Tab or Return after changing an element, <code>onChange()</code> gets triggered</p>
</dd>
<dt> Forms have an <code>onSubmit()</code> event handler</p>
</dt>
<dd>To stop a form from reloading the page when you click on a Submit button, put <code>onSubmit="return false;"</code> in the <code>&lt;form&gt;</code> tag</p>
</dd>
<dt> Checkboxes and radio buttons have a checked property</p>
</dt>
<dd>You can check and uncheck checkboxes and radio buttons by changing their checked property</p>
</dd>
<dt> Checkboxes and radio buttons have an <code>onClick</code> event handler</p>
</dt>
<dd>Just like links, you can trigger functions when a user clicks on a checkbox or radio button</p>
</dd>
<dt> Selects have an options property that is an array of that select&#8217;s options</p>
</dt>
<dd>Just like any array, you can find the length of the options array by typing <code>window.document.form_name.select_name.options.length</code></p>
</dd>
<dt> You can change the text of an option by messing with its text property</p>
</dt>
<dd>To change the text of the first element of a select you&#8217;d type <code>window.document.form_name.select_name.options[0].text='new text';</code></p>
</dd>
<dt> You can find out which option was selected using the <code>selectedIndex</code> property of the select element</p>
</dt>
<dd><code>window.document.form_name.select_name.selectedIndex</code> returns the array number, you can then type <code>window.document.form_name.select_name.options[that_number].text</code> to find out what was actually selected</p>
</dd>
<dt> Selects have <code>onChange</code> event handlers</p>
</dt>
<dd>If someone changes the thing highlighted in a select, the <code>onChange</code> handler gets triggered</p>
</dd>
<dt> You can change the URL of a window using <code>window.location.replace('new url');</code></p>
</dt>
<dd>This was in the homework</p>
</dd>
<dt> You can create a new option for a select element using new Option</p>
</dt>
<dd>Since each option in the options array of a select is an object, you can use new to create a new Option; then you can stick this option into the options array</p>
</dd>
</dl>
<p>Today was packed, and it concludes this set of five lessons. We covered a lot of territory, from the basics of computer programming to a major portion of the JavaScript DOM. Not surprising, there&#8217;s still much more to learn. We only covered part of the DOM, and there are more than a few interesting JavaScript objects to study. We also didn&#8217;t talk too much about making our own objects, nor did we cover all the interesting properties of the Windows object.</p>
<p>Obviously this is a plug for the next set of lessons. So after you give yourself a minute to catch your breath, dive right into my <a href="/2010/02/Advanced_JavaScript_Tutorial" title="Tutorial:Advanced JavaScript Tutorial"> Advanced JavaScript Tutorial</a>.</p>
<p></p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/javascript_tutorial_-_lesson_5/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Manage Transactions in MySQL &#8211; Lesson 2</title>
        <link>http://www.webmonkey.com/2010/02/manage_transactions_in_mysql_-_lesson_2/</link>
        <comments>http://www.webmonkey.com/2010/02/manage_transactions_in_mysql_-_lesson_2/#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=783</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[In Lesson 1 of this tutorial, you leaned how to approximate transaction-like behavior with MyISAM tables. In this lesson, you&#8217;ll see how you can achieve real transactions with each of MySQL&#8217;s three transactional table types: BDB, InnoDB, and Gemini. But before I get to specifics surrounding each table, I need to revisit the notion of [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>In Lesson 1 of this tutorial, you leaned how to approximate transaction-like behavior with MyISAM tables. In this lesson, you&#8217;ll see how you can achieve real transactions with each of MySQL&#8217;s three transactional table types: BDB, InnoDB, and Gemini. But before I get to specifics surrounding each table, I need to revisit the notion of locking.

</p><p>Remember that MyISAM supports only table-level locks of two types: read locks and write locks. The transactional tables types offer more granular locking mechanisms: They can place locks on specific subsets of data. You&#8217;ll read more about each table&#8217;s locking mechanisms as I get to them in the following pages.
</p><br />
<span id="more-783"></span>

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

<ol>
<li><a href="#Using_BDB_Tables">Using BDB Tables</a></li>
<li><a href="#Working_with_Gemini_Tables">Working with Gemini Tables</a></li>
<li><a href="#Using_InnoDB_Tables">Using InnoDB Tables</a></li>
<li><a href="#The_Right_Choice_for_You">The Right Choice for You</a></li>
</ol>
</td></tr></tbody></table>

<p><a name="Working_with_MySQL.27s_Transactional_Table_Types"></a><h3> <span class="mw-headline">Working with MySQL&#8217;s Transactional Table Types </span></h3>

</p><p>Transactional table types can apply two types of locks. These are known as <i>shared locks</i> and <i>exclusive locks</i>. A shared lock is similar to the MyISAM read lock. When a client places a shared lock on data, other clients cannot alter that data with UPDATE or DELETE statements, but they can read the locked data via SELECTs. When a client gains an exclusive lock, other clients can neither alter the locked data via UPDATEs and DELETEs, nor can they read the data with SELECTs.

</p><p>Before we get to the actual code, there&#8217;s a MySQL setting I need to mention. MySQL contains an environment variable called <code>autocommit</code>. By default, autocommit is set to 1. When autocommit is set to 1, you cannot run transactions with any of the MySQL table types. In this mode, MySQL treats every SQL statement as its own transaction. To use groups of statements as transactions you need to turn autocommit mode off. So in all the code snippets that follow, you&#8217;ll notice that I start each with the line:

</p>



<pre class="brush: js"><code>SET autocommit=0;

</code>

</pre>

<p>OK, now on to the rest of the code, starting with BDB tables.

</p>

<a name="Using_BDB_Tables"></a><h3> <span class="mw-headline">Using BDB Tables </span></h3>

<p>To check if you have BDB tables available, run the following query:

</p>

<pre class="brush: js"> mysql&gt; show variables like '%have%';

 +---------------+-------+

 | Variable_name | Value |

 +---------------+-------+

 | have_bdb      | YES   |

 | have_innodb   | YES   |

 | have_isam     | YES   |

 | have_raid     | NO    |

 | have_symlink  | YES   |

 | have_openssl  | NO    |

 +---------------+-------+

 6 rows in set (0.00 sec)



</pre>

<p>If the first row in the listing says &#8220;no&#8221; you don&#8217;t have BDB installed. If you&#8217;ve got either InnoDB or Gemini, that&#8217;s fine &#8212; you can just use one of those, and I&#8217;ll talk about these tables soon (but please stick around, what you learn here will be useful there). If you decide to work with BDB tables, you can either install a MySQL-Max binary or recompile MySQL from source using the <code>--with-bdb</code> flag. BDB tables are available for most operating systems, including Windows, Linux, and Mac OS X.



</p><p>To create BDB tables, you can include <code>type=bdb</code> at the end of the CREATE statement. For example:

</p>

<pre class="brush: js">

 create table inventory(

     product_id int not null primary key,

     in_stock int not null

 )type=bdb;

</pre>

<p>Or, if you wish to move data from a MyISAM to a BDB table, you can run an ALTER statement, like so:

</p>

<pre class="brush: js"><code>

ALTER table table_name type=bdb;

</code>

</pre>

<p>Note that before you run an ALTER statement like this, you should backup the table. This type of ALTER statement actually dumps the table data, creates a new BDB table, and then loads the dumped data into the table. It&#8217;s an involved process that can fail, and if it does fail you want to be protected. Also be prepared to wait a while. If you&#8217;ve got large table, the dump-and-reload process can take a bit of time.

</p><p>BDB tables offer page-level locking. What&#8217;s a page? It&#8217;s a group of rows. The exact number of rows in a page varies depending on the number of rows in your tables, the operating system in use, and other factors. During a transaction, MySQL will apply a lock to a page worth of data. All other rows are unaffected by locks and ready to process whatever queries you throw at them.



</p><p>Page-level locking is a vast improvement over the table-level locking used by MyISAM tables. If only groups of rows &#8212; small subsets of whole tables &#8212; are locked by a single client, that means many clients can access different portions of the table simultaneously. In fact, it&#8217;s acceptable, even commonplace, to have many clients applying various locks to different portions of a table at the same time. The simultaneous access of data by different clients is usually referred to as <i>concurrency</i>. In database land (where the men have hairless backs and the women shapely legs) the greater the concurrency the better.

</p><p>One of the great things about transactions is that for the most part you don&#8217;t need to worry about manually applying the locks. Just start a transaction, run your SQL statements as you normally would, and the clever MySQL engine will mostly take care of the locking for you. Neat-o!

</p><p>Take a look at a simple transaction in a BDB table working with the following table:

</p>

<pre class="brush: js">mysql&gt; select * from inventory;

 +------------+----------+

 | product_id | in_stock |

 +------------+----------+

 |          1 |       24 |

 |          2 |       47 |

 +------------+----------+

 2 rows in set (0.05 sec)

</pre>

<p>To see the effect of a transaction, open up two copies of the command-line client. In one, start a transaction and run a SELECT on the first row:

</p>

<pre class="brush: js"> mysql&gt; set autocommit=0;

 mysql&gt; begin work;

 mysql&gt; select * from inventory where product_id=1;





</pre>

<p>Now in the second client, start a transaction and try to update the row 1.

</p>

<pre class="brush: js"> mysql&gt; set autocommit=0;

 mysql&gt; begin work;

 mysql&gt; update inventory set in_stock=23 where product_id=1;&lt;/code&gt;

</pre>

<p>You&#8217;ll see that the second client, the one trying to do the UPDATE, doesn&#8217;t respond. That&#8217;s because the first client has a share lock on that row. To release the lock, commit the transaction in the first client:

</p>

<pre class="brush: js"><code>mysql&gt; commit;</code>



</pre>

<p>You&#8217;ll notice that the second client is immediately freed to run the update operation.

</p><p>Take a look at the following improvement to the pseudo-code I used in Lesson 1 of the tutorial. Note the use of the BEGIN WORK-COMMIT/ROLLBACK syntax.

</p>

<pre class="brush: js"> set autocommit=0

 INSERT query into buyers table.

 run last_insert_id() to get user_id

 BEGIN WORK

 run INSERT into orders table

 run last_insert_id() to get order_id

 for each of the items in the order

     get quantity from the inventory table

     if quantity is &gt; 0

         insert into order_items table

         update inventory table subtracting the ordered item

     elseif quantity = 0

         set error variable

 if error variable is not set

     update orders table with the current order_id,

     adding the order_total



     COMMIT

 else

     ROLLBACK

     output error

</pre>

<p>Pretty nice, eh? Much cleaner than the MyISAM transaction-equivalent, I think. Keep in mind that you get all the ACID properties with this code if you&#8217;re using BDB tables. There is only one line of this code that doesn&#8217;t really work well and needs to be improved.

</p><p>Notice that for each item in the order, I first check the quantity from the <code>inventory</code> table. That quantity will come from a SELECT statement, something like <code>SELECT in_stock FROM inventory WHERE product_id=1</code>. But in most cases, the inventory is going to change just after this SELECT is run. If there&#8217;s sufficient quantity in stock, this person is going to buy the item and therefore the quantity listed in the table will decrement by one when the transaction is complete. You&#8217;d hate to see other clients get data that will be inaccurate in a matter of milliseconds.

</p><p>In a case like this, you&#8217;d be much better off putting an exclusive lock on a page containing the row in question until the transaction is complete. Remember, with an exclusive lock, all other clients are forbidden from even reading the locked rows. But unfortunately, BDB tables have no way to execute exclusive locks on pages of data. Only by instituting a table-wide write lock can you safeguard the data in the inventory table.



</p><p>When revised with the table-wide write lock the pseudo-code looks like this:

</p>

<pre class="brush: js"> set autocommit=0

 INSERT query into buyers table.

 run last_insert_id() to get user_id

 BEGIN WORK

 run INSERT into orders table

 run last_insert_id() to get order_id

 LOCK TABLES inventory WRITE

 for each of the items in the order

     get quantity from the inventory table

     if quantity is &gt; 0

         insert into order_items table

         update inventory table subtracting the ordered item

     elseif quantity = 0

         set error variable

 UNLOCK TABLES;

 if error variable is not set

     update orders table with the current order_id,

     adding the order_total



     COMMIT

 else

     ROLLBACK

</pre>

<p>The LOCK TABLES command here is a bit messy. But with the other two MySQL tables you won&#8217;t have to worry about this kind of lock.

</p>

<a name="Working_with_Gemini_Tables"></a><h3> <span class="mw-headline">Working with Gemini Tables </span></h3>

<p>It&#8217;s difficult to talk about Gemini tables without touching on the controversy surrounding the maker of the Gemini table, NuSphere. The NuSphere corporation is currently in a <a href="http://www.theregister.co.uk/content/4/24219.html" class="external text" title="http://www.theregister.co.uk/content/4/24219.html" rel="nofollow">legal dispute</a> with MySQL AB, the folks who code the MySQL core engine. The issues include copyright infringement and abuse of the GNU GPL. You may want to read further about these issues before choosing the Gemini table type.

</p><p>Gemini offers a more granular level of locking than BDB. With Gemini (and InnoDB, which I&#8217;ll discuss momentarily), you get the advantage of row-level locking. With Gemini, you can apply both share and exclusive locks to one row at a time. A row-level locking scheme will generally achieve higher concurrency than page-level locking, and much greater concurrency than table-level locking.



</p><p>You can check if you have Gemini installed by running <code>show variables like '%have%'</code>. And if you don&#8217;t have Gemini, you can get an installer that includes MySQL, PHP, mod_perl and other goodies from the <a href="http://www.nusphere.com/" class="external text" title="http://www.nusphere.com/" rel="nofollow">NuSphere website</a>. Note that the most current release of the Gemini table seems to have some bugs running on Windows 98, so if any of the following experiments crash your NuSphere MySQL installation on Windows 98, don&#8217;t blame me.

</p><p>To create Gemini tables include the <code>type=gemini</code> syntax at the end of the CREATE statement, and to transfer a current table to Gemini, run an ALTER TABLE query. The same caveats I mentioned for BDB apply here. For example:

</p>

<pre class="brush: js">	 create table inventory(

     product_id int not null primary key,

     in_stock int not null

 )type=gemini;





 ALTER table table_name type=gemini;

</pre>

<p>Unlike BDB, Gemini tables implement both shared and exclusive locks. If a thread runs an UPDATE or DELETE statement on a row, Gemini will place an exclusive lock on that row, preventing other threads from either reading or altering the locked row until the transaction is complete. If you think about it, this makes perfect sense. If a row is about to change, other threads should be protected from seeing potentially inaccurate data.

</p><p>If a thread runs a SELECT statement on a row, a shared lock will be placed on that row so other threads can read the row with SELECTs but they won&#8217;t be able to alter the row with UPDATE or DELETE statements.

</p><p>You can do some quick experiments with Gemini tables to see how this locking works. Assume you have the following Gemini table.

</p>



<pre class="brush: js">mysql&gt; select * from inventory;

 +------------+----------+

 | product_id | in_stock |

 +------------+----------+

 |          1 |       24 |

 |          2 |       47 |

 +------------+----------+

 2 rows in set (0.05 sec)

</pre>

<p>Open two copies of the command-line client. In the first start a transaction, then run a SELECT on row 1.

</p>

<pre class="brush: js"> mysql&gt; set autocommit=0;

 mysql&gt; begin work;

 mysql&gt; SELECT * FROM inventory WHERE product_id=1;

</pre>

<p>Now in the second client, start a transaction and try two statements, a SELECT and an UPDATE.

</p>



<pre class="brush: js"> mysql&gt; set autocommit=0;

 mysql&gt; begin work;

 mysql&gt; SELECT * FROM inventory WHERE product_id=1;

 mysql&gt; UPDATE inventory SET in_stock=23 WHERE product_id=1;

</pre>

<p>You&#8217;ll see that the SELECT executes immediately, but the UPDATE doesn&#8217;t execute. The UPDATE won&#8217;t execute until you COMMIT or ROLLBACK the transaction started in the first client, which releases the shared lock.

</p><p>You can re-run this experiment trying an UPDATE in the first client. You&#8217;ll notice that the second client is prevented from reading the locked row with a SELECT. When a client runs an UPDATE statement, it gets an exclusive lock on that row.

</p><p>When I discussed BDB tables, I pointed out that at times when inventory numbers are changing fast, you need a SELECT to obtain an exclusive lock so your users access the most up-to-date information. When you run a SELECT on the <code>inventory</code> table to find out the number of items currently in stock, you&#8217;re better off locking out all other threads from reading that row because that number is likely to change very quickly &#8212; an UPDATE will almost always follow that SELECT.



</p><p>With Gemini tables, you can get a exclusive lock while running a SELECT by using the FOR UPDATE keywords. For example.

</p>

<pre class="brush: js"><code>SELECT * FROM inventory WHERE product_id=1 FOR UPDATE</code>

</pre>

<p>Using this added power, the shopping cart pseudo-code can be re-written like so:

</p>

<pre class="brush: js"> set autocommit=0

 INSERT query into buyers table.

 run last_insert_id() to get user_id

 BEGIN WORK

 run INSERT into orders table

 run last_insert_id() to get order_id

 for each of the items in the order

     get quantity from the inventory

     table with SELECT ... FOR UPDATE



     if quantity is &gt; 0

         insert into order_items table

         update inventory table subtracting the ordered item

     elseif quantity = 0

         set error variable

 if error variable is not set

     update orders table with the current order_id,

     adding the order_total



     COMMIT

 else

     ROLLBACK

</pre>

<p>This is much cleaner, and much safer, than non-transactional code. And you can do something similar with InnoDB tables.

</p><p><br />

</p>

<a name="Using_InnoDB_Tables"></a><h3> <span class="mw-headline">Using InnoDB Tables </span></h3>



<p>InnoDB offers row-level locking and works on a wide variety of operating systems, including most UNIX variants, MacOS X, and Windows. This table type is now included by default in most MySQL installations, so if you get current binary from <a href="http://www.mysql.com/" class="external text" title="http://www.mysql.com/" rel="nofollow">mysql.com</a>, you&#8217;ll have InnoDB tables. You can check if you have InnoDB installed by running <code>SHOW VARIABLES LIKE '%have%';</code>.

</p><p>You can create InnoDB tables by using <code>type=innodb</code> in the CREATE statement or by running an ALTER TABLE command. For example:

</p>

<pre class="brush: js"> create table inventory(

     product_id int not null primary key,

     in_stock int not null

 )type=innodb;





 ALTER table table_name type=innodb;

</pre>

<p>The InnoDB transaction model is not quite as straightforward as the Gemini model. If you don&#8217;t understand how InnoDB implements transactions, you could end up with some serious problems with your data.

</p><p>InnoDB uses what&#8217;s called a <i>multi-versioning concurrency</i> model. Essentially, this means that each transaction is locked to a view of the data at a specific point in time. When a thread initiates a transaction, InnoDB gets a snapshot of the data based on the exact moment the transaction started. To understand how this works, take a look at the following example. You have a simple InnoDB table:



</p>

<pre class="brush: js"> mysql&gt; select * from inventory;

 +------------+----------+

 | product_id | in_stock |

 +------------+----------+

 |          1 |       24 |

 |          2 |       47 |

 +------------+----------+

</pre>

<p>In one copy of the command line client, you start a transaction:

</p>

<pre class="brush: js"> mysql&gt; set AUTOCOMMIT=0;

 mysql&gt; begin work;

</pre>

<p>This thread now has a snapshot of the table seen above. If you were to then open another copy of the client and start another transaction, that second client would have the same snapshot of the same table. At this point, the first client runs an UPDATE statement and commits the transaction.

</p>



<pre class="brush: js"><code>mysql&gt; UPDATE inventory set in_stock=23 WHERE product_id=1

mysql&gt; commit;</code>

</pre>

<p>Even after this COMMIT, the second client will not see the results of the UPDATE. The second client receives a snapshot of the data at the moment its transaction began. Until the second client finishes its transaction (with a COMMIT or ROLLBACK), it will not be able to view the changes implemented by other threads that took place while the transaction was active.

</p><p>Things get really sticky if the second client was also running an UPDATE on the same row. If the first and second clients start their transactions at the same time, they would get the same snapshots of data. The first client would run an update, <code>WHERE order_id=3</code>, but the second client would be unaware of the change. The second client could then run its own update, <code>UPDATE WHERE order_id=3</code>. After both of these clients commit their transactions, only one of the values can survive. As it turns out, the last one to COMMIT wins.

</p><p>As you can see, this is potentially a dangerous situation. If you&#8217;re not careful, some of your threads could see out-of-date information.

</p><p>But there are steps you can take to make sure the rows obtained by your transactions are up to date. It may not surprise you that staying current involves locking. With InnoDB, threads can apply the same types of locks that were available in Gemini.

</p><p>In Gemini tables, when you run a SELECT within a transaction, a share lock is placed on the rows read by the SELECT. However, by default, InnoDB does not place any locks on rows during a SELECT. But you can let InnoDB know that you want to obtain a share lock by the adding the clause LOCK IN SHARE MODE at the end of a SELECT.

</p><p>When a thread issues a SELECT with a LOCK IN SHARE MODE clause, InnoDB goes beyond the snapshot of data taken at the start of the transaction and looks for the latest committed data. If another thread is operating on that data (via an UPDATE, DELETE, or another LOCK IN SHARE MODE), the first thread won&#8217;t be able to obtain the share lock and will wait until the other thread finishes its transaction and releases its locks. By attempting to obtain the share lock and receiving the latest committed data, the LOCK IN SHARE MODE clause ensures that the data read by a SELECT will be accurate and up to date.



</p><p>If you&#8217;d like to see how this works, try the following, using the same table shown above. In one client, start a transaction and then run an UPDATE statement:

</p>

<pre class="brush: js"> mysql&gt; set autocommit=0;

 mysql&gt; begin work;

 mysql&gt; update inventory set in_stock=22 where product_id=1;

</pre>

<p>Now in the second client, run two different SELECTs. The first you will run without the LOCK IN SHARE MODE clause. Try <code>SELECT * FROM inventory</code>. This will execute immediately, but the data is potentially inaccurate because there&#8217;s no telling if the first client will COMMIT or ROLLBACK the transaction. If you alter that SELECT statement to include the LOCK IN SHARE MODE clause, the client will not respond until the first client issues a COMMIT or ROLLBACK.

</p><p>Threads can obtain exclusive locks in SELECT statements by using the same FOR UPDATE clause that is used with Gemini.

</p><p>The pseudo-code shown for Gemini will also work for InnoDB tables. But be very careful when writing your SELECT statements for InnoDB. You want to make sure you&#8217;re getting the latest, most accurate data.

</p>



<a name="The_Right_Choice_for_You"></a><h3> <span class="mw-headline">The Right Choice for You </span></h3>

<p>At this point, InnoDB is the most logical choice for most. It offers row-level locking, is available on most every operating system, and is getting a lot of support from MySQL AB. InnoDB is also the first table type to enforce foreign key constraints. But if you&#8217;re working with an installation that has support of one of the other transactional tables, both of those will work just fine.

</p><p>When you decide on the table type you wish to work with, you&#8217;ll have more technical matters to consider. You should read everything the MySQL manual has to say on the table type you end up using.

</p><p>Pay especially careful attention to your logs. The transactional tables use logs to help recover from crashes. If a hard-disk failure causes a crash on your system, you could be in trouble if your logs are on the same hard disk as your MySQL data.

</p><p>If you&#8217;re unhappy with the types of locks initiated by specific statements, you can adjust the locking behavior of Gemini and BDB table with the <a href="http://www.mysql.com/doc/S/E/SET_TRANSACTION.html" class="external text" title="http://www.mysql.com/doc/S/E/SET_TRANSACTION.html" rel="nofollow">SET TRANSACTION command</a>. I won&#8217;t cover it in detail here because the defaults discussed in this tutorial are usually preferable. Note that InnoDB tables are unaffected by SET TRANSACTION command.

</p><p>Transactions are a great improvement to the MySQL database. If you&#8217;re not using them now, consider using them in the future. Because when that backhoe works it way through your power cord, you&#8217;ll be awfully glad you did.

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

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