<?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"
	>

<channel>
	<title>Fotiweb</title>
	<atom:link href="http://www.fotiweb.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fotiweb.com</link>
	<description>All things Foti!</description>
	<pubDate>Wed, 07 Jul 2010 13:32:35 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Chrome 5 is the #4 Browser in North America</title>
		<link>http://www.fotiweb.com/2010/07/07/chrome-5-is-the-4-browser-in-north-america/</link>
		<comments>http://www.fotiweb.com/2010/07/07/chrome-5-is-the-4-browser-in-north-america/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 13:32:35 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=108</guid>
		<description><![CDATA[

Source: StatCounter Global Stats - Browser Version Market Share

And it will soon be the #4 browser worldwide:


Source: StatCounter Global Stats - Browser Version Market Share

]]></description>
			<content:encoded><![CDATA[<div id="browser_version-na-daily-20100706-20100706-bar" width="520" height="350" style="width:520px; height: 350px;"></div>
<p><!-- You may change the values of width and height above to resize the chart -->
<p>Source: <a href="http://gs.statcounter.com/#browser_version-na-daily-20100706-20100706-bar">StatCounter Global Stats - Browser Version Market Share</a></p>
<p><script type="text/javascript" src="http://www.statcounter.com/js/FusionCharts.js"></script><script type="text/javascript" src="http://gs.statcounter.com/chart.php?browser_version-na-daily-20100706-20100706-bar"></script></p>
<p>And it will soon be the #4 browser worldwide:</p>
<div id="browser_version-ww-daily-20100706-20100706-bar" width="520" height="350" style="width:520px; height: 350px;"></div>
<p><!-- You may change the values of width and height above to resize the chart -->
<p>Source: <a href="http://gs.statcounter.com/#browser_version-ww-daily-20100706-20100706-bar">StatCounter Global Stats - Browser Version Market Share</a></p>
<p><script type="text/javascript" src="http://www.statcounter.com/js/FusionCharts.js"></script><script type="text/javascript" src="http://gs.statcounter.com/chart.php?browser_version-ww-daily-20100706-20100706-bar"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2010/07/07/chrome-5-is-the-4-browser-in-north-america/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Geometry at Work</title>
		<link>http://www.fotiweb.com/2010/06/30/geometry-at-work/</link>
		<comments>http://www.fotiweb.com/2010/06/30/geometry-at-work/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 14:56:44 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[NH Academie of Dance]]></category>

		<category><![CDATA[geometry]]></category>

		<category><![CDATA[heart]]></category>

		<category><![CDATA[nhad]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=99</guid>
		<description><![CDATA[Each year, I am tasked with building props for my wife&#8217;s dance studio, NH Academie of Dance.  This year, I had to build two giant hearts that were at least 10&#8242; tall each.  The original plan was that these hearts would consist of a wooden border about 6&#8243; wide with white fabric stretched [...]]]></description>
			<content:encoded><![CDATA[<p>Each year, I am tasked with building props for my wife&#8217;s dance studio, <a href="http://www.nhadance.com">NH Academie of Dance</a>.  This year, I had to build two giant hearts that were at least 10&#8242; tall each.  The original plan was that these hearts would consist of a wooden border about 6&#8243; wide with white fabric stretched across the middle.</p>
<p>First, I decided that I was going to use <a href="http://en.wikipedia.org/wiki/Medium-density_fibreboard">MDF</a> (Medium Density Fibreboard) for the heart border.  MDF is often used for making furniture, school projects, etc., and it seemed like it would be a good choice for my needs.  Strong, yet flexible.</p>
<p>The next step was to draw the heart to scale.  I needed to be able to recreate the hearts on a large scale, so just drawing it freehand wasn&#8217;t really an option.  It was time to dust off my high school geometry knowledge.  Using a protractor and 45 degree triangle, I drew a half circle with a 2.5&#8243; radius on a 45 degree angle (my original plans were hand drawn, but I&#8217;ve included some images below that I recreated on the computer for this post&#8230; the originals seemed more impressive to me&#8230; there&#8217;s just something about getting highly precise drawings by hand that looks more impressive).  This would be the top left side of the heart.</p>
<p><a href="http://www.fotiweb.com/wp-content/heart-top-left.png"><img src="http://www.fotiweb.com/wp-content/heart-top-left.png" alt="Top left side of heart" title="Top left side of heart" width="396" height="396" class="aligncenter size-full wp-image-102" /></a></p>
<p>Next, I created a mirror image of this by creating another half circle on a 135 degree angle.  This angle was the tangent created at the rightmost edge of the first half circle.  This gave me the top right side of the heart.</p>
<p><a href="http://www.fotiweb.com/wp-content/heart-top-right.png"><img src="http://www.fotiweb.com/wp-content/heart-top-right.png" alt="Top right side of heart" title="Top right side of heart" width="500" height="347" class="aligncenter size-full wp-image-103" /></a></p>
<p>Next, I extended the tangents on the outer edge of each circle until they intersected to form the bottom of the heart.  </p>
<p><a href="http://www.fotiweb.com/wp-content/heart3.png"><img src="http://www.fotiweb.com/wp-content/heart3.png" alt="Bottom of heart" title="Bottom of heart" width="500" height="500" class="aligncenter size-full wp-image-104" /></a></p>
<p>I needed to know the lengths of the bottom pieces of the heart, so I took a look at what I knew already.</p>
<ol>
<li>The angles where the tangent lines crossed were all 90 degree angles so when dividing the heart in half down the middle, I get two right triangles, each with 45 degree angles for both of its complementary angles.</li>
<li>If the complementary angles of a right triangle have the same measure, then the legs of the triangle opposite those angles have the same length.  I knew that the radius of my arc was 2.5&#8243;, which meant that the diameter was 5&#8243;.  Since the two 45 degree angles are equal, the lengths of both legs must therefore be 5&#8243;. I now had a scale version of my heart shape.</li>
</ol>
<p><a href="http://www.fotiweb.com/wp-content/heart4.png"><img src="http://www.fotiweb.com/wp-content/heart4.png" alt="Heart with measurements" title="Heart with measurements" width="500" height="500" class="aligncenter size-full wp-image-105" /></a></p>
<p>Looking back at it, I now see a much easier approach that I could have taken.  I could have started by drawing a square, then draw the arcs using half the length of one side of the square as the radius, from the midpoint of one of the sides.  Then I could have rotated the whole thing 45 degrees and it&#8217;s the same heart.</p>
<p>At this point, I had the basic outer edge of my heart shape.  There was to be some overlap on the bottom (giving it an almost ribbon-like appearance), and at the top-middle of the heart where the arcs met.  For the top overlap, I simply extended each arc along it&#8217;s tangent for about 9&#8243; (since the width of the border was 6&#8243;, that gave about 3&#8243; of overlap).  For the bottom, I started out by creating an arc whose center was on one of the tangent lines (extending the tangents farther down), but in the end I decided that those could be a bit more freehand.</p>
<p>I was quite happy with the end result, and glad I still remembered some of those Geometry lessons from high school.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2010/06/30/geometry-at-work/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Web Hosting</title>
		<link>http://www.fotiweb.com/2010/05/12/web-hosting/</link>
		<comments>http://www.fotiweb.com/2010/05/12/web-hosting/#comments</comments>
		<pubDate>Wed, 12 May 2010 17:09:14 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[hosting]]></category>

		<category><![CDATA[hostmysite]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=97</guid>
		<description><![CDATA[I&#8217;ve been a loyal customer of HostMySite.com for many years. However, since they acquired Hosting.com, I feel the quality of customer support has been not quite as good as it once was.  Also, the cost, while not unreasonable, is a little higher than I&#8217;d like to be paying (given the rough economy).
I&#8217;ve been considering [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been a loyal customer of <a href="http://HostMySite.com">HostMySite.com</a> for many years. However, since they acquired Hosting.com, I feel the quality of customer support has been not quite as good as it once was.  Also, the cost, while not unreasonable, is a little higher than I&#8217;d like to be paying (given the rough economy).</p>
<p>I&#8217;ve been considering moving to a new host.  I&#8217;ve heard good things about <a href="http://jaguarpc.com">JaguarPC.com</a>, and the pricing looks great ($5 / month if I go with a 3 year plan).</p>
<p>Got any web hosts you&#8217;d like to suggest?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2010/05/12/web-hosting/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Google Voice Turns 1 But Still Needs Fixing</title>
		<link>http://www.fotiweb.com/2010/03/12/google-voice-turns-1-but-still-needs-fixing/</link>
		<comments>http://www.fotiweb.com/2010/03/12/google-voice-turns-1-but-still-needs-fixing/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 14:26:46 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Google Voice]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=91</guid>
		<description><![CDATA[http://googlevoiceblog.blogspot.com/2010/03/google-voice-turns-1.html
We wanted to thank you for letting us know what you think, and we hope you like the improvements we&#8217;ve made since then.
Many users have voiced their complaint about certain missing call screening features.  In particular, I&#8217;m referring to the following:

Once a call screening name has been recorded, there is no way to delete [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://googlevoiceblog.blogspot.com/2010/03/google-voice-turns-1.html">http://googlevoiceblog.blogspot.com/2010/03/google-voice-turns-1.html</a></p>
<blockquote><p>We wanted to thank you for letting us know what you think, and we hope you like the improvements we&#8217;ve made since then.</p></blockquote>
<p>Many users have voiced their complaint about certain missing call screening features.  In particular, I&#8217;m referring to the following:</p>
<ol>
<li>Once a call screening name has been recorded, there is no way to delete it or force it to be re-recorded.  So if you friend calls you and hears the prompt to record his name and he says &#8220;What the F***?&#8221; as his name, that is what you will hear every time that person calls you.  This is especially not good if you have little ones that might answer the phone.</li>
<li>The proposed solution to that problem is not a solution at all.  Add that person to your contacts and their name will be &#8220;read&#8221; instead.  This is much more of a hack than a fix, and from what I&#8217;ve read it doesn&#8217;t even always work.</li>
<li>Suppose the person is calling via a business that has a phone system that gives every outbound call the same caller id?  For example, say my boss calls me from work and records his name.  Now any time anyone calls me from that company, I will hear my bosses name even though it could be any number of people calling me.</li>
</ol>
<p>It seems like a terrible oversight that users can not manage the recordings.   Also, it should be configurable to force a recording every time for certain numbers (which would solve the 3rd problem listed above).</p>
<p>In my opinion, Google Voice still has a long way to go, and it&#8217;s disappointing that it has been live for a year with not even a word of fixing these issues.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2010/03/12/google-voice-turns-1-but-still-needs-fixing/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tasha Bit Me, and That Really Hurts</title>
		<link>http://www.fotiweb.com/2010/03/03/tasha-bit-me-and-that-really-hurts/</link>
		<comments>http://www.fotiweb.com/2010/03/03/tasha-bit-me-and-that-really-hurts/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 15:24:52 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=88</guid>
		<description><![CDATA[As I learned last night, it is never a good idea to try hand feeding a pill to a dog when that dog is still chewing on food.
As I stuck my left hand in her mouth (to hold it open while I popped the pill in with my right hand), I had my thumb too [...]]]></description>
			<content:encoded><![CDATA[<p>As I learned last night, it is never a good idea to try hand feeding a pill to a dog when that dog is still chewing on food.</p>
<p>As I stuck my left hand in her mouth (to hold it open while I popped the pill in with my right hand), I had my thumb too far back near the molars.  As she continued chewing her food, she punctured right through the middle of my thumb&#8217;s fingernail with one of her pointy premolars.  Blood instantly started flowing out of the hole, and the pain was intense.  I washed it with antibacterial soap, and ran it under cold water for several minutes.  Eventually the blood stopped flowing and I could see the small, purplish splotch in the center of my nail surrounding the crack.  I put some antibiotic ointment on the wound and wrapped a bandaid around it.</p>
<p>A small amount of blood continues to make its way out of the hole in my nail today.  I&#8217;m not sure yet whether that nail is going to fall off or not.  A dull, throbbing pain continues, but it&#8217;s bearable.  My impatience cost me, but I&#8217;ve learned my lesson.  It was my fault, but I won&#8217;t make that mistake again.</p>
<p><a href="http://www.youtube.com/watch?v=HE4FJL2IDEs">http://www.youtube.com/watch?v=HE4FJL2IDEs</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2010/03/03/tasha-bit-me-and-that-really-hurts/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Internet Explorer 6: You Had a Good Run&#8230; Now Please Die</title>
		<link>http://www.fotiweb.com/2010/02/16/internet-explorer-6-you-had-a-good-run-now-please-die/</link>
		<comments>http://www.fotiweb.com/2010/02/16/internet-explorer-6-you-had-a-good-run-now-please-die/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 21:49:42 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=86</guid>
		<description><![CDATA[A recent look at some analytics showed that 66.82% of visitors to the NH Academie of Dance website were using Internet Explorer (IE).  Of those users, 26.04% were using IE 6, which was 17.4% of the total visits.  You people still using IE 6 (and you know who you are), it&#8217;s time to [...]]]></description>
			<content:encoded><![CDATA[<p>A recent look at some analytics showed that 66.82% of visitors to the <a href="http://www.nhadance.com">NH Academie of Dance website</a> were using Internet Explorer (IE).  Of those users, 26.04% were using IE 6, which was 17.4% of the total visits.  You people still using IE 6 (and you know who you are), it&#8217;s time to upgrade!  Several Web Applications are dropping support for IE 6, and I&#8217;d like nothing better than drop support for it as well.  So please&#8230; I&#8217;m begging you&#8230; help us put IE 6 to rest, and upgrade to a better browsing experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2010/02/16/internet-explorer-6-you-had-a-good-run-now-please-die/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Comparing JavaScript Frameworks</title>
		<link>http://www.fotiweb.com/2009/12/17/comparing-javascript-frameworks/</link>
		<comments>http://www.fotiweb.com/2009/12/17/comparing-javascript-frameworks/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 21:05:16 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[libraries]]></category>

		<category><![CDATA[speed]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=83</guid>
		<description><![CDATA[While reading the YUI 3 forum, I came upon some links which perform some tests using multiple libraries.  I found them very useful and will probably use them as a reference from time to time:
http://yuilibrary.com/~msweeney/yui-tests/taskspeed/
http://yuilibrary.com/~msweeney/yui-tests/slickspeed/
]]></description>
			<content:encoded><![CDATA[<p>While reading the <a href="http://yuilibrary.com/forum/viewtopic.php?f=18&#038;t=1482">YUI 3 forum</a>, I came upon some links which perform some tests using multiple libraries.  I found them very useful and will probably use them as a reference from time to time:<br />
<a href="http://yuilibrary.com/~msweeney/yui-tests/taskspeed/">http://yuilibrary.com/~msweeney/yui-tests/taskspeed/</a><br />
<a href="http://yuilibrary.com/~msweeney/yui-tests/slickspeed/">http://yuilibrary.com/~msweeney/yui-tests/slickspeed/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2009/12/17/comparing-javascript-frameworks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cross Browser XMLHttpRequest</title>
		<link>http://www.fotiweb.com/2009/11/19/cross-browser-xmlhttprequest/</link>
		<comments>http://www.fotiweb.com/2009/11/19/cross-browser-xmlhttprequest/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 15:12:53 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[IE6]]></category>

		<category><![CDATA[MSXML]]></category>

		<category><![CDATA[XMLHTTP]]></category>

		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=80</guid>
		<description><![CDATA[I recently did a lot of investigating around the best way to create an XMLHttpRequest, as various resources on the web use slightly different methods.  Newer browsers (Chrome, Firefox, IE7+, Opera, and Safari) all have a native XMLHttpRequest object, so the exception is really IE versions less than 7.
Internet Explorer 5, 5.5, and 6 [...]]]></description>
			<content:encoded><![CDATA[<p>I recently did a lot of investigating around the best way to create an <em>XMLHttpRequest</em>, as various resources on the web use slightly different methods.  Newer browsers (Chrome, Firefox, IE7+, Opera, and Safari) all have a native XMLHttpRequest object, so the exception is really IE versions less than 7.</p>
<p>Internet Explorer 5, 5.5, and 6 all support XMLHttpRequest by means of an ActiveXObject.  But there are various versions of MSXML, and it was not clear to me which versions should be used, and in which order they should be declared.  Microsoft <a href="http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx">recommended</a> some versions, but their recommendation was 3 years old and I wasn&#8217;t sure if it was still applicable (or applicable at all when using MSXML for creating XMLHTTP objects).  It turns out that it was.</p>
<p>Initially I wanted to support the widest range of browsers, including IE5 and IE5.5.  However, those versions of IE are no longer supported by Microsoft, so why should I try and support them?  I have no way to test in those versions.  More research suggested that IE5 and IE5.5 account for only about .02% of browser market share (2 people out of 10,000) from <a href="http://gs.statcounter.com/#browser_version-ww-monthly-200908-200910-bar">August 2009 - October 2009</a>.  It doesn&#8217;t make sense to try and support IE5.x, which means there is no need to support the legacy Microsoft.XMLHTTP ActiveXObject.</p>
<p>That just leaves IE6.  IE6 still has considerable market share, so I do want to support it.  IE6 shipped with MSXML 3.0, which is the &#8220;fallback&#8221; version to use recommended by Microsoft.  Previous versions of MSXML are <a href="http://en.wikipedia.org/wiki/MSXML">no longer supported</a> by Microsoft, so MSXML 3.0 will be my fallback version.  The recommended version is MSXML 6.0 (note, it is NOT recommended to use MSXML 5.0 or MSXML 4.0).</p>
<p>So now I&#8217;m going to be working with a set of 3 possible objects:</p>
<ol>
<li>a native XMLHttpRequest object</li>
<li>an MSXML 6.0 XMLHTTP ActiveXObject (IE6 only)</li>
<li>an MSXML 3.0 XMLHTTP ActiveXObject (IE6 only, when MSXML 6.0 not available)</li>
</ol>
<p>To see how I decided to format that code, visit:<br />
<a href="http://www.webmasterworld.com/javascript/4027629.htm">http://www.webmasterworld.com/javascript/4027629.htm</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2009/11/19/cross-browser-xmlhttprequest/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Dependent Lists and Progressive Enhancement</title>
		<link>http://www.fotiweb.com/2009/07/02/dependent-lists-and-progressive-enhancement/</link>
		<comments>http://www.fotiweb.com/2009/07/02/dependent-lists-and-progressive-enhancement/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 11:54:05 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[progressive enhancement]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=54</guid>
		<description><![CDATA[I recently stumbled across a newsgroup post where someone needed dependent list boxes that let users select a car make from one list box and a second list box would be populated with car models.  He wanted to use AJAX to get the list of models from the server, but also wanted a solution [...]]]></description>
			<content:encoded><![CDATA[<p>I recently stumbled across a newsgroup post where someone needed dependent list boxes that let users select a car make from one list box and a second list box would be populated with car models.  He wanted to use AJAX to get the list of models from the server, but also wanted a solution that would work for users that didn&#8217;t have JavaScript (particularly, mobile device users).  My suggestion was to use <strong>progressive enhancement</strong>.  The end result can be viewed at <a href="http://www.fotiweb.com/samples/dependent-list-box/">http://www.fotiweb.com/samples/dependent-list-box/</a>, though some of this solution is PHP based (see below for that code).</p>
<p>My suggestion was to create a <em>web service</em> that would take a car make and return a list of models.  He could interact with this service via an AJAX call, parse the results, and populate the list box with the results.  Alternatively, his server side processing could determine if a make had been selected, and if so call the service to get the list and populate the list box that way.</p>
<p>I started by creating a basic HTML form:</p>
<pre name="code" class="php">
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" &gt;
&lt;style type="text/css"&gt;
select {
    width: 15em;
}
&lt;title&gt;Untitled&lt;/title&gt;
&lt;body&gt;
<div>
<form action="" method="GET" id='getMakeModel'>
<div>
<select id="make" name="make" size="10">
    &lt;?php
    echo $makeOptionList;
    ?&gt;
    </select>

    <!--
        If JavaScript is enabled, this submit button will be removed
        and replaced with AJAX methods to get the models.
    -->
<input type="submit" id="getmodels" name="getmodels" value="Get Models" />
<select id="models" size="10">
    &lt;?php
    echo $modelsOptionList;
    ?&gt;
    </select>
</div>
</form>
</div>

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>I used placeholders where the list options will be.</p>
<p>Next, I created the web service at .  Here&#8217;s what that service looks like:</p>
<pre name="code" class="php">
&lt;?php
// This example returns just a simple comma separated list.
// A real world example would probably look up values from a
// database and might return a JSON or XML string with the
// results. This is just a proof of concept.
if (!isset($_GET['make'])) {
    // Exit nicely
    exit(0);
}
$make = $_GET['make'];
switch ($make) {
    case 'Ford':
        echo 'Focus,Explorer';
        break;
    case 'Nissan':
        echo 'Sentra';
        break;
    case 'Toyota':
        echo 'Prius,Tundra';
        break;
    default:
        echo '';
        break;
}
exit(0);
?&gt;
</pre>
<p>Next I needed to create the PHP behind my form page.  This PHP populates the vehicle makes and if the user has selected a make and clicked the &#8220;Get Models&#8221; button, will also populate the models by making a <strong>curl</strong> request to the web service.</p>
<pre name="code" class="php">
&lt;?php
// The 'makes' list might be populated from a database
$makes = array('Ford', 'Nissan', 'Toyota');
// 'models'
$models = array();
// 'selectedMake' The make selected by the user (if any)
$selectedMake = '';

// Check whether the make has been submitted
if (array_key_exists('getmodels', $_GET)) {
    if ( isset($_GET['make']) ) {
        $selectedMake = $_GET['make'];
        // Request model values for the selected
        $ch = curl_init("http://www.fotiweb.com/samples/dependent-list-box/getModels/?make=$selectedMake");
        // Return the transfer as a string
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // $output contains the output string
        $models = curl_exec($ch);
        // Close the curl resource
        curl_close($ch);
        // Convert results to array
        $models = explode(',', $models);
    }
}

// Format variables for HTML output
$makeOptionList = '';
$modelsOptionList = '';

// Generate the options list of makes
foreach ($makes as $make) {
    $makeOptionList .= "&lt;option value='$make'";
    if ($selectedMake == $make) {
        $makeOptionList .= " selected='selected'";
    }
    $makeOptionList .= "&gt;$make&lt;/option&gt;";
}

// Generate the options list of models
if (count($models) &gt; 0) {
    foreach ($models as $model) {
        $modelsOptionList .= "&lt;option value='$model'&gt;$model&lt;/option&gt;";
    }
}
else {
    $modelsOptionList = '&lt;option value=""&gt;Select a Make&lt;/option&gt;';
}
?&gt;
</pre>
<p>So now the page is functioning for all users that don&#8217;t have JavaScript.  When the page loads, the makes will be populated. If the user clicks on the &#8220;Get Models&#8221; button, the selected make will be submitted back to the PHP above, which in turn will populate the models and show the form again, but this time with the populated results.</p>
<p>All that&#8217;s left is to use Progressive Enhancement to provide an AJAX alternative to the post back to the server. An AJAX solution will be more responsive, as the entire page doesn&#8217;t need to be reloaded.  Here&#8217;s the JavaScript code.  Note, I&#8217;m using the Yahoo UI Library for it&#8217;s DOM manipulation, Event handling utility, Element manipulation, and Connection Manager for it&#8217;s simplified AJAX interface.</p>
<pre name="code" class="php">
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.7.0/build/yahoo-dom-event/yahoo-dom-event.js&#038;2.7.0/build/connection/connection-min.js&#038;2.7.0/build/element/element-min.js"></script>
</pre>
<p>And then my own script:</p>
<pre name="code" class="javascript">
var make = new YAHOO.util.Element('make'),
    submitbtn = new YAHOO.util.Element('getmodels'),
    models = new YAHOO.util.Element('models');

// Remove the submit button
submitbtn.setStyle('display','none');

// Attach event listeners to 'make' that will call getModels
// service, parse the results, and populate 'models' options
make.on('click', function (e) {
    YAHOO.util.Connect.setForm('getMakeModel');
    var transaction = YAHOO.util.Connect.asyncRequest('GET',
            'http://www.fotiweb.com/samples/dependent-list-box/getModels/', {
                success: function(o) {
                    var i, op, old,
                        modelList = o.responseText;
                    // Remove the existing option elements
                    old = models.getElementsByTagName('option');
                    while (old.length &gt; 0) {
                        old[old.length - 1].parentNode.removeChild(old[old.length - 1]);
                    }
                    // Convert results to array
                    modelList = modelList.split(",");
                    // Generate the options list of models
                    for (i = 0; i &lt; modelList.length; i++) {
                        op = document.createElement('option');
                        op.text = modelList[i];
                        op.value = modelList[i];
                        models.appendChild(op);
                    }
                }
    }, null);
});
</pre>
<p>This will hide the submit button and perform the request to the getModels service when the user selects a make.  This is just one way you could use Progressive Enhancement to enhance your dependent lists.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2009/07/02/dependent-lists-and-progressive-enhancement/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Another Baby First</title>
		<link>http://www.fotiweb.com/2009/03/10/another-baby-first/</link>
		<comments>http://www.fotiweb.com/2009/03/10/another-baby-first/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 04:40:19 +0000</pubDate>
		<dc:creator>Peter Foti</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.fotiweb.com/?p=52</guid>
		<description><![CDATA[Today my son Alex waved &#8220;bye bye&#8221; to someone for the first time.  I was surprised at how exciting I found it.  He&#8217;s growing up so quick.
]]></description>
			<content:encoded><![CDATA[<p>Today my son Alex waved &#8220;bye bye&#8221; to someone for the first time.  I was surprised at how exciting I found it.  He&#8217;s growing up so quick.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fotiweb.com/2009/03/10/another-baby-first/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
