<?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>dougv.com « Doug Vanderweide &#187; drop down / select list</title>
	<atom:link href="http://www.dougv.com/tag/drop-down-select-list/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.dougv.com</link>
	<description>ASP.NET, PHP, XML, JavaScript, Web geekery, Entrepreneurship</description>
	<lastBuildDate>Thu, 17 May 2012 22:33:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Working With The authorize.net Server Integration Method (SIM) Payment Gateway, Part 1: Don&#8217;t Use JavaScript</title>
		<link>https://www.dougv.com/2012/02/23/working-with-the-authorize-net-server-integration-method-sim-payment-gateway-part-1-dont-use-javascript/</link>
		<comments>https://www.dougv.com/2012/02/23/working-with-the-authorize-net-server-integration-method-sim-payment-gateway-part-1-dont-use-javascript/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 18:11:19 +0000</pubDate>
		<dc:creator>Doug Vanderweide</dc:creator>
				<category><![CDATA[API]]></category>
		<category><![CDATA[authorize.net]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[drop down / select list]]></category>
		<category><![CDATA[elegance]]></category>
		<category><![CDATA[Greasemonkey]]></category>
		<category><![CDATA[payment gateway]]></category>
		<category><![CDATA[radio buttons]]></category>
		<category><![CDATA[Server Integration Method]]></category>

		<guid isPermaLink="false">http://www.dougv.com/?p=4115</guid>
		<description><![CDATA[JavaScript is too insecure to compute shopping cart totals. You can't rely on it when submitting payment requests to authorize.net.<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/07/06/working-with-the-authorize-net-customer-information-manager-cim-part-1-overview/" rel="bookmark">Working With The Authorize.net Customer Information Manager (CIM), Part 1: Overview</a> (28.4)</li>
				<li><a href="https://www.dougv.com/2009/05/13/using-javascript-to-perform-a-task-traditionally-solved-with-server-side-scripting/" rel="bookmark">Using JavaScript To Perform A Task Traditionally Solved With Server-Side Scripting</a> (16.3)</li>
				<li><a href="https://www.dougv.com/2007/07/03/working-with-a-simple-structure-array-in-vbnet/" rel="bookmark">Working With A Simple Structure Array In VB.NET</a> (14.5)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p>I got an email a few days ago from a reader seeking help with the <a href="http://www.authorize.net/" target="_blank">authorize.net</a> <a href="http://developer.authorize.net/api/sim/" target="_blank">Server Integration Method (SIM)</a> credit card <a href="http://en.wikipedia.org/wiki/Payment_gateway" target="_blank">payment gateway</a>.</p>
<p>Specifically, he was asking how he could use JavaScript to pass a calculated total to a PHP page that contains the SIM code. </p>
<ul>
<li>A customer chooses a series of options from some select lists, radio buttons and the like;</li>
<li>the page calculates an order total;</li>
<li>the end user hits a submit button;</li>
<li>the results are posted to the SIM processing page, which acts as a &#8220;confirmation page&#8221;; and</li>
<li>The customer presses another button, which takes him to authorize.net to provide payment info and actually charge the card.</li>
</ul>
<p>You can see an approximation of what I&#8217;m talking about here: <a href="http://www.dougv.com/demo/js_form_values" target="_blank">http://www.dougv.com/demo/js_form_values</a>. The questioner&#8217;s form is similar to this approximation in function.</p>
<div class="aside">I will show how to properly customize a SIM form, and submit payment requests to authorize.net via SIM, in an upcoming post. This post explores why it&#8217;s a terrible idea to process order forms with JavaScript. That is, it&#8217;s about the wrong way to use SIM. Stay tuned for the right way.</div>
<p><span id="more-4115"></span>The direct answer to my reader&#8217;s question is simple. </p>
<p>1. Add a hidden form field inside the form:</p>
<pre class="brush: xml; title: ; notranslate">&lt;input type=&quot;hidden&quot; id=&quot;order_total_input&quot; name=&quot;order_total_input&quot; value=&quot;0.00&quot; /&gt;</pre>
<p>2. Using JavaScript, assign the calculated total as the value of that hidden form field:</p>
<pre class="brush: jscript; title: ; notranslate">

function orderTotal() {
	var total;
	//bunch of code that calculates the total from various form inputs
	total = total.toFixed(2);
	document.getElementById('order_total_input').value = total;
}
</pre>
<p>3. Add this function as an onsubmit event for the form:</p>
<pre class="brush: xml; title: ; notranslate">&lt;form id=&quot;orderform&quot; name=&quot;orderform&quot; method=&quot;post&quot; action=&quot;sim.php&quot; onsubmit=&quot;orderTotal()&quot;&gt;</pre>
<p>You can see this in action here: <a href="http://www.dougv.com/demo/js_form_values" target="_blank">http://www.dougv.com/demo/js_form_values</a>.</p>
<h3>JavaScript Is Wildly Insecure</h3>
<p><img src="http://www.dougv.com/wp-content/uploads/2012/02/alert.jpg" alt="Never rely on JavaScript alone alert box" title="Never rely on JavaScript alone alert box" width="357" height="115" class="alignright size-full wp-image-4121" />That said, this entire approach is wrong-headed, a complete security risk, and likely to backfire. </p>
<p><strong>Never use JavaScript to calculate the values you intend to submit to a credit card processor.</strong> For what that&#8217;s worth, <strong>never use a hidden form fields to pass any variable to a credit card processor.</strong></p>
<p><strong>Always use server-side processing to check, sanitize and process credit card orders.</strong></p>
<p>Why? Because anyone with a basic understanding of JavaScript can easily change the value of any form variable, simply by injecting a script onto your Web page.</p>
<p>You may have heard of <a href="http://www.greasespot.net/" target="_blank">Greasemonkey</a>. It&#8217;s a Web browser plugin that allows any user to add JavaScript to any Web page. And many Web browsers allow you to <a href="http://www.codinghorror.com/blog/2009/05/the-web-browser-address-bar-is-the-new-command-line.html" target="_blank">add JavaScript to the current page simply by typing it into the location bar</a>.</p>
<p>Using this knowledge, one can easily poison any form variable value on the page. He can not only poison the hidden form input that carries over the total to our shopping cart; he can also poison individual elements.</p>
<p>So, by the same token that the questioner can use this JavaScript to assign a value to order_total_input on form submission:</p>
<pre class="brush: jscript; title: ; notranslate">document.getElementById('order_total_input').value = total;</pre>
<p>I can override the orderTotal() function to be just this one line:</p>
<pre class="brush: jscript; title: ; notranslate">document.getElementById('order_total_input').value = '0.01';</pre>
<p>And that will set the total cost of my order to 1 cent.</p>
<p>You can see a demo of what I am talking about here: <a href="http://www.dougv.com/demo/js_form_values/poison.htm" target="_blank">http://www.dougv.com/demo/js_form_values/poison.htm</a>.</p>
<h3>Always Process Orders Server-Side</h3>
<p>If you don&#8217;t check that value at some point, to ensure it is correct, you could easily wind up selling me your entire cart for a penny. </p>
<p>If you use JavaScript to confirm the order total, not only have you duplicated your efforts / code &#8212; which is the dictionary definition of <a href="http://dictionary.reference.com/browse/inelegant" target="_blank">inelegant</a> &#8212; I can simply poison whatever JavaScript you used to confirm the order total is right, and still send along my one-penny charge.</p>
<p>Now, it&#8217;s true that many credit card processors will <a href="http://en.wikipedia.org/wiki/Credit_card_fraud#Carding" target="_blank">flag a one-cent charge as suspicious</a>. Many will also flag a $1 charge. But most credit card processors consider a $1 hold entirely appropriate, as a request to confirm a card is valid, and indicative of a charge that will be posted later. </p>
<p>(If you buy gasoline at the pump using a credit card, you know this is how it&#8217;s usually handled: A $1 hold is placed on your card, and the actual total for gas is posted as an amended transaction a day or two later, depending on when the gas station&#8217;s merchant bank processes its queue.)</p>
<p>So a smart scammer wouldn&#8217;t use 1 cent to poison your variable. But if he saw a total charge, for several items, of $150, and one or two of the things he ordered cost $35, he would amend his total, via JavaScript, to $35. </p>
<p>That amount wouldn&#8217;t be flagged by the credit card processor, which has no idea what specifically is being bought; only how much you want to charge the customer. It sees a $35 charge, which it has probably processed numerous times on your behalf, as totally legitimate. Such as charge could easily slip past whomever is fulfilling your orders, especially if they are busy, and you haven&#8217;t engineered a program that properly checks order totals.</p>
<h3>Any Form Variable Can Be Poisoned By DOM Manipulation</h3>
<p>Admittedly, a significant part of the problem with the questioner&#8217;s approach is that he is using, as values in his form / JavaScript, the actual prices of what he is selling.</p>
<p>Since I know how much he wants to charge for each thing, and because he is calculating his order total based on values contained in HTML elements, I can simply change those values to be whatever I want them to be, via a little <a href="http://www.w3schools.com/dom/dom_document.asp" target="_blank">Document Object Model (DOM) manipulation</a>. </p>
<p>So, if you have a select list that looks like this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;select id=&quot;base_membership&quot; name=&quot;base_membership&quot; onchange=&quot;orderTotal()&quot;&gt;
	&lt;option value=&quot;0.00&quot; selected=&quot;selected&quot;&gt;No membership&lt;/option&gt;
	&lt;option value=&quot;50.00&quot;&gt;Basic membership, $50 / year&lt;/option&gt;
	&lt;option value=&quot;80.00&quot;&gt;Silver membership, $80 / year&lt;/option&gt;
	&lt;option value=&quot;100.00&quot;&gt;Gold membership, $100 / year&lt;/option&gt;
&lt;/select&gt;
</pre>
<p>There is nothing stopping me from writing a Greasemonkey script that changes the values for each of those options:</p>
<pre class="brush: jscript; title: ; notranslate">
var tmp = document.getElementById('base_membership');
var i;
for(i = 0; i &lt; tmp.length; i++) {
	tmp.options[i].value = parseFloat(tmp.options[i].value / 10).toFixed(2);
}
</pre>
<p>Now, his $50 membership only costs me $5, and the $100 membership is a bargain at $10.</p>
<p>You can see this in action here: <a href="http://www.dougv.com/demo/js_form_values/poison2.htm" target="_blank">http://www.dougv.com/demo/js_form_values/poison2.htm</a>.</p>
<p>That is why, again,<strong> you should never use JavaScript to calculate a shopping cart total</strong> and <strong>always process credit card transaction totals on the server side</strong>.</p>
<p>I don&#8217;t mean to pile abuse onto my questioner. </p>
<p>Quite the opposite; I really appreciate the opportunity he&#8217;s provided to address the security issues around using JavaScript to accomplish important tasks, to discuss application security in general, and to set up the future discussion of how to properly implement authorize.net&#8217;s Server Integration Method (SIM).</p>
<p>Again, I&#8217;ll do that soon.</p>
<p>You can download the demo code for this article here: <a href='http://www.dougv.com/wp-content/uploads/2012/02/js_form_values.zip'>http://www.dougv.com/wp-content/uploads/2012/02/js_form_values.zip</a></p>
<p>All links in this post on delicious: <a href="http://delicious.com/dougvdotcom/working-with-the-authorize-net-server-integration-method-sim-payment-gateway-part-1-dont-use-javascript" target="_blank">http://delicious.com/dougvdotcom/working-with-the-authorize-net-server-integration-method-sim-payment-gateway-part-1-dont-use-javascript</a></p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/07/06/working-with-the-authorize-net-customer-information-manager-cim-part-1-overview/" rel="bookmark">Working With The Authorize.net Customer Information Manager (CIM), Part 1: Overview</a> (28.4)</li>
				<li><a href="https://www.dougv.com/2009/05/13/using-javascript-to-perform-a-task-traditionally-solved-with-server-side-scripting/" rel="bookmark">Using JavaScript To Perform A Task Traditionally Solved With Server-Side Scripting</a> (16.3)</li>
				<li><a href="https://www.dougv.com/2007/07/03/working-with-a-simple-structure-array-in-vbnet/" rel="bookmark">Working With A Simple Structure Array In VB.NET</a> (14.5)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a>, <a href="https://www.dougv.com/tag/elegance/" title="elegance" rel="tag">elegance</a>, <a href="https://www.dougv.com/tag/greasemonkey/" title="Greasemonkey" rel="tag">Greasemonkey</a>, <a href="https://www.dougv.com/tag/payment-gateway/" title="payment gateway" rel="tag">payment gateway</a>, <a href="https://www.dougv.com/tag/radio-buttons/" title="radio buttons" rel="tag">radio buttons</a>, <a href="https://www.dougv.com/tag/server-integration-method/" title="Server Integration Method" rel="tag">Server Integration Method</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2012/02/23/working-with-the-authorize-net-server-integration-method-sim-payment-gateway-part-1-dont-use-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Parent-Child DropDownList Controls In ASP.NET Web Forms (VB.NET)</title>
		<link>https://www.dougv.com/2011/12/25/parent-child-dropdownlist-controls-in-asp-net-web-forms-vb-net/</link>
		<comments>https://www.dougv.com/2011/12/25/parent-child-dropdownlist-controls-in-asp-net-web-forms-vb-net/#comments</comments>
		<pubDate>Sun, 25 Dec 2011 20:44:40 +0000</pubDate>
		<dc:creator>Doug Vanderweide</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Stored Procedures]]></category>
		<category><![CDATA[Transact-SQL]]></category>
		<category><![CDATA[Web Forms]]></category>
		<category><![CDATA[drop down / select list]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[MSDN]]></category>
		<category><![CDATA[ZIP Code database]]></category>

		<guid isPermaLink="false">http://www.dougv.com/?p=3950</guid>
		<description><![CDATA[Discusses three approaches to databinding child values in an ASP.NET DropDownList, based on parent DropDownList selections.<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/06/21/parent-child-select-lists-revisited-multiple-parent-child-select-lists-via-php-mysql-and-jquery/" rel="bookmark">Parent &#8211; Child Select Lists Revisited: Multiple Parent &#8211; Child Select Lists Via PHP, MySQL And jQuery</a> (28.7)</li>
				<li><a href="https://www.dougv.com/2011/04/24/automatically-hash-tagging-text-with-asp-net-web-forms-vb-net/" rel="bookmark">Automatically Hash Tagging Text With ASP.NET Web Forms (VB.NET)</a> (25)</li>
				<li><a href="https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/" rel="bookmark">Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</a> (24)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p>Some time ago I <a title="binding a data from database to dropdownlist based on selected item of another dropdown list" href="http://www.dougv.com/2011/10/10/binding-a-data-from-database-to-dropdownlist-based-on-selected-item-of-another-dropdown-list/">promised a formspring anon</a> I would do a tutorial on parent / child DropDownList controls in ASP.NET Web Forms. At long last, I&#8217;m delivering. (From here on out, I will use &#8220;DropDownList&#8221; and &#8220;select list&#8221; interchangeably.)</p>
<div class="aside">Parent-child <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.dropdownlist.aspx" target="_blank">DropDownList controls</a> means you have a parent, or main / master select list. Based on whatever selection is made in that first DropDownList, a second, &#8220;child&#8221; or &#8220;detail&#8221; select list is populated with relevant results.For example, if we had a database of cars, we might have a parent (master) DropDownList of manufacturers &#8212; Ford, Chevy, Toyota, etc. &#8212; and populate the child DropDownList with models from the selected manufacturer. So, if someone chose Ford in the parent select list, the child select list would automatically populate with choices such as Fusion, Mustang, Explorer, F-150, etc.</div>
<p>I&#8217;ll be demonstrating two different ways to accomplish this task, as well as a few variations on the first: First, binding with only <a href="http://msdn.microsoft.com/en-us/library/dz12d98w%28v=VS.100%29.aspx" target="_blank">SqlDataSource controls</a>, which is by far the easiest way to proceed and will suffice for about 90 percent of applications; second, using code behind and <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.comparevalidator.aspx" target="_blank">CompareValidator controls</a>, to cover all possible roadblocks.</p>
<p>Some notes before we proceed:</p>
<ul>
<li>I&#8217;ll use the <a title="Getting All ZIP Codes In A Given Radius From A Known Point / ZIP Code Via PHP And MySQL" href="http://www.dougv.com/2009/03/27/getting-all-zip-codes-in-a-given-radius-from-a-known-point-zip-code-via-php-and-mysql/" target="_blank">ZIP Code database</a> I&#8217;ve been using for a while as the back-end data. I also have a separate table of USPS state codes I&#8217;m using as the parent data, to help illustrate that you can use several tables / data sources to fuel this solution, provided the keys that relate the data make sense to each data store. In other words, you can use a lot of different sources for your data, so long as the data is <a href="http://computer.howstuffworks.com/question599.htm" target="_blank">relational</a>.</li>
<li>I&#8217;m going to use SQL Server, stored procedures and a connection string stored in my web.config file to access my data. I recognize that some people prefer to use SQL statements / LINQ and the like, or can only use Access / MySQL or other data stores. I really urge you to always use stored procedures, as they <a href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29" target="_blank">are way safer than inline SQL statements</a>. As far as alternative data stores go, that should be a easy a fix as switching your code to use to the relevant <a href="http://msdn.microsoft.com/en-us/library/32c5dh3b%28v=VS.100%29.aspx" target="_blank">ADO.NET ODBC classes</a>, rather than the SQL Client classes.</li>
<li>This solution should work for ASP.NET versions 2.0 forward.</li>
</ul>
<p><span id="more-3950"></span><br />
<h3>Example 1: Using SqlDataSource Controls</h3>
<p>Most ASP.NET Web developers know about the SqlDataSource control and how to databind a DropDownList with that control. What they may not know is that, via the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.controlparameter.aspx" target="_blank">ControlParameter class</a>, we can use the values in any other ASP.NET control(s) &#8212; including other databound controls &#8212; on the page as query parameters.</p>
<p>All you need to do is indicate, as properties of the ControlParameter, the ID of the control that will provide the key value for your child query, the property of that control (e.g., selected value, text, etc.) which should serve as the key, and the variable name that should be used in that query.</p>
<p>In our example, I have a select list named ddlParent, which will contain a list of state codes I get from a database table. Another select list, named ddlChild, will bind to a SqlDataSource control (named sqlChildDDL) that uses the selected value in ddlParent to retrieve proper records. </p>
<p>In my case, the stored procedure that will get the child records expects a parameter named &#8220;StateInitials&#8221;, the value of which comes from ddlParent and serves as the key for selecting the proper child records. By setting the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.autopostback.aspx" target="_blank">AutoPostBack property</a> of the parent DropDownList to true, I ensure the child DropDownList is rebound with the proper records each time the selected index of the parent list is changed.</p>
<pre class="brush: xml; title: ; notranslate">&lt;asp:Label runat=&quot;server&quot; ID=&quot;lblParent&quot; Text=&quot;Select A State: &quot; /&gt;
&lt;!-- parent ddl --&gt;
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;ddlParent&quot; DataSourceID=&quot;sqlParentDDL&quot; DataValueField=&quot;StateCode&quot; DataTextField=&quot;StateName&quot; AutoPostBack=&quot;true&quot; /&gt;
&lt;!-- parent ddl is populated with a parameterless SQL query --&gt;
&lt;asp:SqlDataSource runat=&quot;server&quot; ID=&quot;sqlParentDDL&quot; SelectCommand=&quot;GetStates&quot; SelectCommandType=&quot;StoredProcedure&quot; ConnectionString=&quot;&lt;%$ ConnectionStrings:MyConnection %&gt;&quot; /&gt;
&lt;br /&gt;
&lt;!-- child ddl --&gt;
&lt;asp:Label runat=&quot;server&quot; ID=&quot;lblChild&quot; Text=&quot;Select A Town: &quot; /&gt;
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;ddlChild&quot; DataSourceID=&quot;sqlChildDDL&quot; DataValueField=&quot;ZIPCode&quot; DataTextField=&quot;CityName&quot; /&gt;
&lt;!-- child ddl gets its parameter value from the selected value of the parent ddl --&gt;
&lt;!--
    ControlParamter property values
    ControlID: The ASP.NET control that is providing the paramter's value
    Name: The parameter's name as it appears in your stored procedure / SQL query
    PropertyName: The property of the ASP.NET control that will supply the value to your parameter
--&gt;
&lt;asp:SqlDataSource runat=&quot;server&quot; ID=&quot;sqlChildDDL&quot; SelectCommand=&quot;GetZIPCodes&quot; SelectCommandType=&quot;StoredProcedure&quot; ConnectionString=&quot;&lt;%$ ConnectionStrings:MyConnection %&gt;&quot;&gt;
    &lt;SelectParameters&gt;
        &lt;asp:ControlParameter ControlID=&quot;ddlParent&quot; Name=&quot;StateInitials&quot; PropertyName=&quot;SelectedValue&quot; /&gt;
    &lt;/SelectParameters&gt;
&lt;/asp:SqlDataSource&gt;</pre>
<p>Demo: <a href="http://dougv.net/demos/parent_child_dropdown/Example1A.aspx" target="_blank">http://dougv.net/demos/parent_child_dropdown/Example1A.aspx</a></p>
<div class="aside">Note that we can use any ASP.NET control on the page as a ControlParamter, and we can use any of that control&#8217;s properties as a parameter value, regardless of data type. </p>
<p>In other words, we could have a textbox on the page and use its Text property to let people type in free-text terms. (That&#8217;s a huge security risk, but it can be done.) </p>
<p>Or we could even use a static control with a non-text property, such as the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.parent.aspx" target="_blank">Parent value of a Label control</a>. </p>
<p>Of course, we need to exercise care here; any parameter value we send to a database query has to be the right data type / something the database store understands how to parse. The point is, ControlParamter is a powerful tool; respect it and it will open a number of possibilities.</p></div>
<p>Now that we have a parent-child select lists pair, how do we use that data to power some other control&#8217;s data? Simple: We just use the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.selectedvalue.aspx" target="_blank">SelectedValue</a> of the child DropDownList as the ControlParamter value for another SqlDataSource &#8212; in this example, it will bind to a <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.aspx" target="_blank">GridView</a> that gives the selected town&#8217;s ZIP Code, CityLatitude and CityLongitude.</p>
<p>All we need to do is add the GridView and its SqlDataSource, plus set the AutoPostBack property for ddlChild to true, so that the GridView&#8217;s values will change any time ddlChild&#8217;s selected index is changed.</p>
<pre class="brush: xml; title: ; notranslate">&lt;asp:Label runat=&quot;server&quot; ID=&quot;lblParent&quot; Text=&quot;Select A State: &quot; /&gt;
&lt;!-- parent ddl --&gt;
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;ddlParent&quot; DataSourceID=&quot;sqlParentDDL&quot; DataValueField=&quot;StateCode&quot; DataTextField=&quot;StateName&quot; AutoPostBack=&quot;true&quot; /&gt;
&lt;!-- parent ddl is populated with a parameterless SQL query --&gt;
&lt;asp:SqlDataSource runat=&quot;server&quot; ID=&quot;sqlParentDDL&quot; SelectCommand=&quot;GetStates&quot; SelectCommandType=&quot;StoredProcedure&quot; ConnectionString=&quot;&lt;%$ ConnectionStrings:MyConnection %&gt;&quot; /&gt;
&lt;br /&gt;
&lt;!-- child ddl --&gt;
&lt;asp:Label runat=&quot;server&quot; ID=&quot;lblChild&quot; Text=&quot;Select A Town: &quot; /&gt;
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;ddlChild&quot; DataSourceID=&quot;sqlChildDDL&quot; DataValueField=&quot;ZIPCode&quot; DataTextField=&quot;CityName&quot; AutoPostBack=&quot;true&quot; /&gt;
&lt;!-- child ddl gets its parameter value from the selected value of the parent ddl --&gt;
&lt;!--
    ControlID: Name of the ASP.NET control that is providing the paramter's value
    Name: The name of the parameter in your stored procedure / SQL query
    PropertyName: The property of the control, specified in ControlID, that will supply the value to your query, specified in Name
--&gt;
&lt;asp:SqlDataSource runat=&quot;server&quot; ID=&quot;sqlChildDDL&quot; SelectCommand=&quot;GetZIPCodes&quot; SelectCommandType=&quot;StoredProcedure&quot; ConnectionString=&quot;&lt;%$ ConnectionStrings:MyConnection %&gt;&quot;&gt;
    &lt;SelectParameters&gt;
        &lt;asp:ControlParameter ControlID=&quot;ddlParent&quot; Name=&quot;StateInitials&quot; PropertyName=&quot;SelectedValue&quot; /&gt;
    &lt;/SelectParameters&gt;
&lt;/asp:SqlDataSource&gt;
&lt;br /&gt;
&lt;br /&gt;

&lt;!-- A GridView to show the resuls --&gt;
&lt;asp:GridView runat=&quot;server&quot; ID=&quot;gvDetails&quot; DataSourceID=&quot;sqlZipDetails&quot; DefaultMode=&quot;ReadOnly&quot; CellPadding=&quot;5&quot; AutoGenerateColumns=&quot;false&quot;&gt;
    &lt;AlternatingRowStyle BackColor=&quot;LightGray&quot; /&gt;
    &lt;HeaderStyle BackColor=&quot;LightYellow&quot; Font-Bold=&quot;True&quot; HorizontalAlign=&quot;Center&quot; /&gt;
    &lt;Columns&gt;
        &lt;asp:BoundField HeaderText=&quot;City&quot; DataField=&quot;CityName&quot; /&gt;
        &lt;asp:BoundField HeaderText=&quot;State&quot; DataField=&quot;StateInitials&quot; /&gt;
        &lt;asp:BoundField HeaderText=&quot;ZIP Code&quot; DataField=&quot;ZIPCode&quot; /&gt;
        &lt;asp:BoundField HeaderText=&quot;Latitide&quot; DataField=&quot;CityLatitude&quot; /&gt;
        &lt;asp:BoundField HeaderText=&quot;Longitude&quot; DataField=&quot;CityLongitude&quot; /&gt;
    &lt;/Columns&gt;
&lt;/asp:GridView&gt;
&lt;!-- the GridView gets records based on the SelectedValue of ddlChild --&gt;
&lt;asp:SqlDataSource runat=&quot;server&quot; ID=&quot;sqlZipDetails&quot; SelectCommand=&quot;GetCityDetails&quot; SelectCommandType=&quot;StoredProcedure&quot; ConnectionString=&quot;&lt;%$ ConnectionStrings:MyConnection %&gt;&quot;&gt;
    &lt;SelectParameters&gt;
        &lt;asp:ControlParameter ControlID=&quot;ddlChild&quot; Name=&quot;ZIPCode&quot; PropertyName=&quot;SelectedValue&quot; /&gt;
    &lt;/SelectParameters&gt;
&lt;/asp:SqlDataSource&gt;</pre>
<p>See this in action: <a href="http://dougv.net/demos/parent_child_dropdown/Default.aspx" target="_blank">http://dougv.net/demos/parent_child_dropdown/Default.aspx</a></p>
<h3>Example 1B: A Little Code Behind To Clean Things Up</h3>
<p>If you play with the demo above, you&#8217;ll notice a problem: Any time you change the selected <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listitem.aspx" target="_blank">ListItem</a> in ddlParent, the ListItems in ddlChild are updated, but not the data in the details GridView. </p>
<p>In other words, if you select a new state from the parent select list, the town values in the child select will change to the appropriate entries, but the GridView retains the old data from the previously selected town. Only choosing a new town from the child select list will update the GridView.</p>
<p>That happens because although ddlChild has been populated with new ListItems, the SelectedValue of ddlChild hasn&#8217;t been changed. Changing the SelectedValue is an act that must take place within ddlChild, not ddlParent. </p>
<p>In other words, the event that triggered the page to post back was a change in ddlParent&#8217;s selected value, <em>not</em> ddlChild. Until we explicitly instruct ddlChild to update its selected value, either programmatically or by hand, as far as ASP.NET is concerned, it retains the last SelectedValue, regardless of the fact that its ListItems have changed.</p>
<p>This behavior is by design and as it should be. But it does make for an annoyance we need to address.</p>
<p>Fortunately, we can fix this with just a little codebehind; namely, an event handler that fires on ddlParent&#8217;s OnSelectedIndexChanged event. That handler will:</p>
<ul>
<li>Rebind ddlChild to its SqlDataSource, which will now contain the correct town list.</li>
<li>Set the SelectedIndex of ddlChild to 0, or the first town in the new list.</li>
<li>Rebind the GridView&#8217;s SqlDataSource so it draws from the first town in the updated town list.</li>
</ul>
<pre class="brush: vb; title: ; notranslate">
Sub ddlParent_selectedIndexChanged(Sender As Object, E As EventArgs) Handles ddlParent.SelectedIndexChanged
	ddlChild.DataBind()
	ddlChild.SelectedIndex = 0
	sqlZipDetails.DataBind()
End Sub
</pre>
<p>Demo: <a href="http://dougv.net/demos/parent_child_dropdown/Example1B.aspx" target="_blank">http://dougv.net/demos/parent_child_dropdown/Example1B.aspx</a></p>
<p>This pretty much solves our data latency problem, but it adds duplicate queries to the process and thus is inefficient. We can do a better if we get more code-intensive.</p>
<h3>Example 2: Using Code Behind And CompareValidator Controls</h3>
<p>To streamline the process, reduce database queries and handle potentially bad inputs, we can use code behind to populate our DropDownLists and GridView, plus use CompareValidators to ensure we have legitimate data before sending our database queries.</p>
<p>We&#8217;ll bind records to a SqlDataReader, then use that reader to populate the DropDownLists and, where appropriate, the detail GridView. Additionally, we&#8217;ll use CompareValidators to ensure that the users have selected a valid option from each DropDownList. </p>
<p>First up, we need to create the DropDownLists and GridView. Notice that both DropDownLists begin with a single, default ListItem with a value of 0. </p>
<p>That&#8217;s because our valid options, once this list is populated, will never be zero; as a result, we can test with the CompareValidators whether the selected value of either DropDownList is 0. If it is, we know we have an invalid choice; otherwise, we expect the choice to be valid.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;asp:Label runat=&quot;server&quot; ID=&quot;lblParent&quot; Text=&quot;Select A State: &quot; /&gt;
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;ddlParent&quot; AutoPostBack=&quot;true&quot;&gt;
    &lt;asp:ListItem Text=&quot;Select A State ...&quot; Value=&quot;0&quot; /&gt;
&lt;/asp:DropDownList&gt;
&lt;asp:CompareValidator runat=&quot;server&quot; ID=&quot;cvParent&quot; ControlToValidate=&quot;ddlParent&quot; ValueToCompare=&quot;0&quot; Operator=&quot;NotEqual&quot; ErrorMessage=&quot;Please select a valid option&quot; Display=&quot;Dynamic&quot; /&gt;
&lt;br /&gt;
&lt;asp:Label runat=&quot;server&quot; ID=&quot;lblChild&quot; Text=&quot;Select A Town: &quot; /&gt;
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;ddlChild&quot; AutoPostBack=&quot;true&quot;&gt;
    &lt;asp:ListItem Text=&quot;Select A State First&quot; Value=&quot;0&quot; /&gt;
&lt;/asp:DropDownList&gt;
&lt;asp:CompareValidator runat=&quot;server&quot; ID=&quot;cvChild&quot; ControlToValidate=&quot;ddlChild&quot; ValueToCompare=&quot;0&quot; Operator=&quot;NotEqual&quot; ErrorMessage=&quot;Please select a valid option&quot; Display=&quot;Dynamic&quot; /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;asp:GridView runat=&quot;server&quot; ID=&quot;gvDetails&quot; CellPadding=&quot;5&quot; AutoGenerateColumns=&quot;false&quot;&gt;
    &lt;AlternatingRowStyle BackColor=&quot;LightGray&quot; /&gt;
    &lt;HeaderStyle BackColor=&quot;LightYellow&quot; Font-Bold=&quot;True&quot; HorizontalAlign=&quot;Center&quot; /&gt;
    &lt;Columns&gt;
        &lt;asp:BoundField HeaderText=&quot;City&quot; DataField=&quot;CityName&quot; /&gt;
        &lt;asp:BoundField HeaderText=&quot;State&quot; DataField=&quot;StateInitials&quot; /&gt;
        &lt;asp:BoundField HeaderText=&quot;ZIP Code&quot; DataField=&quot;ZIPCode&quot; /&gt;
        &lt;asp:BoundField HeaderText=&quot;Latitide&quot; DataField=&quot;CityLatitude&quot; /&gt;
        &lt;asp:BoundField HeaderText=&quot;Longitude&quot; DataField=&quot;CityLongitude&quot; /&gt;
    &lt;/Columns&gt;
&lt;/asp:GridView&gt;
</pre>
<p>We have several subroutines needed to power this solution. </p>
<p>First, we need to initially populate the parent DropDownList; we&#8217;ll do that in the Page_Load subroutine, checking whether this page is a postback. (We don&#8217;t want to repopulate the parent select list on every page refresh; if we do, we won&#8217;t ever be able to change the child select list&#8217;s values, since the selected index of the parent DropDownList becomes 0, automatically, every time it is databound.</p>
<pre class="brush: vb; title: ; notranslate">
Sub Page_Load(Sender As Object, E As EventArgs) Handles Me.Load
	If Not Page.IsPostBack Then
		ddlParent_dataBind()
	End If
End Sub
</pre>
<p>The process of binding the parent DropDownList is just connecting to the database server, populating a SqlDataReader with records, binding that to the parent DropDownList and indicating which fields should be used for text and values of the resulting ListItems.</p>
<pre class="brush: vb; title: ; notranslate">
Sub ddlParent_dataBind()
	Dim objConn As New SqlConnection(ConfigurationManager.ConnectionStrings(&quot;MyConnection&quot;).ConnectionString)
	Dim objCmd As New SqlCommand(&quot;GetStates&quot;, objConn)
	objCmd.CommandType = CommandType.StoredProcedure

	Dim objReader As SqlDataReader

	objConn.Open()
	objReader = objCmd.ExecuteReader()

	If Not objReader.HasRows Then
		ddlParent.Items.Clear()
		ddlParent.Items.Add(&quot;No records found.&quot;)
		ddlParent.Enabled = False
	Else
		ddlChild.Enabled = True
		ddlParent.DataSource = objReader
		ddlParent.DataTextField = &quot;StateName&quot;
		ddlParent.DataValueField = &quot;StateCode&quot;
		ddlParent.DataBind()
		ddlParent.Items.Insert(0, New ListItem(&quot;Select A State ...&quot;, &quot;0&quot;))
	End If

	objConn.Close()
	objCmd.Dispose()
	objConn.Dispose()
End Sub
</pre>
<p>We bind data to the child select list in a similar way, except we&#8217;re going to get some sort of key value from the parent DropDownList. So we pass that in as a parameter.</p>
<pre class="brush: vb; title: ; notranslate">
Sub ddlChild_dataBind(strKey As String)
	ddlChild.Items.Clear()

	Dim objConn As New SqlConnection(ConfigurationManager.ConnectionStrings(&quot;MyConnection&quot;).ConnectionString)
	Dim objCmd As New SqlCommand(&quot;GetZIPCodes&quot;, objConn)
	objCmd.CommandType = CommandType.StoredProcedure

	objCmd.Parameters.Add(New SqlParameter(&quot;StateInitials&quot;, SqlDbType.Char, 2))
	objCmd.Parameters(&quot;StateInitials&quot;).Value = strKey

	Dim objReader As SqlDataReader

	objConn.Open()
	objReader = objCmd.ExecuteReader()

	If Not objReader.HasRows Then
		ddlChild.Items.Clear()
		ddlChild.Items.Insert(0, &quot;Error getting towns list from database&quot;)
	Else
		ddlChild.Enabled = True
		ddlChild.DataSource = objReader
		ddlChild.DataTextField = &quot;CityName&quot;
		ddlChild.DataValueField = &quot;ZIPCode&quot;
		ddlChild.DataBind()
		ddlChild.Items.Insert(0, New ListItem(&quot;Select A Town ...&quot;, &quot;0&quot;))
	End If

	objConn.Close()
	objCmd.Dispose()
	objConn.Dispose()
End Sub
</pre>
<p>And binding the GridView data is pretty much more of the same.</p>
<pre class="brush: vb; title: ; notranslate">
Sub gvDetails_dataBind(strKey As String)
	Dim objConn As New SqlConnection(ConfigurationManager.ConnectionStrings(&quot;MyConnection&quot;).ConnectionString)
	Dim objCmd As New SqlCommand(&quot;GetCityDetails&quot;, objConn)
	objCmd.CommandType = CommandType.StoredProcedure

	objCmd.Parameters.Add(New SqlParameter(&quot;ZIPCode&quot;, SqlDbType.Char, 5))
	objCmd.Parameters(&quot;ZIPCode&quot;).Value = strKey

	Dim objReader As SqlDataReader

	objConn.Open()
	objReader = objCmd.ExecuteReader()

	gvDetails.DataSource = objReader
	gvDetails.DataBind()

	objConn.Close()
	objCmd.Dispose()
	objConn.Dispose()
End Sub
</pre>
<p>Note that in all this databinding, I am not checking for exceptions, such as failure to connect to the database, a problem with the stored procedures, etc. </p>
<p>As I have said before, what makes for workable error trapping on your end is impossible for me to know, which is why I am not including it here. <em>You should always check for errors.</em> Don&#8217;t trust your programs won&#8217;t break; expect them to break. How you do that is up to you, but you definitely should prepare for failure.</p>
<p>We&#8217;ve got one more non-event subroutine to consider before we get into the action: A way to reset the GridView when we don&#8217;t have a valid child DropDownList selection. </p>
<p>To do that, we&#8217;ll simply set the DataSource of the GridView to nothing (null), then bind it; when a GridView is bound to a null, it is thus empty and, absent having its EmptyDataTemplate or EmptyDataText properties set, simply doesn&#8217;t render.</p>
<p>(I recognize that using nulls in this way is lazy. An alternative is to toggle the visibility of the GridView so that it only shows when we know we have good data, but that&#8217;s wordier and yes, I am being kind of lazy here.)</p>
<pre class="brush: vb; title: ; notranslate">
Sub gvDetails_reset()
	gvDetails.DataSource = Nothing
	gvDetails.DataBind()
End Sub
</pre>
<p>OK, with the mechanical parts of our code out of the way, we can handle changes to the selected item indexes of both the parent and child lists.</p>
<p>In the case of a parent select list change, we always know that whatever information is currently in the detail GridView will be outdated. So we&#8217;ll reset it, and we&#8217;ll rebind the child DropDownList if the selection in the parent DropDownList is valid (which we check with the relevant CompareValidator).</p>
<pre class="brush: vb; title: ; notranslate">
Sub ddlParent_selectedIndexChanged(Sender As Object, E As EventArgs) Handles ddlParent.SelectedIndexChanged
	cvParent.Validate()
	If cvParent.IsValid Then
		ddlChild_dataBind(ddlParent.SelectedValue)
		ddlChild.SelectedIndex = 0
	End If
	gvDetails_reset()
End Sub
</pre>
<p>When the child DropDownList&#8217;s selected index is changed, one of two things are true: Either the selection isn&#8217;t valid, in which case we reset the detail GridView, or it&#8217;s time to populate the details GridView with a new town&#8217;s information.</p>
<pre class="brush: vb; title: ; notranslate">
Sub ddlChild_selectedIndexChanged(Sender As Object, E As EventArgs) Handles ddlChild.SelectedIndexChanged
	cvChild.Validate()
	If cvChild.IsValid Then
		gvDetails_dataBind(ddlChild.SelectedValue)
	Else
		gvDetails_reset()
	End If
End Sub
</pre>
<p>You can see all this in action here: <a href="http://dougv.net/demos/parent_child_dropdown/Example2.aspx" target="_blank">http://dougv.net/demos/parent_child_dropdown/Example2.aspx</a>. You can also copy and paste relevant code from there. I distribute code under the GNU GPL version 3.</p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/06/21/parent-child-select-lists-revisited-multiple-parent-child-select-lists-via-php-mysql-and-jquery/" rel="bookmark">Parent &#8211; Child Select Lists Revisited: Multiple Parent &#8211; Child Select Lists Via PHP, MySQL And jQuery</a> (28.7)</li>
				<li><a href="https://www.dougv.com/2011/04/24/automatically-hash-tagging-text-with-asp-net-web-forms-vb-net/" rel="bookmark">Automatically Hash Tagging Text With ASP.NET Web Forms (VB.NET)</a> (25)</li>
				<li><a href="https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/" rel="bookmark">Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</a> (24)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a>, <a href="https://www.dougv.com/tag/microsoft/" title="Microsoft" rel="tag">Microsoft</a>, <a href="https://www.dougv.com/tag/msdn/" title="MSDN" rel="tag">MSDN</a>, <a href="https://www.dougv.com/tag/zip-code-database/" title="ZIP Code database" rel="tag">ZIP Code database</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2011/12/25/parent-child-dropdownlist-controls-in-asp-net-web-forms-vb-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>binding a data from database to dropdownlist based on selected item of another dropdown list</title>
		<link>https://www.dougv.com/2011/10/10/binding-a-data-from-database-to-dropdownlist-based-on-selected-item-of-another-dropdown-list/</link>
		<comments>https://www.dougv.com/2011/10/10/binding-a-data-from-database-to-dropdownlist-based-on-selected-item-of-another-dropdown-list/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 11:59:18 +0000</pubDate>
		<dc:creator>formspring.me</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[FormSpring Questions]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[drop down / select list]]></category>

		<guid isPermaLink="false">http://www.dougv.com/2011/10/10/binding-a-data-from-database-to-dropdownlist-based-on-selected-item-of-another-dropdown-list/</guid>
		<description><![CDATA[A question about databinding child DropDownLists from selected parent DropDownList values gets a promise of a future blog post.<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/" rel="bookmark">Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</a> (44.3)</li>
				<li><a href="https://www.dougv.com/2007/04/02/changing-an-iframe-source-from-a-drop-down-list-via-javascript-dom/" rel="bookmark">Changing An IFrame Source From A Drop-Down List Via JavaScript / DOM</a> (17.6)</li>
				<li><a href="https://www.dougv.com/2007/06/22/going-to-a-new-url-via-a-drop-down-list-javascript-and-dom-php-aspnet/" rel="bookmark">Going To A New URL Via A Drop-Down List: JavaScript And DOM, PHP, ASP.NET</a> (16.6)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p class="formspringmeAnswer">I blogged about doing this with PHP / MySQL / jQuery at <a href="http://dougv.us/64" target="_blank" rel="nofollow" class="nofollow">http://dougv.us/64</a> , <a href="http://dougv.us/4s" target="_blank" rel="nofollow" class="nofollow">http://dougv.us/4s</a> and <a href="http://dougv.us/4r" target="_blank" rel="nofollow" class="nofollow">http://dougv.us/4r</a> . If you&#8217;re looking for an ASP.NET Web Forms version, I&#8217;ll add this to my &quot;to blog&quot; list. Can&#8217;t say as to when I&#8217;ll get around to it, but probably not immediately, sorry.</p>
<p class="formspringmeFooter">
    <a href="http://www.formspring.me/dougvdotcom?utm_medium=social&amp;utm_source=wordpress&amp;utm_campaign=shareanswer">Ask me anything</a></p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/" rel="bookmark">Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</a> (44.3)</li>
				<li><a href="https://www.dougv.com/2007/04/02/changing-an-iframe-source-from-a-drop-down-list-via-javascript-dom/" rel="bookmark">Changing An IFrame Source From A Drop-Down List Via JavaScript / DOM</a> (17.6)</li>
				<li><a href="https://www.dougv.com/2007/06/22/going-to-a-new-url-via-a-drop-down-list-javascript-and-dom-php-aspnet/" rel="bookmark">Going To A New URL Via A Drop-Down List: JavaScript And DOM, PHP, ASP.NET</a> (16.6)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2011/10/10/binding-a-data-from-database-to-dropdownlist-based-on-selected-item-of-another-dropdown-list/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Parent &#8211; Child Select Lists Revisited: Multiple Parent &#8211; Child Select Lists Via PHP, MySQL And jQuery</title>
		<link>https://www.dougv.com/2009/06/21/parent-child-select-lists-revisited-multiple-parent-child-select-lists-via-php-mysql-and-jquery/</link>
		<comments>https://www.dougv.com/2009/06/21/parent-child-select-lists-revisited-multiple-parent-child-select-lists-via-php-mysql-and-jquery/#comments</comments>
		<pubDate>Sun, 21 Jun 2009 18:04:46 +0000</pubDate>
		<dc:creator>Doug Vanderweide</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[drop down / select list]]></category>

		<guid isPermaLink="false">http://www.dougv.com/blog/?p=2331</guid>
		<description><![CDATA[A while ago, I promised to answer Brian&#8217;s request for a demonstration of how to make multiple parent / child select lists &#8212; in other words, starting from one drop down / select list, having two or more child lists, each of which, in turn, may act as a parent to another list. Multiple parent-child [...]<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/05/21/parent-child-select-lists-revisited-validating-selected-options-via-jquery-and-php/" rel="bookmark">Parent &#8211; Child Select Lists Revisited: Validating Selected Options Via jQuery And PHP</a> (73.3)</li>
				<li><a href="https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/" rel="bookmark">Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</a> (37.8)</li>
				<li><a href="https://www.dougv.com/2007/01/03/retaining-selections-from-a-single-select-box-in-two-multiple-select-boxes-via-javascript-dom/" rel="bookmark">Retaining Selections From A Single Select Box In Two Multiple Select Boxes Via JavaScript / DOM</a> (34.3)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p>A while ago, I promised to answer <a href="http://www.dougv.com/2009/05/21/parent-child-select-lists-revisited-validating-selected-options-via-jquery-and-php/">Brian&#8217;s request for a demonstration of how to make multiple parent / child select lists</a> &#8212; in other words, starting from one drop down / select list, having two or more child lists, each of which, in turn, may act as a parent to another list.</p>
<p>Multiple parent-child select lists are considerably more complicated to program than a single parent-child relationship. Not only do we have additional data relationships to consider (that is, how we&#8217;re going to tie child list values to the selected parent values), we now need to plan for what to do if a &#8220;middle&#8221; relationship is changed (more on this shortly).</p>
<p>Fortunately, we have a starting point in <a href="http://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/">my original parent-child select list post</a>. We don&#8217;t need to reinvent the wheel, therefore, so much as we need to upgrade from a horse cart to a Lamborghini.</p>
<h3>Overview Of The Approach</h3>
<p>As was the case when we had a single child drop-down list, we must begin with relational data for each select list. Apologies to those who consider that obvious, but for n00bs, what I mean is, if you want to select a value from List A and have List B populated with new values, then the values you intend to have in List B must somehow be keyed (linked) to the selection made in List A.</p>
<p>This multiple parent-child select list approach will work for as many parent-nee-child lists you want. If you want to populate 10 or 100 or 1,000 lists, you won&#8217;t need to change a single line of JavaScript; however, your PHP &#8220;helper&#8221; page will need some modification to accommodate all the queries you&#8217;ll need, and the more lists you have, the more code you&#8217;ll have to put into your HTML (more on this shortly).</p>
<p><span id="more-2331"></span></p>
<p>For the purposes of this demo, I am going to use the geocoded ZIP Code data I picked up for my post titled, &#8220;<a href="http://www.dougv.com/2009/03/27/getting-all-zip-codes-in-a-given-radius-from-a-known-point-zip-code-via-php-and-mysql/">Getting All ZIP Codes In A Given Radius From A Known Point / ZIP Code Via PHP And MySQL</a>.&#8221; I will therefore have four select lists: A parent list of states; a parent-nee-child list of cities within that state; a child list of ZIP Codes for the selected city; and a fourth list that reflects the coordinates of the ZIP Code.</p>
<p>In truth, there will never be more than one set of coordinates for any given ZIP Code, so this isn&#8217;t technically a four-list parent-child chain. But I wanted to demonstrate how this solution works for any number of lists you may choose to have, and I&#8217;m a bit too lazy to find, upload and clean up new data for this posting alone.</p>
<p>In the case of the data I am using, state, city and ZIP Code are all columns in the same table; the coordinates are a concatenation of longitude and latitude columns. Therefore, this discussion will focus primarily on data in which your select lists represent columns in the same table / view / query results set.</p>
<p>If you have truly relational data &#8212; that is, your select list values exist in unique tables / views that are keyed to each other &#8212; this approach will still work, but the narrative on programming the PHP &#8220;helper page&#8221; will be somewhat irrelevant. If there is interest expressed in approaching this problem with truly relational data, I may expand on this post.</p>
<p>Otherwise, the basic ideas here are exactly the same as those I presented in my original parent-child select list post and <a href="http://www.dougv.com/2009/05/21/parent-child-select-lists-revisited-validating-selected-options-via-jquery-and-php/">my follow-up post on validation</a>. This article effectively summarizes those posts and ties them all together into a single solution.</p>
<h3>HTML Modifications</h3>
<p>To accommodate the hybrid parent-child select lists, we need to add each select list that will be part of our parent-child chain to a common class. We do this not for the purposes of CSS, which is why most people assign an element to a class, but rather to help jQuery pick out of our form all the select lists in the parent-child chain.</p>
<p>In theory, we could have jQuery simply get all select lists, but your form may have select lists that aren&#8217;t part of your parent-child chain. Using a class selector allows us to ensure we only deal with drop down lists that are in the chain.</p>
<p>Each parent select list is going to take on a modified onchange event handler. In this case, the handler will take as its first argument the ID of the target select list  &#8212; that is, the select we intend to populate with new options. The second argument will be the ID of the invoking select list &#8212; that is, the immediate parent of the list that is being populated. Those arguments will be followed by the IDs of every other select that is a parent to the target list.</p>
<p>It is important to get the first two arguments in the correct order, for reasons that will be explained shortly. In other words, the first argument to the bindList() function must always be the ID of the target list, and the second argument must always be the ID of the list sending the request. The remaining parent list arguments can be in any order you like.</p>
<pre class="brush: xml; first-line: 1; title: ; notranslate">
&lt;select id=&quot;state&quot; name=&quot;state&quot; class=&quot;ms&quot; onchange=&quot;bindList('city', 'state')&quot;&gt;
&lt;select id=&quot;city&quot; name=&quot;city&quot; class=&quot;ms&quot; disabled=&quot;disabled&quot; onchange=&quot;bindList('zip', 'city', 'state')&quot;&gt;
&lt;select id=&quot;zip&quot; name=&quot;zip&quot; class=&quot;ms&quot; disabled=&quot;disabled&quot; onchange=&quot;bindList('lat', 'zip', 'city', 'state')&quot;&gt;
&lt;select id=&quot;lat&quot; name=&quot;lat&quot; class=&quot;ms&quot; disabled=&quot;disabled&quot;&gt;
</pre>
<p>Let&#8217;s take a closer look at how we are invoking bindList():</p>
<p>Line 1, the select list declaration for our &#8220;master parent&#8221; list, passes to the bindList() function as its first argument the ID of the list it is populating &#8212; namely, city &#8212; and its second argument is its own ID.</p>
<p>Line 2, a parent-nee-child list, uses as its first argument the ID of the select it will populate (zip), then its own ID (city), and then the name of its parent (state).</p>
<p>Line 3, another parent-nee-child list, first uses the ID of the list it will populate, lat; then its own ID; then all the IDs of its parent and grandparents (city and state).</p>
<p>Line 4, a child list, needs no event handler, because it does not populate any other select.</p>
<p>Some people don&#8217;t like to write event handlers directly into HTML code; you may have team development or abstraction concerns. You could, if you wanted, wire up these handlers using jQuery&#8217;s $(document).ready() method; I&#8217;ve chosen to do it in HTML in order to make things simpler for newer programmers. <a href="http://www.dougv.com/2009/06/22/automatically-wiring-up-xhtml-element-events-on-page-load-with-jquery/">I discuss wiring up event handlers in jQuery in another post</a>.</p>
<p>All four select lists bear the class ms. You can use this class to apply CSS styling if you want; or, you can make it one of several css class declarations for the select lists in your chain. If you use multiple classes, it doesn&#8217;t matter which order they appear, at least not for this solution.</p>
<h3>The bindList() Function</h3>
<p>The first consideration we have when populating multiple select lists is that we need at least two arguments: The ID of the list to be bound, and the ID of the list calling the function. In other words, the minimum number of arguments that must be passed to bindList() is 2, but will often be more.</p>
<p>Again, the first argument must be the ID of the target list, and the second argument must be the ID of the list calling the function. And again, you must pass as arguments to bindList() the IDs of all grandparent lists, too.</p>
<pre class="brush: jscript; title: ; notranslate">
function bindList() {
	if(arguments.length &lt; 2) {
		alert('You did not provide enough arguments to the bindList() function');
	}
</pre>
<p><a href="http://www.dougv.com/2009/06/20/javascript-function-arguments-theyre-an-array-and-you-can-treat-them-as-such/">For more help on using the arguments array, check out this post</a>.</p>
<h3>The clearChildLists() Function</h3>
<p>Assured that we have at least the minimum number of arguments, we next want to depopulate all child lists of the sending select list. We&#8217;ll do that via a function named clearChildLists(), which takes as its arguments whatever arguments were sent to the bindList() function.</p>
<pre class="brush: jscript; title: ; notranslate">
clearChildLists.apply(this, arguments);
</pre>
<p>The clearChildLists function places every list ID in the parent-child chain into an array, using the each() method of jQuery. We have to reassign these elements to a standard JavaScript array because as of this writing, due to the way jQuery works, we can&#8217;t call the arguments array side-by-side with jQuery element notation (I&#8217;m sure this will be cleared up at some point).</p>
<p>We&#8217;ll use nested for loops to first traverse through all the select lists in the parent-child chain, then check their IDs against the ID list sent to this function by bindList(). And select list not in the arguments list will then be appended to a new array, which holds the IDs of child lists. (This is in large part why we need to pass all parent and grandparent ID lists to the bindList() function).</p>
<p>Finally, we will then clear the options in every child list, and set them to have a single, common message, instructing us to select valid parent values.</p>
<pre class="brush: jscript; first-line: 1; title: ; notranslate">
function clearChildLists() {
	//function clears values of all lists in parent-child chain that are not sent as arguments

	var lists = new Array();
	var children = new Array();
	var s;
	var tmp;

	//add all parent-child chain lists to array
	$(&quot;.ms&quot;).each(function() {
		lists.push(this.id);
	});

	//check every parent-child chain select ...
	for(var i = 0; i &lt; lists.length; i++) {
		tmp = false;
		//against the invoking select list and its parents ...
		for(var x = 0; x &lt; arguments.length; x++) {
			//if the chain list is the invoking list or its parent(s), stop
			if(arguments[x] == lists[i]) {
				tmp = true;
				break;
			}
		}
		//if the chain list is not the invoking list or its parent(s), it's a child of the invoking list
		if(!tmp) {
			children.push(lists[i]);
		}
	}

	//if there are any child lists to the invoking list, clear them
	if(children.length &gt; 0) {
		for(var a = 0; a &lt; children.length; a++) {
			addParentSelectMessage(children[a]);
		}
	}
}

function addParentSelectMessage(obj) {
	var s = document.getElementById(obj);
	//remove all options from list
	s.options.length = 0;
	//add option indicating a valid parent value is needed
	s.options[0] = new Option('Select a valid parent value ...', '');
	//disable the list
	s.disabled = true;
}
</pre>
<p>Note that I could have used splice() at line 21, instead of a Boolean and new array, to remove parent select list IDs from the parent-child chain. I have sacrificed some elegance here in order to be more obvious about what is going on inside the function.</p>
<p>We clear the all child list values to protect against a &#8220;middle&#8221; list change.</p>
<p>For example, suppose a user goes though this demo and correctly selects a state, city, ZIP Code and coordinates. He then changes the value of the state list.</p>
<p>That would cause the city list to repopulate, but the previously selected ZIP Code and coordinates lists would retain their values. Those values will be wrong, and we want to indicate as much to the end user.</p>
<h3>Building The Query String</h3>
<p>With the children now clear of values, we can begin building the URL to the helper page. And the way we&#8217;re going to do that is twofold.</p>
<p>First, we want to ensure we have a correct selected value from the sending select list &#8212; if the value isn&#8217;t right, we don&#8217;t want to invoke an AJAX request that&#8217;s going to crap out on us for want of proper values.</p>
<p>If we do have a legitimate sending value, then we&#8217;ll simply iterate all the arguments sent to bindList(), getting their selected values from the respective lists. If we don&#8217;t have a legitimate sending-select value, we clear the target list&#8217;s values and indicate a proper parent value is needed.</p>
<pre class="brush: jscript; title: ; notranslate">
var qs = &quot;list.php?&quot;;
var ok = true;
var s;

//list to be bound with values
var target = &quot;#&quot; + arguments[0];
//list that is invoking this function
var sender = &quot;#&quot; + arguments[1];

//clear child list values
$(target).attr(&quot;disabled&quot;, true);
clearMessage(target);

//change target list to indicate values being retrieved
var s = document.getElementById(arguments[0]);
s.options.length = 0;
s.options[0] = new Option('Getting list ...', '');

if(checkValue(sender)) {
	//build querystring
	for(var i = 1; i &lt; arguments.length; i++) {
		qs += &quot;&amp;&quot; + arguments[i] + &quot;=&quot; + escape($(&quot;#&quot; + arguments[i]).val());
	}

	//http get call to helper page
	var theOptions = new Array();
	$.get(qs, function(data) {
			eval(data);
			//on success, bind list as options
			if(theOptions.length &gt; 0) {
				addOptions(target, theOptions);
			}
		}
	);
}
else {
	//replace with error message on invalid parent option
	s.options.length = 0;
	s.options[0] = new Option('Select a valid parent value ...', '');
}
</pre>
<h3>The PHP Helper Page</h3>
<p>Our PHP helper page checks the query string values it receives to ensure they are in range. And now, because it is going to handle populating multiple lists, we need to determine which arguments the helper page has received, and therefore which SQL command to build.</p>
<pre class="brush: php; title: ; notranslate">
/variable validation
if(!preg_match('/^[A-Z]{2}$/', urldecode($_GET['state']))) {
	$output = &quot;alert('State value not in range');\n&quot;;
}
elseif(isset($_GET['zip']) &amp;&amp; !preg_match('/^[0-9]{5}$/', urldecode($_GET['zip']))) {
	$output = &quot;alert('ZIP Code value not in range');\n&quot;;
}
elseif(isset($_GET['city']) &amp;&amp; !preg_match('/^[\w \']{1,50}$/', urldecode($_GET['city']))) {
	$output = &quot;alert('City value not in range');\n&quot;;
}
elseif(!$link = mysql_connect('server-name', 'username', 'password')) {
	$output = &quot;alert('Could not connect to database');\n&quot;;
}
elseif(!mysql_select_db('database-name')) {
	$output = &quot;alert('Could not select database');\n&quot;;
}
else {
	//inputs OK and connected; let's query
	if(isset($_GET['zip'])) {
		$sql = &quot;SELECT CONCAT(CAST(latitude AS CHAR), ', ', CAST(longitude AS CHAR)) AS latlng FROM php_zip_code_distance WHERE zip_code = '&quot; . mysql_real_escape_string($_GET['zip']) . &quot;' AND state_code = '&quot; . mysql_real_escape_string($_GET['state']) . &quot;' AND city = '&quot; . mysql_real_escape_string($_GET['city']) . &quot;' ORDER BY zip_code&quot;;
	}
	elseif(isset($_GET['city'])) {
		$sql = &quot;SELECT zip_code FROM php_zip_code_distance WHERE state_code = '&quot; . mysql_real_escape_string($_GET['state']) . &quot;' AND city = '&quot; . mysql_real_escape_string($_GET['city']) . &quot;' ORDER BY zip_code&quot;;
	}
	else {
		$sql = &quot;SELECT DISTINCT city FROM php_zip_code_distance WHERE state_code = '&quot; . mysql_real_escape_string($_GET['state']) . &quot;' ORDER BY city&quot;;
	}
</pre>
<p>With the SQL set to go, we can execute our query, get back the results, and send those along to bindList().</p>
<pre class="brush: php; title: ; notranslate">
	if(!$rs = mysql_query($sql)) {
		$output = &quot;alert('Error getting list from database');\n&quot;;
	}
	elseif(mysql_num_rows($rs) == 0) {
		$output = &quot;alert('No records found');\n&quot;;
	}
	else {
		$i = 0;
		while($row = mysql_fetch_array($rs)) {
			if($i % 5 == 0) {
				$output .= &quot;theOptions.push(new Option('--------------------', ''));\n&quot;;
			}
			$output .= &quot;theOptions.push(new Option('$row[0]', '$row[0]'));\n&quot;;
			$i++;
		}
	}
}

header('Content-type: text/plain');
echo $output;
</pre>
<p>Note that I could have used JSON here instead of creating a JavaScript array. JSON would have been far more elegant, but again, I am trying to balance the elegance of this solution against the abilities of most people looking for help with this need. Since far more people are familiar with arrays than JSON, I went with the less efficient array method.</p>
<h3>The Remaining JavaScript Functions</h3>
<p>Once we have values returned from the helper page, addOptions() re-enables the target list, clears it of any current values, then appends the passed options to the target list.</p>
<pre class="brush: jscript; title: ; notranslate">
function addOptions(s, cl) {
	//enable child select and clear current child options
	$(s).removeAttr(&quot;disabled&quot;);
	//repopulate child list with array from helper page
	var list = document.getElementById(s.replace('#', ''));
	list.options.length = 0;
	for(var i = 0; i &lt; cl.length; i++) {
		list.options[i] = new Option(cl[i].text, cl[i].value);
	}
}
</pre>
<p>The checkValue() function ensures we got a valid selection from the sending list. Note that I need this function because I am using valueless separators in my lists; if you do not use that technique, you can alter the code to remove this function and all calls to it.</p>
<pre class="brush: jscript; title: ; notranslate">
function checkValue(obj) {
	//remove current error message
	clearMessage(obj);
	//if there is an invalid choice, place error message, return false
	if($(obj).val() == &quot;&quot;) {
		$(obj).css(&quot;background-color&quot;, &quot;pink&quot;);
		$(obj + &quot;msg&quot;).html(&quot;&amp;laquo; Please make a valid choice&quot;);
		return false;
	}
	return true;
}
</pre>
<p>The clearMessage() function is used to assist with my jQuery-based form validation. If I have an error, I update a span with a warning message for each error, and change the background color of the select list in question; this function &#8220;resets&#8221; such messages by clearing the inner HTML of the span and setting the select list&#8217;s background to white.</p>
<pre class="brush: jscript; title: ; notranslate">
function clearMessage(obj) {
	//clear status message for element
	$(obj + &quot;msg&quot;).html('');
	$(obj).css(&quot;background-color&quot;, &quot;white&quot;);
}
</pre>
<p>Finally, checkForm() ensures that I have valid values selected in all of the parent-child chain select lists. If at least one does not contain a valid value, the function returns false and the form is not processed.</p>
<pre class="brush: jscript; title: ; notranslate">
function checkForm() {
	var obj;
	var ok = true;

	// for every list in the parent-child chain ...
	$(&quot;.ms&quot;).each(function() {
		obj = &quot;#&quot; + this.id;
		//if it does not have a valid value, return false
		if(!checkValue(obj)) {
			ok = false;
		}
	});

	return ok;
}
</pre>
<p>And that completes the code. You can see a working demo here: <a href="http://www.dougv.com/demo/ajax_parent_multi_child_select/index.php">http://www.dougv.com/demo/ajax_parent_multi_child_select/index.php</a></p>
<p>You can download the code used in this demo here: <a href='http://www.dougv.com/wp-content/uploads/2009/06/ajax_parent_multi_child_select.zip'>Parent &#8211; Child Select Lists Revisited: Multiple Parent &#8211; Child Select Lists Via PHP, MySQL And jQuery Demo Code</a></p>
<p>I distribute all code under the GNU GPL version 3.</p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/05/21/parent-child-select-lists-revisited-validating-selected-options-via-jquery-and-php/" rel="bookmark">Parent &#8211; Child Select Lists Revisited: Validating Selected Options Via jQuery And PHP</a> (73.3)</li>
				<li><a href="https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/" rel="bookmark">Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</a> (37.8)</li>
				<li><a href="https://www.dougv.com/2007/01/03/retaining-selections-from-a-single-select-box-in-two-multiple-select-boxes-via-javascript-dom/" rel="bookmark">Retaining Selections From A Single Select Box In Two Multiple Select Boxes Via JavaScript / DOM</a> (34.3)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2009/06/21/parent-child-select-lists-revisited-multiple-parent-child-select-lists-via-php-mysql-and-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parent &#8211; Child Select Lists Revisited: Validating Selected Options Via jQuery And PHP</title>
		<link>https://www.dougv.com/2009/05/21/parent-child-select-lists-revisited-validating-selected-options-via-jquery-and-php/</link>
		<comments>https://www.dougv.com/2009/05/21/parent-child-select-lists-revisited-validating-selected-options-via-jquery-and-php/#comments</comments>
		<pubDate>Thu, 21 May 2009 18:02:58 +0000</pubDate>
		<dc:creator>Doug Vanderweide</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[drop down / select list]]></category>

		<guid isPermaLink="false">http://www.dougv.com/blog/?p=2078</guid>
		<description><![CDATA[Recently received via e-mail, in response to my previous blog entry, &#8220;Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control&#8220;: Would you be interested in modifying your solution in 2 ways. One would be to have it contain a country downdown as well. So [...]<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/" rel="bookmark">Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</a> (45)</li>
				<li><a href="https://www.dougv.com/2007/01/03/retaining-selections-from-a-single-select-box-in-two-multiple-select-boxes-via-javascript-dom/" rel="bookmark">Retaining Selections From A Single Select Box In Two Multiple Select Boxes Via JavaScript / DOM</a> (23.5)</li>
				<li><a href="https://www.dougv.com/2006/12/05/javascript-handling-multiple-selections-in-a-select-box/" rel="bookmark">JavaScript: Handling Multiple Selections In A Select Box</a> (18.7)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p>Recently received via e-mail, in response to my previous blog entry, &#8220;<a href="http://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/">Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</a>&#8220;:</p>
<blockquote><p>Would you be interested in modifying your solution in 2 ways. One would be to have it contain a country downdown as well. So it would be parent, child, child. I looked into attempting it myself, but my head began spinning as I began looking at all the code. The next option that would be nice, would be to have some sort of Dropdown Validation. Once the state is selected and the city is not  yet selected, i am able to hit the submit button. So, it would be nice to see a message that says &#8220;Please fill choose a city&#8221;. &#8230;</p>
<p>Thank you,</p>
<p>Brian</p></blockquote>
<p>I&#8217;m actually going to address this in two posts, because the first request &#8212; nested parent-child select lists &#8212; will take a bit more time to demo and describe than I have at the moment.</p>
<p>However, form validation &#8212; namely, ensuring the user chooses valid parent and child values from each select list &#8212; is something I can describe quickly and without extensive coding. And it&#8217;s a subject I should address, since my previous post noted that server-side validation was important to this solution, but I didn&#8217;t describe how to do it.</p>
<p><span id="more-2078"></span></p>
<h3>jQuery Form Validation</h3>
<p>The old-school way to validate a form in JavaScript is to invoke the onsubmit event of the form element.</p>
<p>That is, we simply create a JavaScript function that checks whether the selected options within the parent and child lists have a non-empty-string value. If either contained an empty value, we would pop up an alert and shift focus to the select that needs a valid option chosen.</p>
<p>But we&#8217;ve already incurred the overhead of jQuery, so why not spice things up a bit? Rather than using an ugly old alert, let&#8217;s really draw the user&#8217;s attention to elements that need correcting.</p>
<p>In this case, we&#8217;ll turn the list with a bad value pink, and append on a message asking the user to select a proper option.</p>
<p>To do that, we first need to add a couple of span elements to our form, one following each of the select elements, to receive the error message when appropriate.</p>
<p>Why span elements? Because div elements are properly used to group sections of markup; that&#8217;s why you use them to control layout. And a p or other text element would require extensive formatting to get to line up properly in relation to other form elements. A span is intended to mark HTML for some sort of special consideration; and that&#8217;s exactly what we are doing here, showing text under special conditions.</p>
<p>We also need to add a new event handler for the child list; it calls a yet-to-be-defined function called checkOption(), which takes as its argument the id of the select. I have also added a handler for the form&#8217;s onsubmit event, which will also be described momentarily. Finally, I have added a submit button, so the form can be posted.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;form id=&quot;form1&quot; name=&quot;form1&quot; method=&quot;post&quot; action=&quot;&lt;?php echo htmlentities($_SERVER['PHP_SELF']); ?&gt;&quot; onsubmit=&quot;return checkForm();&quot;&gt;
    &lt;label&gt;
        Select a state:&amp;nbsp;
        &lt;select id=&quot;state&quot; name=&quot;state&quot; onchange=&quot;bindCity()&quot;&gt;
            &lt;!-- php code to insert parent records goes here --&gt;
        &lt;/select&gt;
        &lt;span id=&quot;statemsg&quot; class=&quot;warning&quot;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;br /&gt;
    &lt;label&gt;
        Select a city:&amp;nbsp;
        &lt;select id=&quot;city&quot; name=&quot;city&quot; disabled=&quot;disabled&quot; onchange=&quot;checkOption('#city')&quot;&gt;
            &lt;option&gt;Select a state ...&lt;/option&gt;
        &lt;/select&gt;
    &lt;/label&gt;
    &lt;span id=&quot;citymsg&quot; class=&quot;warning&quot;&gt;&lt;/span&gt;
    &lt;br /&gt;
    &lt;input type=&quot;submit&quot; id=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
&lt;/form&gt;
</pre>
<p>Note that each new span gets an id attribute that starts with the id of one of the lists and ends in &#8220;msg.&#8221; That&#8217;s because we want to be able to efficiently associate each span with its attendant select.</p>
<p>If we use the id of the select and append some other string to it &#8212; e.g., &#8220;state&#8221; + &#8220;msg&#8221; = &#8220;statemsg&#8221;, &#8220;city&#8221; + &#8220;msg&#8221; = &#8220;citymsg&#8221; &#8212; then we can easily use the same JavaScript function to handle validation of both lists.</p>
<h3>The JavaScript Functions</h3>
<p>We&#8217;ll need three JavaScript functions to complete this task, and we need to amend the bindCity() function slightly to accommodate this validation scheme.</p>
<p>The first step is writing a function that will clear the error message span for either list, and set the background color of the select in question back to white.</p>
<pre class="brush: jscript; title: ; notranslate">
function clearMessage(s) {
	//clear status message for element
	$(s + &quot;msg&quot;).html('');
	$(s).css(&quot;background-color&quot;, &quot;white&quot;);
}
</pre>
<p>Note that at line 3, we concatenate the argument of the function &#8212; in this case, the id of the select in question &#8212; with &#8220;msg&#8221;, in order to get the id of the span we want to clear.</p>
<p>The checkOption() function, previously noted, does the actual validating. First, it clears the error message for the select in question; next, it sees if the selected option has an empty string for a value. If the value is empty, then we set the background color of the select to pink, add an error message, and disable the submit button.</p>
<pre class="brush: jscript; title: ; notranslate">
function checkOption(s) {
	clearMessage(s);
	//invalid choice
	if($(s).val() == &quot;&quot;) {
		//place error message, colorize select list, disable submit button
		$(s).css(&quot;background-color&quot;, &quot;pink&quot;);
		$(s + &quot;msg&quot;).html(&quot;&amp;laquo; Please make a valid choice&quot;);
		$(&quot;#submit&quot;).attr(&quot;disabled&quot;, true);
		return false;
	}
	//element OK, enable submit button
	$(&quot;#submit&quot;).removeAttr(&quot;disabled&quot;);
	return true;
}
</pre>
<p>We need one more function. Because we&#8217;re using the onchange event handler to trigger validation for each list, it&#8217;s possible the user will simply submit the form immediately after page load, without making a selection; it&#8217;s also possible he will submit the form after selecting a proper parent option, but not a valid child option.</p>
<p>So, it turns out we still need a handler for the form&#8217;s onsubmit event. This function will call checkOption() for each of the selects; if both pass, the form is submitted; otherwise, the submit button is disabled and the form is not processed.</p>
<pre class="brush: jscript; title: ; notranslate">
function checkForm() {
	//check both select lists for valid values
	var ok1 = checkOption('#state');
	var ok2 = checkOption('#city');
	if(ok1 &amp;&amp; ok2) {
		return true;
	}
	else {
		//bad option in one or both lists, disable submit button
		$(&quot;#submit&quot;).attr(&quot;disabled&quot;, true);
		return false;
	}
}
</pre>
<p>Finally, we need to tweak the bindCity() function to use our new form validation scheme. We do that by calling clearMessage(), then using checkOption() to see if the state select has a non-empty value. If so, we go ahead and update the child list.</p>
<pre class="brush: jscript; title: ; notranslate">
function bindCity() {
	//disable child select list
	$(&quot;#city&quot;).attr(&quot;disabled&quot;, true);
	//clear error message if it exists
	clearMessage(&quot;#city&quot;);

	//check selection
	if(checkOption(&quot;#state&quot;)) {
		//clear child select list's options
		$(&quot;#city&quot;).html('');

		//querystring value is selected value of parent drop down list
		var qs = $(&quot;#state&quot;).val();
		//show message indicating we're getting new values
		$(&quot;#city&quot;).append(new Option('Getting city list ...'));
		//declare options array and populate
		var cityOptions = new Array();
		$.get(&quot;citylist.php?statecode=&quot; + qs, function(data) {
				eval(data);
				if(cityOptions.length &gt; 0) {
					addOptions(cityOptions);
				}
			}
		);
	}
	else {
		$(&quot;#city&quot;).val() = '';
	}
}
</pre>
<p>And with that, we have a fully functional, jQuery-powered, pretty-in-pink validation script.</p>
<h3>PHP Validation</h3>
<p>While it&#8217;s a lot less glamorous, validating our inputs with PHP is far more important than a jQuery validation script. Remember, users can not only disable JavaScript, they can add, modify and delete any JavaScript on / to your page. Therefore, we need to ensure any form values we get back from a page are in range &#8212; that is, contain values we anticipate getting.</p>
<p>The easiest way to do that is with regular expressions.</p>
<p><em>A quick aside on sanitizing form values in PHP:</em> PHP 5.2.0 and later ships with <a href="http://www.php.net/manual/en/book.filter.php">data filtering extensions</a> built in. These filters and sanitizers are exceedingly handy, and at some point I will demonstrate using them. For now, because this problem is so limited in scope, I&#8217;m going to use <a href="http://www.php.net/manual/en/book.pcre.php">PCRE</a>.</p>
<p>We know the value of state should be two capital letters, and the value of city should be a mix of capital and lower-case letters, with an occasional apostrophe, period or space. So, a  couple of regular expressions nested in an if-else statement is all we need for validation</p>
<pre class="brush: php; title: ; notranslate">
	if(isset($_POST['submit'])) {
		if(!preg_match('/^[A-Z]{2}$/', $_POST['state'])) {
			echo &quot;&lt;p&gt;&lt;strong&gt;You did not select a proper state option. Please try again.&lt;/strong&gt;&lt;/p&gt;\n&quot;;
		}
		elseif(!preg_match('/^[A-Za-z\'\.\s]{3,25}$/', $_POST['city'])) {
			echo &quot;&lt;p&gt;&lt;strong&gt;You did not select a proper city option. Please try again.&lt;/strong&gt;&lt;/p&gt;\n&quot;;
		}
		else {
			echo &quot;&lt;p&gt;You selected $_POST[city], $_POST[state].&lt;/p&gt;\n&quot;;
		}
	}
</pre>
<p>And that&#8217;s all there is to it. You can see a working demo here:</p>
<p><a href="http://www.dougv.com/demo/ajax_parent_child_select_1">http://www.dougv.com/demo/ajax_parent_child_select_1</a></p>
<p>To test just the PHP part of the script, simply disable JavaScript.</p>
<p>I distribute all code under the GNU GPL Version 3. There&#8217;s no download file this time; when I do the multiple child select list demo, I&#8217;ll provide a download file that encompasses this entry.</p>
<p>All links in this entry on delicious: <a href="http://delicious.com/dhvrm/parent-child-select-lists-revisited-validating-selected-options-via-jquery-and-php">http://delicious.com/dhvrm/parent-child-select-lists-revisited-validating-selected-options-via-jquery-and-php</a></p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/" rel="bookmark">Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</a> (45)</li>
				<li><a href="https://www.dougv.com/2007/01/03/retaining-selections-from-a-single-select-box-in-two-multiple-select-boxes-via-javascript-dom/" rel="bookmark">Retaining Selections From A Single Select Box In Two Multiple Select Boxes Via JavaScript / DOM</a> (23.5)</li>
				<li><a href="https://www.dougv.com/2006/12/05/javascript-handling-multiple-selections-in-a-select-box/" rel="bookmark">JavaScript: Handling Multiple Selections In A Select Box</a> (18.7)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2009/05/21/parent-child-select-lists-revisited-validating-selected-options-via-jquery-and-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control</title>
		<link>https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/</link>
		<comments>https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 05:06:10 +0000</pubDate>
		<dc:creator>Doug Vanderweide</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[drop down / select list]]></category>

		<guid isPermaLink="false">http://www.dougv.com/blog/?p=1890</guid>
		<description><![CDATA[Recently asked on Yahoo! Answers: How to generate a submenu on the basis of value in a menu without refreshing the page? I want to use if else construct to generate a submenu on the basis of value from a textfield in the same form. You can get it in the way that when someone [...]<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2007/04/02/changing-an-iframe-source-from-a-drop-down-list-via-javascript-dom/" rel="bookmark">Changing An IFrame Source From A Drop-Down List Via JavaScript / DOM</a> (31.2)</li>
				<li><a href="https://www.dougv.com/2007/06/22/going-to-a-new-url-via-a-drop-down-list-javascript-and-dom-php-aspnet/" rel="bookmark">Going To A New URL Via A Drop-Down List: JavaScript And DOM, PHP, ASP.NET</a> (30.7)</li>
				<li><a href="https://www.dougv.com/2009/02/07/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control/" rel="bookmark">Revisited: Adding Non-Selectable ListItem Controls To An ASP.NET DataBound List Control</a> (26.9)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p>Recently asked on Yahoo! Answers:</p>
<blockquote><p><strong><a href="http://answers.yahoo.com/question/index?qid=20090422015439AAfM2R7">How to generate a submenu on the basis of value in a menu without refreshing the page?</a></strong><br />
I want to use if else construct to generate a submenu on the basis of value from a textfield in the same form. You can get it in the way that when someone selects a country in a field&#8230;the states menu of the form changes according to the country selected.</p></blockquote>
<p>This question, rephrased: You have two HTML select lists; one contains parent values &#8212; for example, a list of states &#8212; and the other will contain child values &#8212; say, a list of cities in the selected state. Every time the value in the parent drop down list is changed, the values in the child drop down list are also changed. (I&#8217;ll be using the terms <em>select list</em> and <em>drop down list</em> interchangeably.)</p>
<p>This is a fairly common programming problem, and there are lots of examples out on the Web on how to solve it. So why write another one?</p>
<p>Primarily, because this question is so common. Most of the questioners on Yahoo! Answers are beginners, and as a result, a significant number don&#8217;t necessarily know how to phrase a Web search to find a tutorial. Far easier, then, to demonstrate the technique here and simply refer Yahoo! Answers users to this blog entry.</p>
<p>The executive summary: We&#8217;ll use AJAX to query a database seamlessly in the background every time the value of the parent select list is changed. More specifically, we&#8217;ll use the <a href="http://jquery.com/">jQuery</a> library to handle the AJAX requests, bind the child list and make sure the form can&#8217;t be processed until the request is complete.</p>
<p><span id="more-1890"></span></p>
<h4>Before We Start: You Need Relational Data</h4>
<p>In order to have parent and child drop down lists, you must have parent and child data that is relational. In other words, whatever is going to appear as an option in the child drop down list has to be determined by some value in the parent list.</p>
<p>I know this sounds obvious, but you need to plan your data properly for a parent / child select list scheme to work. For example, suppose you have a parent select list which contains all the world&#8217;s manufacturers of automobiles. You want the child drop down&#8217;s options to be all the car models made by the manufacturer selected in the parent drop down list.</p>
<p>To do that, you have to have data that keys car models to their manufacturers. You can do that a couple of ways:</p>
<ol>
<li>You might have just a table of car models, which contains a column of standardized values for each manufacturer (in other words, for all cars made by Ford, &#8220;Ford&#8221; is the only value in the manufacturer column of your car models table).</li>
<li>You might have two tables, one of manufacturers and another of models, where the model table has a foreign key to the manufacturer table.</li>
<li>You have some other structured data source, such as an array or a class, that groups firmly together the manufacturers and models of cars they make.</li>
</ol>
<p>Once more: You must have a way to take a value from the parent list and equate it to some subset of child records. And that, in short, means relational data.</p>
<h4>Step 1: Get jQuery</h4>
<p>If you don&#8217;t already have a copy of jQuery on your Web site, you&#8217;ll need to download it. It&#8217;s free from <a href="http://docs.jquery.com/Downloading_jQuery">http://docs.jquery.com/Downloading_jQuery</a>. Either the &#8220;minified&#8221; or uncompressed version is fine; elegance dictates downloading the &#8220;minified&#8221; version.</p>
<p>Once you&#8217;ve downloaded the file, upload it to your Web site. Then, create a script tag in your Web page&#8217;s head section that imports the jQuery library:</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot; src=&quot;jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
</pre>
<h4>Step 2: Create The Select Lists</h4>
<p>With the jQuery library on the page, we can now create the parent select list and its child.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;form id=&quot;form1&quot; name=&quot;form1&quot; method=&quot;post&quot; action=&quot;&lt;?php echo htmlentities($_SERVER['PHP_SELF']); ?&gt;&quot;&gt;
    &lt;label&gt;
        Select a state:&amp;nbsp;
        &lt;select id=&quot;state&quot; name=&quot;state&quot; onchange=&quot;bindCity()&quot;&gt;
            &lt;!-- php code to get state list goes here --&gt;
        &lt;/select&gt;
    &lt;/label&gt;
    &lt;br /&gt;
    &lt;label&gt;
        Select a city:&amp;nbsp;
        &lt;select id=&quot;city&quot; name=&quot;city&quot; disabled=&quot;disabled&quot;&gt;
            &lt;option&gt;Select a state ...&lt;/option&gt;
        &lt;/select&gt;
    &lt;/label&gt;
    &lt;br /&gt;
    &lt;input id=&quot;submitform&quot; name=&quot;submitform&quot; type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
&lt;/form&gt;
</pre>
<p>We will create the values for the parent select list using a normal PHP script on the page. That&#8217;s because no matter what, we need to get the values for the parent drop down list every time the page is loaded; and the values in the parent select list will never change.</p>
<p>I&#8217;m going to use states and cities for my data. Specifically, I will be getting the parent values &#8212; states &#8212; and child values &#8212; all the cities in the selected state &#8212; from the ZIP Codes table I created a few weeks ago, for the blog entry titled, &#8220;<a href="http://www.dougv.com/2009/03/27/getting-all-zip-codes-in-a-given-radius-from-a-known-point-zip-code-via-php-and-mysql/">Getting All ZIP Codes In A Given Radius From A Known Point / ZIP Code Via PHP And MySQL</a>.&#8221;</p>
<p>I&#8217;m also going to use a variation on another previous post, &#8220;<a href="http://www.dougv.com/2009/02/07/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control/">Revisited: Adding Non-Selectable ListItem Controls To An ASP.NET DataBound List Control</a>&#8220;, to help break up these long lists.</p>
<p>Doing that is simple: We just declare a counter variable, increment it by one every time we read a record, and see if the modulus of that counter variable divided by five is zero. If it is, we output a dashed line.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
//error if cannot connect to db server
if(!$link = mysql_connect('server', 'username', 'password')) {
	echo &quot;&lt;option&gt;Cannot connect to database server&lt;/option&gt;\n&quot;;
}
//error if cannot select database
elseif(!mysql_select_db('database')) {
	echo &quot;&lt;option&gt;Cannot select database&lt;/option&gt;\n&quot;;
}
else {
	//error if problem parsing query
	if(!$rs = mysql_query(&quot;SELECT DISTINCT state, state_code FROM php_zip_code_distance ORDER BY state&quot;)) {
		echo &quot;&lt;option&gt;Error getting state values from database&lt;/option&gt;\n&quot;;
	}
	//error if query returns no records
	elseif(mysql_num_rows($rs) == 0) {
		echo &quot;&lt;option&gt;No records found&lt;/option&gt;\n&quot;;
	}
	else {
		//ouput records
		$i = 0;
		while($row = mysql_fetch_array($rs)) {
			//create separator every five records
			if($i % 5 == 0) {
				echo &quot;&lt;option value=\&quot;\&quot;&gt;--------------------&lt;/option&gt;\n&quot;;
			}
			echo &quot;&lt;option value=\&quot;$row[state_code]\&quot;&gt;$row[state]&lt;/option&gt;\n&quot;;
			$i++;
		}
	}
}
?&gt;
</pre>
<h4>Step 3: The citylist.php &#8220;Helper&#8221; Script</h4>
<p>We&#8217;re going to need a PHP &#8220;helper&#8221; script, which will receive from our yet-to-be-written AJAX request the name of the selected state, and returns a listing of all the cities in that state.</p>
<p>This is basically just a normal PHP page, except instead of outputting our results as HTML, we&#8217;re going to send the results as plain text &#8212; or, more specifically, as text we can process as JavaScript.</p>
<p>More on how we do that processing in a bit. Let&#8217;s focus now on getting the relevant records. Our helper script does the following:</p>
<ul>
<li>Uses a regular expression to check if there is a GET variable named statecode that consists of two capital letters. If not, the script alerts us to that fact.</li>
<li>Connects to the database server and selects the database, or reports errors if either cannot be done.</li>
<li>Selects all city records for the given state code (which we ensured was in the proper format with our first step), and reports if there was a database error or no records were found.</li>
<li>Adds all the city records to a JavaScript array (we&#8217;ll discuss that shortly), with periodic separators as we did for the parent select list.</li>
</ul>
<pre class="brush: php; title: ; notranslate">
&lt;?php
//create error if statecode query string is not present or not two capital letters
if(!preg_match('/[A-Z]{2}/', $_GET['statecode'])) {
	$output = &quot;alert('Input pattern incorrect');\n&quot;;
}
//error if cannot connect to db server
elseif(!$link = mysql_connect('server', 'username', 'password')) {
	$output = &quot;alert('Could not connect to database');\n&quot;;
}
//error if cannot select database
elseif(!mysql_select_db('database')) {
	$output = &quot;alert('Could not select database');\n&quot;;
}
else {
	//error if query for child records cannot be parsed
	if(!$rs = mysql_query(&quot;SELECT DISTINCT city FROM php_zip_code_distance WHERE state_code = '$_GET[statecode]' AND TRIM(city) != '' ORDER BY city LIMIT 80&quot;)) {
		$output = &quot;alert('Error getting city list from database');\n&quot;;
	}
	//error if no matching records found for state code
	elseif(mysql_num_rows($rs) == 0) {
		$output = &quot;alert('No records found');\n&quot;;
	}
	else {
		//if child records found, output results to JavaScript array of Option objects
		$i = 0;
		while($row = mysql_fetch_array($rs)) {
			//create a non-selectable separator every five entries
			if($i % 5 == 0) {
				$output .= &quot;cityOptions.push(new Option('--------------------', ''));\n&quot;;
			}
			$output .= &quot;cityOptions.push(new Option('$row[city]', '$row[city]'));\n&quot;;
			$i++;
		}
	}
}
//return results
header('Content-type: text/plain');
echo $output;
?&gt;
</pre>
<h4>Step 4: The bindCity() JavaScript Function</h4>
<p>We&#8217;re ready to get jQuery to send to the helper page a request for the child records &#8212; again, in this example, a listing of all cities within the selected state. Our function will:</p>
<ul>
<li>Disable the child list, so that incorrect / inappropriate selections cannot be made while we wait for new records.</li>
<li>Clear the current values of the child list, in preparation of new values.</li>
<li>Presents a message to the user that we are getting new child records.</li>
<li>Gets the value of the selected item in the parent drop down list. If that value is an empty string (i.e., a separator), the script indicates the option is invalid. Otherwise, it appends the parent select list&#8217;s value as the value of the statecode GET variable.</li>
<li>The helper script is called, its results evaluated as JavaScript, and a second function &#8212; addOptions &#8212; is called to populate the child list, provided we got options back from the database.</li>
</ul>
<pre class="brush: jscript; title: ; notranslate">
function bindCity() {
	//disable child select list
	$(&quot;#city&quot;).attr(&quot;disabled&quot;, true);
	//clear child select list's options
	$(&quot;#city&quot;).html('');

	//querystring value is selected value of parent drop down list
	var qs = $(&quot;#state&quot;).val();
	//if user selected a separator, show error
	if(qs == '') {
		alert('You cannot select this option. Please make a different selection.');
	}
	else {
		//show message indicating we're getting new values
		$(&quot;#city&quot;).append(new Option('Getting city list ...'));
		//declare options array and populate
		var cityOptions = new Array();
		$.get(&quot;citylist.php?statecode=&quot; + qs, function(data) {
				eval(data);
				if(cityOptions.length &gt; 0) {
					addOptions(cityOptions);
				}
			}
		);
	}
}
</pre>
<p>The addOptions() function accepts as an argument the list of options we got from the database. It then re-enables the child select list, clears all its current options (namely, the message we sent in bindCity(), saying we were getting the child records) and then adds all the available options.</p>
<p>Unfortunately, due to a limitation in Internet Explorer, we cannot use jQuery notation to add options to the child select list; we have to use old-school DOM scripting. This is especially disappointing as Jim O&#8217;Neil of Microsoft has <a href="http://blogs.msdn.com/jimoneil/archive/2008/10/15/microsoft-and-open-source.aspx">stated on his blog</a>, and in my presence on more than one occasion, that Microsoft is committed to jQuery&#8217;s development. A DOM manipulation technique as simple and straightforward as appending options to a select list ought to be supported by IE.</p>
<pre class="brush: jscript; title: ; notranslate">
function addOptions(cl) {
	//enable child select and clear current child options
	$(&quot;#city&quot;).removeAttr(&quot;disabled&quot;);
	$(&quot;#city&quot;).html('');
	//repopulate child list with array from helper page
	var city = document.getElementById('city');
	for(var i = 0; i &lt; cl.length; i++) {
		city.options[i] = new Option(cl[i].text, cl[i].value);
	}
}
</pre>
<p>And that&#8217;s all there is to it.</p>
<p>You can see a working demo here: <a href="http://www.dougv.com/demo/ajax_parent_child_select/">http://www.dougv.com/demo/ajax_parent_child_select/</a></p>
<p>You can download the PHP pages &#8212; both the form containing the parent / child select lists and the helper page &#8212; from here: <a href='http://www.dougv.com/wp-content/uploads/2009/04/ajax_parent_child_select.zip'>Using AJAX To Data Bind A Child Drop Down List Based On The Selected Option Of A Parent Select Control Demo Code</a>. I distribute all code under the GNU GPL.</p>
<p>All links in this post on delicious: <a href="http://delicious.com/dhvrm/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control">http://delicious.com/dhvrm/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control</a></p>
<h4>Two Quick Postscripts</h4>
<p>Note that this solution requires JavaScript to work. As such, if you are going to send the values of these select lists to a server-side script (e.g., a PHP page), you will want to be extra careful to ensure you get values from the child list, and that any such values are sanitized by your server script &#8212; since users can easily amend the values sent to your form via JavaScript.</p>
<p>Also, if you want to use the data for this example, you will need to follow the process noted in Step 1 of the my post titled, &#8220;<a href="http://www.dougv.com/2009/03/27/getting-all-zip-codes-in-a-given-radius-from-a-known-point-zip-code-via-php-and-mysql/">Getting All ZIP Codes In A Given Radius From A Known Point / ZIP Code Via PHP And MySQL</a>.&#8221;</p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2007/04/02/changing-an-iframe-source-from-a-drop-down-list-via-javascript-dom/" rel="bookmark">Changing An IFrame Source From A Drop-Down List Via JavaScript / DOM</a> (31.2)</li>
				<li><a href="https://www.dougv.com/2007/06/22/going-to-a-new-url-via-a-drop-down-list-javascript-and-dom-php-aspnet/" rel="bookmark">Going To A New URL Via A Drop-Down List: JavaScript And DOM, PHP, ASP.NET</a> (30.7)</li>
				<li><a href="https://www.dougv.com/2009/02/07/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control/" rel="bookmark">Revisited: Adding Non-Selectable ListItem Controls To An ASP.NET DataBound List Control</a> (26.9)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2009/04/24/using-ajax-to-data-bind-a-child-drop-down-list-based-on-the-selected-option-of-a-parent-select-control/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Moving ListItems From A ComboBox / DropDownList To A ListBox In .NET</title>
		<link>https://www.dougv.com/2009/02/21/moving-listitems-from-a-combobox-dropdownlist-to-a-listbox-in-net/</link>
		<comments>https://www.dougv.com/2009/02/21/moving-listitems-from-a-combobox-dropdownlist-to-a-listbox-in-net/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 06:43:44 +0000</pubDate>
		<dc:creator>Doug Vanderweide</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[drop down / select list]]></category>

		<guid isPermaLink="false">http://www.dougv.com/blog/?p=1727</guid>
		<description><![CDATA[Recently asked on Yahoo! Answers: ComboBox Question in Visual Basic? I am trying to create a combobox dropdown list of countries. When user click on a country, it should add to the listbox. I manage to do it. But I want to enhance some form of checking. If the country is already added in the [...]<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2008/08/10/adding-non-selectable-listitems-to-an-aspnet-dropdownlist-control/" rel="bookmark">Adding Non-Selectable ListItems To An ASP.NET DropDownList Control</a> (34.5)</li>
				<li><a href="https://www.dougv.com/2007/01/15/dynamically-populating-a-listbox-from-a-textbox-via-javascript-dom/" rel="bookmark">Dynamically Populating A Listbox From A Textbox Via JavaScript / DOM</a> (22.4)</li>
				<li><a href="https://www.dougv.com/2009/02/07/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control/" rel="bookmark">Revisited: Adding Non-Selectable ListItem Controls To An ASP.NET DataBound List Control</a> (10.1)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p>Recently asked on Yahoo! Answers:</p>
<blockquote><p>
<strong><a href="http://answers.yahoo.com/question/index?qid=20090220194334AAJXhOP">ComboBox Question in Visual Basic?</a></strong><br />
I am trying to create a combobox dropdown list of countries. When user click on a country, it should add to the listbox. I manage to do it. But I want to enhance some form of checking. If the country is already added in the listbox, the user should not be able to select the same country again. These are my codes, but it won&#8217;t work. I don&#8217;t know what&#8217;s wrong. Can someone please help? Thanks!</p>
<p>For Each country As String In lstCountry.Items<br />
If country Is cbxCountries.SelectedItem Then<br />
MsgBox(&#8220;County already selected.&#8221;, MsgBoxStyle.Information, )<br />
Else<br />
lstCountry.Items.Add(cbxCountries.Select&#8230;<br />
End If<br />
Next
</p></blockquote>
<p>Thanks to .NET&#8217;s totally object-oriented approach to programming &#8212; especially its <a href="http://en.wikipedia.org/wiki/Module_(programming)">modularity</a>, <a href="http://en.wikipedia.org/wiki/Encapsulation_(computer_science)">encapsulation</a> and <a href="http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming">polymorphism</a> &#8212; moving the selected value of a <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.aspx">ComboBox</a> (in ASP.NET, a <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.dropdownlist.aspx">DropDownList</a>) control to a <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.aspx">ListBox</a> control takes three lines of code. And removing that same item from the ComboBox takes just one more line.</p>
<p>Because I want to demo this, I&#8217;ll be writing this in ASP.NET. However, it will translate just fine to Windows Forms, as well; the questioner doesn&#8217;t state which he&#8217;s using, but my guess is it&#8217;s Windows Forms, since he&#8217;s using a ComboBox control.</p>
<p><span id="more-1727"></span></p>
<h4>The Power Of Object-Oriented Code</h4>
<p>Some quick notes before we start with the coding.</p>
<p>Most of what I am about to do will translate fine to Windows Forms. However, ASP.NET and Windows Forms aren&#8217;t the same thing. Most important, the ComboBox and ListItem controls in Windows Forms can basically use any object as their options; but in ASP.NET, both a DropDownList and a ListBox use the ListItem class.</p>
<p>That might seem like a huge problem for demonstration purposes, but thanks to encapsulation and polymorphism, it doesn&#8217;t really matter.</p>
<p>In the case of Windows Forms, options in a ComboBox or ListBox are stored in an <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.objectcollection.aspx">ObjectCollection</a>; in ASP.NET, options for DropDownList and ListBox controls are stored in a <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listitemcollection.aspx">ListItemCollection</a>. Those collections pretty much share the same methods and properties; the parent controls have the same methods and properties for addressing those collections, too.</p>
<p>So while the controls we will use are different between ASP.NET and Windows Forms, the code we use in either case is almost exactly the same. That&#8217;s the strength of object-oriented programming.</p>
<p>Finally, from here on out, unless I state otherwise, I will be using &#8220;ComboBox&#8221; and &#8220;DropDownList&#8221; interchangeably.</p>
<p>OK, on with the code.</p>
<h4>Step 1: The ComboBox And ListBox Controls</h4>
<p>As I just noted, we need to create the ComboBox (DropDownList) control that contains our initial values, plus a ListBox control. You do this as you normally would in Windows Forms: Most people drag the controls from the toolbox onto the form, then set the properties as required.</p>
<p>In the case of ASP.NET, we simply declare a DropDownList and ListBox control on our ASPX page, and add ListItem controls to the DropDownList.</p>
<p>We need to have, as the first item in the ComboBox / DropDownList, a non-selectable item. (You can read <a href="http://www.dougv.com/2009/02/07/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control/">my previous entry on non-selectable ListItems</a> for exotic ways to accomplish this task; here, it&#8217;s simply an option with no value).</p>
<p>We need to do this because we&#8217;ll be removing the selected options from the ComboBox, which will reset the selected index of the ComboBox to be the first item. That means, if we have a list of 10 things, we could only move nine of them; the 10th item would be selected once we remove the 9th item, and therefore, we wouldn&#8217;t be able to fire the SelectedIndexChanged event; there aren&#8217;t any other options to select.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;cbxCountries&quot; AutoPostBack=&quot;true&quot;&gt;
	&lt;asp:ListItem Text=&quot;Select ...&quot; Value=&quot;&quot; /&gt;
	&lt;asp:ListItem Value=&quot;USA&quot; /&gt;
	&lt;asp:ListItem Value=&quot;Canada&quot; /&gt;
	&lt;asp:ListItem Value=&quot;Mexico&quot; /&gt;
	&lt;asp:ListItem Value=&quot;Guatemala&quot; /&gt;
	&lt;asp:ListItem Value=&quot;Belize&quot; /&gt;
	&lt;asp:ListItem Value=&quot;El Salvador&quot; /&gt;
	&lt;asp:ListItem Value=&quot;Honduras&quot; /&gt;
	&lt;asp:ListItem Value=&quot;Nicaragua&quot; /&gt;
	&lt;asp:ListItem Value=&quot;Costa Rica&quot; /&gt;
	&lt;asp:ListItem Value=&quot;Panama&quot; /&gt;
&lt;/asp:DropDownList&gt;

&lt;asp:ListBox runat=&quot;server&quot; ID=&quot;lstCountries&quot; Rows=&quot;10&quot; /&gt;
</pre>
<p>(Note that I have to add an AutoPostBack attribute to the DropDownMenu control, so that changing the selected index of the DropDownList will make the page post back to the server. Of course, there&#8217;s no such property for a ComboBox.)</p>
<h4>Step 2: The Code</h4>
<p>As noted above, doing what the questioner wants is as simple as creating an OnSelectedIndexChanged event handler for the ComboBox control.</p>
<p>And as previously noted, we can use fundamentally the same code to accomplish this task in ASP.NET or Windows Forms. In the case of ASP.NET, we&#8217;re working with a ListItem control; in Windows Forms, a generic Object. The code below is set for ASP.NET, just comment out its line and comment in the correct one.</p>
<pre class="brush: vb; title: ; notranslate">
Sub cbxCountries_selectedIndexChanged(ByVal Sender As Object, ByVal E As EventArgs) Handles cbxCountries.SelectedIndexChanged
	If Not String.IsNullOrEmpty(cbxCountries.SelectedValue) Then
		'reset selected index for listbox; this is required for adding new listitems
		lstCountries.SelectedIndex = -1

		'ASP.NET version: add selected listitem to listbox
		Dim lsiSelected As ListItem = cbxCountries.Items(cbxCountries.SelectedIndex)

		'Windows Forms version: add selected listitem to listbox
		'Dim lsiSelected As Object = cbxCountries.Items(cbxCountries.SelectedIndex)

		lstCountries.Items.Add(lsiSelected)

		'remove selected from combobox
		cbxCountries.Items.RemoveAt(cbxCountries.SelectedIndex)
	End If
End Sub
</pre>
<p>The code above does the following:</p>
<ul>
<li>We first check to see if the value of the selected option is an empty string. We do that because we don&#8217;t want to insert the &#8220;Select &#8230;&#8221; option into our ListBox. Again, the &#8220;Select &#8230;&#8221; item exists to ensure our OnSelectedIndexChanged event fires.</li>
<li>We clear the selected index of the ListBox. Every time we add a ListItem to the ListBox, it becomes the selected index of the ListBox control. If our ListBox is set to be a single-selection ListBox &#8212; the default behavior, and the case in this demo &#8212; an error will be thrown if an option was already selected in the ListBox, because there would then be two selected options. If your ListBox is set to multiple-selection, you need not reset the selected index of the ListBox. There are also ways to retain the selected index of the ListBox when adding a new ListItem to it; I will demo that if asked.</li>
<li>We declare a generic ListItem or Object control and set it to be whichever ListItem or Object is selected in the ComboBox.</li>
<li>We use the Add method of the ListItemCollection / ObjectCollection to append the selected option to the ListBox. There are ways to place the inserted item at the top of the list, and I will demo that if there is interest.</li>
<li>We use the RemoveAt method of the ListItemCollection / ObjectCollection to remove the selected option from the ComboBox.</li>
</ul>
<p>And that&#8217;s all there is to it. You can see this in action here:</p>
<p><a href="http://www.dougv.net/demos/combo_to_listbox/">http://www.dougv.net/demos/combo_to_listbox/</a></p>
<p>I distribute all code under the <a href="http://www.gnu.org/licenses/gpl-3.0.txt">GNU GPL version 3</a>.</p>
<p>All the links in this post on delicious.com: <a href="http://delicious.com/dhvrm/moving-listitems-from-a-combobox-dropdownlist-to-a-listbox-in-net">http://delicious.com/dhvrm/moving-listitems-from-a-combobox-dropdownlist-to-a-listbox-in-net</a></p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2008/08/10/adding-non-selectable-listitems-to-an-aspnet-dropdownlist-control/" rel="bookmark">Adding Non-Selectable ListItems To An ASP.NET DropDownList Control</a> (34.5)</li>
				<li><a href="https://www.dougv.com/2007/01/15/dynamically-populating-a-listbox-from-a-textbox-via-javascript-dom/" rel="bookmark">Dynamically Populating A Listbox From A Textbox Via JavaScript / DOM</a> (22.4)</li>
				<li><a href="https://www.dougv.com/2009/02/07/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control/" rel="bookmark">Revisited: Adding Non-Selectable ListItem Controls To An ASP.NET DataBound List Control</a> (10.1)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2009/02/21/moving-listitems-from-a-combobox-dropdownlist-to-a-listbox-in-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Revisited: Adding Non-Selectable ListItem Controls To An ASP.NET DataBound List Control</title>
		<link>https://www.dougv.com/2009/02/07/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control/</link>
		<comments>https://www.dougv.com/2009/02/07/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control/#comments</comments>
		<pubDate>Sat, 07 Feb 2009 22:34:16 +0000</pubDate>
		<dc:creator>Doug Vanderweide</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Transact-SQL]]></category>
		<category><![CDATA[drop down / select list]]></category>
		<category><![CDATA[elegance]]></category>

		<guid isPermaLink="false">http://www.dougv.com/blog/?p=1675</guid>
		<description><![CDATA[Last August I had quickly blogged on the subject of adding non-selectable ListItem controls to an ASP.NET DropDownList. At the time I didn&#8217;t have an easy way to demonstrate how that code worked &#8212; and, in all honesty, I hadn&#8217;t tested it thoroughly, so it had some problems. But now, thanks to GoDaddy&#8217;s dirt-cheap ASP.NET [...]<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2008/08/10/adding-non-selectable-listitems-to-an-aspnet-dropdownlist-control/" rel="bookmark">Adding Non-Selectable ListItems To An ASP.NET DropDownList Control</a> (50.5)</li>
				<li><a href="https://www.dougv.com/2007/06/22/going-to-a-new-url-via-a-drop-down-list-javascript-and-dom-php-aspnet/" rel="bookmark">Going To A New URL Via A Drop-Down List: JavaScript And DOM, PHP, ASP.NET</a> (20.9)</li>
				<li><a href="https://www.dougv.com/2006/10/28/update-dynamically-adding-javascript-to-select-aspnet-content-pages-master-pages/" rel="bookmark">Update: Dynamically Adding JavaScript To Select ASP.NET Content Pages / Master Pages Via The HtmlGenericControl Class</a> (18.4)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p>Last August I had quickly blogged on the subject of <a href="http://www.dougv.com/2008/08/10/adding-non-selectable-listitems-to-an-aspnet-dropdownlist-control/">adding non-selectable ListItem controls to an ASP.NET DropDownList</a>. At the time I didn&#8217;t have an easy way to demonstrate how that code worked &#8212; and, in all honesty, I hadn&#8217;t tested it thoroughly, so it had some problems.</p>
<p>But now, thanks to <a href="http://www.godaddy.com/gdshop/hosting/shared.asp?ci=13447">GoDaddy&#8217;s dirt-cheap ASP.NET Web hosting</a>, I can run <a href="http://www.dougv.net">dougv.net</a>, the <a href="http://www.dougv.com/2008/09/09/new-site-for-aspnet-demos-dhvrmcom/">ASP.NET demo site I had promised</a> some time ago.</p>
<p>I&#8217;ve finally gotten around to configuring that new site and getting it to run the way I want, so at long last I can post this revisiting of the original post, which has actually been sitting around on my hard drive since last September.</p>
<p>Let&#8217;s first define some terms for less-experienced ASP.NET developers.</p>
<p><strong>Control:</strong> An <em><a href="http://msdn.microsoft.com/en-us/library/bb386451.aspx">ASP.NET control</a></em> is any Web page element &#8212; a text box, select list, image, div, whatever &#8212; that either allows the user to change its value (e.g., a text box or select list) or that had its contents / value / rendering changed on the server side (such as a <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.aspx">GridView</a> that is populated by a <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasource.aspx">SqlDataSource</a>).</p>
<p>So for most intents and purposes, an ASP.NET control is any Web page element that runs at the server.</p>
<p><strong>Databound:</strong> A control is databound when its contents / options have been set with specific information. For example, a select list (<a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.dropdownlist.aspx">DropDownList</a>) is databound as soon as we add an option (ListItem) to it.</p>
<p>Some resources on the Web claim databinding only takes place if you use an external data store, such as an XML file or SQL Server database, to populate the child controls of a databound control (for example, to add <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listitem.aspx">ListItem</a> controls to a DropDownList). That is incorrect: A control is technically databound if we set any of its properties. For example, a <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.textbox.aspx">TextBox</a> control is technically databound if we initially set its Text property.</p>
<p>OK, with those definitions out of the way, let&#8217;s visit the next obvious question: Why in the world would you want a non-selectable ListItem?</p>
<p><span id="more-1675"></span></p>
<p>Because often, the number of items in a list-style control &#8212; namely, a select / DropDownList, but in ASP.NET, also a CheckBoxList or RadioButtonList control &#8212; can get unwieldy. If you have a list of, say, 30 options in a select list, it&#8217;s going to be difficult to pick the 17th option out of that list.</p>
<p>But if you broke the list up into groups of 5, it&#8217;s as easy as going to the fourth group and picking the second item from the top. That&#8217;s where the non-selectable ListItem comes in: We create an option that only serves the purpose of breaking up our list visually; it does not contain a valid value, and we don&#8217;t want to let users send that invalid value to our application.</p>
<p>Consider: Which of these lists is easier to read?</p>
<table cellspacing="0" border="0">
<tr>
<td style="vertical-align: top; padding-right: 30px; border-right: 1px solid #000;">
<pre>
03901    BERWICK
03902    CAPE NEDDICK
03903    ELIOT
03903    SOUTH ELIOT
03904    KITTERY
03905    CUTTS ISLAND
03905    KITTERY POINT
03906    NORTH BERWICK
03907    OGUNQUIT
03908    SOUTH BERWICK
03909    YORK
03909    YORK CENTER
04001    ACTON
04002    ALFRED
04003    BAILEY ISLAND
04004    BAR MILLS
04005    ARUNDEL
04005    BIDDEFORD
04005    DAYTON
04005    LYMAN
04006    BIDDEFORD POOL
04008    BOWDOINHAM
04009    BRIDGTON
04009    SOUTH BRIDGTON
04009    WEST BRIDGTON
04010    BROWNFIELD
04010    EAST FRYEBURG
04010    WEST DENMARK
04011    BIRCH ISLAND
04011    BRUNSWICK
</pre>
</td>
<td style="vertical-align: top; padding-left: 30px;">
<pre>
03901    BERWICK
03902    CAPE NEDDICK
03903    ELIOT
03903    SOUTH ELIOT
03904    KITTERY

03905    CUTTS ISLAND
03905    KITTERY POINT
03906    NORTH BERWICK
03907    OGUNQUIT
03908    SOUTH BERWICK

03909    YORK
03909    YORK CENTER
04001    ACTON
04002    ALFRED
04003    BAILEY ISLAND

04004    BAR MILLS
04005    ARUNDEL
04005    BIDDEFORD
04005    DAYTON
04005    LYMAN

04006    BIDDEFORD POOL
04008    BOWDOINHAM
04009    BRIDGTON
04009    SOUTH BRIDGTON
04009    WEST BRIDGTON

04010    BROWNFIELD
04010    EAST FRYEBURG
04010    WEST DENMARK
04011    BIRCH ISLAND
04011    BRUNSWICK
</pre>
<td>
</tr>
</table>
<p></p>
<p>The blank spaces in the right-hand list above represent where we might insert non-selectable ListItem controls to &#8220;break up&#8221; the list.</p>
<p>Of course, the limitations of the Web are that you can&#8217;t easily prevent end users from choosing a specific option from a select list. Sure, you can do it with JavaScript (and I would be willing to blog on how to do so if anyone asks), but you can&#8217;t rely on JavaScript to provide your applications with good data.</p>
<p>Fortunately, ASP.NET makes evaluating a non-selectable ListItem as simple as checking its value. In other words, as long as we explicitly declare the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listitem.value.aspx">Value property</a> of a ListItem control to be an empty string, we can make that ListItem non-selectable.</p>
<h4>Example 1: The Basics</h4>
<p>Let&#8217;s start by hand-coding a DropDownList with several ListItems. We&#8217;ll add in a Label control that we will change based on the selected item in the DropDownList, and we&#8217;ll set the DropDownList&#8217;s <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.autopostback.aspx">AutoPostBack property</a> to true, so that every time we change selections, the page will be sent back to the server for processing.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;ddlVacation&quot; AutoPostBack=&quot;true&quot; OnSelectedIndexChanged=&quot;ddlVacation_postBack&quot;&gt;
 &lt;asp:ListItem Text=&quot;-- Sunny Island -- &quot; Value=&quot;&quot; /&gt;
 &lt;asp:ListItem Value=&quot;Aruba&quot; /&gt;
 &lt;asp:ListItem Value=&quot;Hawaii&quot; /&gt;
 &lt;asp:ListItem Value=&quot;Bermuda&quot; /&gt;
 &lt;asp:ListItem Text=&quot;-- Snowy Getaway --&quot; Value=&quot;&quot; /&gt;
 &lt;asp:ListItem Value=&quot;Vail, CO&quot; /&gt;
 &lt;asp:ListItem Value=&quot;Nome, AK&quot; /&gt;
 &lt;asp:ListItem Value=&quot;Greenland&quot; /&gt;
 &lt;asp:ListItem Value=&quot;The North Pole&quot; /&gt;
 &lt;asp:ListItem Value=&quot;Antartica&quot; /&gt;
 &lt;asp:ListItem Text=&quot;-- Big Adventure --&quot; Value=&quot;&quot; /&gt;
 &lt;asp:ListItem Value=&quot;Mt. Everest&quot; /&gt;
 &lt;asp:ListItem Value=&quot;The Amazon River&quot; /&gt;
&lt;/asp:DropDownList&gt;
&lt;asp:Label runat=&quot;server&quot; ID=&quot;lblMessage&quot; Text=&quot;Select a vacation&quot; /&gt;
</pre>
<p>Note that we explicitly set the value of the non-selectable items to be an empty string. Again, that&#8217;s how we&#8217;re going to determine if the ListItem is non-selectable; if it contains no value, we know the user shouldn&#8217;t have selected it.</p>
<p>We can do this programmatically very easily. We simply ask if the SelectedValue property of the DropDownList &#8212; that is, the value of the ListItem which is currently selected &#8212; is an empty string. If so, the Label control is changed to indicate the option is not available; if not, the Label control is changed to reflect the choice made.</p>
<pre class="brush: vb; title: ; notranslate">
Sub ddlVacation_postBack(ByVal Sender As Object, ByVal E As EventArgs)
    If ddlVacation.SelectedValue = String.Empty Then
        lblMessage.Text = &quot;Sorry, that's not an option. Please choose again.&quot;
        lblMessage.Font.Bold = True
        lblMessage.ForeColor = Drawing.Color.Red
    Else
        lblMessage.Text = &quot;I would love to go to &lt;strong&gt;&quot; &amp; ddlVacation.SelectedValue &amp; &quot;&lt;/strong&gt;!&quot;
        lblMessage.Font.Bold = False
        lblMessage.ForeColor = Drawing.Color.Black
    End If
End Sub
</pre>
<p>Working demo: <a href="http://www.dougv.net/demos/non_selectable_listitem/default.aspx">http://www.dougv.net/demos/non_selectable_listitem/default.aspx</a></p>
<h4>Example 2: Periodic Separators In A DataBound Control</h4>
<p>A more useful tactic is automatically programming separators into a collection of ListItems that you have retrieved from an external data store, such as a database.</p>
<p>For example, I have a database table that lists all 50 US states plus their postal codes. Perhaps I want this list to be easier on my users&#8217; eyes and make it easier to pick out a given state.</p>
<p>To do that, I will break the list up into 10-state sections. And to accomplish that, I am going to have to get old school and programmatically bind the database&#8217;s result set to the DropDownList control.</p>
<p>First, let&#8217;s look at the control / page cod, which is the simple control declarations: the DropDownList, a Label and a Button.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;ddlMyList&quot; /&gt;
&lt;asp:Label runat=&quot;server&quot; ID=&quot;lblStatus&quot; Text=&quot;Select a town from the list and click Get Postal Code.&quot; /&gt;
&lt;br /&gt;
&lt;asp:Button runat=&quot;server&quot; ID=&quot;btnSubmit&quot; OnClick=&quot;btnSubmit_onClick&quot; Text=&quot;Get Postal Code&quot; /&gt;
</pre>
<p>The codebehind is a bit more complex, because we need to open a connection to the database, query it for records, then create the ListItems from those records, periodically inserting our non-selectable separators.</p>
<p>We use three subroutines to accomplish this task: Page_Load is used to trigger the initial population of the DropDownList. ddlMyList_dataBind actually adds the ListItems to the control. And btnSubmit_click handles the postback.</p>
<pre class="brush: vb; title: ; notranslate">
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
        'bind the dropdownlist
        ddlMyList_dataBind()
    End If
End Sub

Sub ddlMyList_dataBind()
    'Subroutine that binds listitems to dropdownlist
    'This requires the System.Data and System.Data.SqlClient namespaces

    'Open connection to database; declare SQL statement
    'You really should use parameterized stored procedures, but we'll do this as straight SQL
    Dim objConn As New SqlConnection(&quot;my connection string&quot;)
    Dim objCmd As New SqlCommand(&quot;SELECT * FROM states_table ORDER BY state_name ASC&quot;, objConn)
    objCmd.CommandType = CommandType.Text

    'We need a generic loop counter
    Dim I As Integer = 0

    Try
        'connect to db
        objConn.Open()
        'create a data reader and populate it with SQL statement results
        Dim objReader As SqlDataReader = objCmd.ExecuteReader()

        'if the reader has records, let's bind the results
        If objReader.HasRows() Then
            'go through all items in the recordset
            'we'll read the items one by one
            Do While objReader.Read()
                'add a heading at the top of the list and every 10 additional items
                If I Mod 10 = 0 And I &lt; 50 Then
                    ddlMyList.Items.Insert(I, New ListItem(&quot;--------------------&quot;, String.Empty))
                Else
                    'add the current data reader item
                    ddlMyList.Items.Insert(I, New ListItem(objReader(&quot;state_name&quot;), objReader(&quot;state_code&quot;)))
                End If
                'increment the loop counter
                I += 1
            Loop
        Else
            'report that there are no items to display in the list
            ' and disable the dropdownlist
            lblStatus.Text = &quot;There are no records for this item&quot;
            ddlMyList.Enabled = False
        End If

        'close the connection
        objConn.Close()

    Catch ex As Exception
        'if there is an error, report it
        ' and disable the dropdownlist
        lblStatus.Text = ex.Message
        ddlMyList.Enabled = False
    End Try

    'clean up the database objects
    objCmd.Dispose()
    objConn.Dispose()
End Sub

Sub btnSubmit_onClick(ByVal Sender As Object, ByVal E As EventArgs) Handles btnSubmit.Click
    'report when a non-selectable item has been selected
    'non-selectable items have no values
    If String.IsNullOrEmpty(ddlMyList.SelectedValue) Then
        lblStatus.Text = &quot;You cannot select this item. Please select a different item.&quot;
        lblStatus.ForeColor = Drawing.Color.Red
        lblStatus.Font.Bold = True
    Else
        lblStatus.Text = &quot;Postal code: &quot; &amp; ddlMyList.SelectedValue
        lblStatus.ForeColor = Drawing.Color.Black
        lblStatus.Font.Bold = False
    End If
End Sub
</pre>
<p>Note that we check for postback in the Page_Load subroutine. Every time btnSubmit is clicked, the page is sent via postback. If we didn&#8217;t check, therefore, whether the page was being posted back, we would databind anew the DropDownList every time the page is loaded &#8212; effectively wiping out whatever choice we made.</p>
<p>Working demo: <a href="http://www.dougv.net/demos/non_selectable_listitem/databound.aspx">http://www.dougv.net/demos/non_selectable_listitem/databound.aspx</a></p>
<h4>Example 3: With A CustomValidator Control</h4>
<p>This is what I was after with my initial post: A simple way to use ASP.NET&#8217;s built-in validation controls to do what they are designed to do, namely, validate input.</p>
<p>The problem is that ASP.NET List controls are not amenable to validation controls out of the box. Basically, you need to create a <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.customvalidator.aspx">CustomValidator</a> that isn&#8217;t specifically set to validate the given control, then write an explicit <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.customvalidator.onservervalidate.aspx">OnServerValidate</a> event handler that uses the List control&#8217;s name, rather than the passed <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.servervalidateeventargs.aspx">ServerValidateEventArguments</a>.</p>
<p>That sounds more complicated than it actually is. Let&#8217;s start with the page / control code:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;asp:DropDownList runat=&quot;server&quot; ID=&quot;ddlVacation&quot; AutoPostBack=&quot;true&quot; OnSelectedIndexChanged=&quot;ddlVacation_postBack&quot;&gt;
    &lt;asp:ListItem Text=&quot;-- Sunny Island -- &quot; Value=&quot;&quot; /&gt;
    &lt;asp:ListItem Value=&quot;Aruba&quot; /&gt;
    &lt;asp:ListItem Value=&quot;Hawaii&quot; /&gt;
    &lt;asp:ListItem Value=&quot;Bermuda&quot; /&gt;
    &lt;asp:ListItem Text=&quot;-- Snowy Getaway --&quot; Value=&quot;&quot; /&gt;
    &lt;asp:ListItem Value=&quot;Vail, CO&quot; /&gt;
    &lt;asp:ListItem Value=&quot;Nome, AK&quot; /&gt;
    &lt;asp:ListItem Value=&quot;Greenland&quot; /&gt;
    &lt;asp:ListItem Value=&quot;The North Pole&quot; /&gt;
    &lt;asp:ListItem Value=&quot;Antartica&quot; /&gt;
    &lt;asp:ListItem Text=&quot;-- Big Adventure --&quot; Value=&quot;&quot; /&gt;
    &lt;asp:ListItem Value=&quot;Mt. Everest&quot; /&gt;
    &lt;asp:ListItem Value=&quot;The Amazon River&quot; /&gt;
&lt;/asp:DropDownList&gt;
&lt;asp:Label runat=&quot;server&quot; ID=&quot;lblMessage&quot; Text=&quot;Select a vacation&quot; /&gt;
&lt;asp:CustomValidator runat=&quot;server&quot; ID=&quot;cvVacation&quot; OnServerValidate=&quot;cvVacation_serverValidate&quot; ForeColor=&quot;Red&quot; Font-Bold=&quot;true&quot; ErrorMessage=&quot;Sorry, that's not an option. Please try again.&quot; Display=&quot;Dynamic&quot; /&gt;
</pre>
<p>And now, the codebehind. Note that every time we call the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.onselectedindexchanged.aspx">OnSelectedIndexChanged</a> event handler for the DropDownList, we need to validate the page; that is the only way to get the CustomValidator to fire. If we don&#8217;t call Page.Validate, the CustomValidator will not be invoked at all.</p>
<pre class="brush: vb; title: ; notranslate">
Sub ddlVacation_postBack(ByVal Sender As Object, ByVal E As EventArgs)
    Page.Validate()
    If Page.IsValid Then
        lblMessage.Text = &quot;I would love to go to &lt;strong&gt;&quot; &amp; ddlVacation.SelectedValue &amp; &quot;&lt;/strong&gt;!&quot;
    End If
End Sub

Sub cvVacation_serverValidate(ByVal Sender As Object, ByVal E As ServerValidateEventArgs)
    If ddlVacation.SelectedValue = String.Empty Then
        E.IsValid = False
        lblMessage.Text = &quot;&quot;
    End If
End Sub
</pre>
<p>Working demo: <a href="http://www.dougv.net/demos/non_selectable_listitem/validator.aspx">http://www.dougv.net/demos/non_selectable_listitem/validator.aspx</a></p>
<p>Notice that this is startlingly similar to Example 1. In fact, you could argue that Example 1 is more elegant. So why bother with the CustomValidator?</p>
<p>One thought is that you might want to validate all your controls only once, at the time the page is submitted. If so, you can simply add Page.Validate to the subroutine or function that handles your postback processing, so that all controls are fired at once.</p>
<p>You might also want to validate proper input as part of a group of items on a page. For example, you might have a DropDownList that gives a series of state names, and a textbox next to it that asks for a ZIP Code; it may be that you want to ensure a proper state is chosen, then ensure the ZIP Code provided is valid for the state given, before proceeding to another part of the form.</p>
<p>To do that, you would set the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basevalidator.validationgroup.aspx">ValidationGroup</a> property of both controls&#8217; validators &#8212; for the DropDownList, a custom validator; for the TextBox, perhaps another CustomValidator, or perhaps a <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.comparevalidator.aspx">CompareValidator</a> or <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.regularexpressionvalidator.aspx">RegularExpressionValidator</a> &#8212; to be the same, so that they effectively validate as a single item.</p>
<p>All the links in this post on delicious: <a href="http://delicious.com/dhvrm/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control">http://delicious.com/dhvrm/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control</a></p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2008/08/10/adding-non-selectable-listitems-to-an-aspnet-dropdownlist-control/" rel="bookmark">Adding Non-Selectable ListItems To An ASP.NET DropDownList Control</a> (50.5)</li>
				<li><a href="https://www.dougv.com/2007/06/22/going-to-a-new-url-via-a-drop-down-list-javascript-and-dom-php-aspnet/" rel="bookmark">Going To A New URL Via A Drop-Down List: JavaScript And DOM, PHP, ASP.NET</a> (20.9)</li>
				<li><a href="https://www.dougv.com/2006/10/28/update-dynamically-adding-javascript-to-select-aspnet-content-pages-master-pages/" rel="bookmark">Update: Dynamically Adding JavaScript To Select ASP.NET Content Pages / Master Pages Via The HtmlGenericControl Class</a> (18.4)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a>, <a href="https://www.dougv.com/tag/elegance/" title="elegance" rel="tag">elegance</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2009/02/07/revisited-adding-non-selectable-listitem-controls-to-an-aspnet-databound-list-control/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Simple YouTube Jukebox Using JavaScript / DOM And deconcept&#8217;s SWFObject</title>
		<link>https://www.dougv.com/2007/07/02/a-simple-youtube-jukebox-using-javascript-dom-and-deconcepts-swfobject/</link>
		<comments>https://www.dougv.com/2007/07/02/a-simple-youtube-jukebox-using-javascript-dom-and-deconcepts-swfobject/#comments</comments>
		<pubDate>Tue, 03 Jul 2007 03:35:16 +0000</pubDate>
		<dc:creator>Doug Vanderweide</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[drop down / select list]]></category>

		<guid isPermaLink="false">http://www.dougv.com/blog/2007/07/02/a-simple-youtube-jukebox-using-javascript-dom-and-deconcepts-swfobject/</guid>
		<description><![CDATA[Recently asked on Yahoo! Answers: HTML Help &#8211; Dropbox with Loading Option? Okay, here&#8217;s my issue. I have a decent piece of coding that gives me a dropbox. The dropbox has a &#8216;go&#8217; button, and it is filled with titles of music videos from YouTube. Now, used alone, it&#8217;s fine. It opens a new page, [...]<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2006/12/18/fun-with-javascript-a-simple-test-quiz-script-to-demonstrate-dom-form-handling/" rel="bookmark">Fun With JavaScript: A Simple Test / Quiz Script To Demonstrate DOM Form Handling</a> (25.9)</li>
				<li><a href="https://www.dougv.com/2007/01/15/dynamically-populating-a-listbox-from-a-textbox-via-javascript-dom/" rel="bookmark">Dynamically Populating A Listbox From A Textbox Via JavaScript / DOM</a> (18.6)</li>
				<li><a href="https://www.dougv.com/2007/04/02/changing-an-iframe-source-from-a-drop-down-list-via-javascript-dom/" rel="bookmark">Changing An IFrame Source From A Drop-Down List Via JavaScript / DOM</a> (18.6)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p>Recently asked on Yahoo! Answers:</p>
<blockquote><p><strong><a href="http://answers.yahoo.com/question/index?qid=20070702152330AAkmUUv">HTML Help &#8211; Dropbox with Loading Option?</a></strong></p>
<p>Okay, here&#8217;s my issue. I have a decent piece of coding that gives me a dropbox. The dropbox has a &#8216;go&#8217; button, and it is filled with titles of music videos from YouTube.</p>
<p>Now, used alone, it&#8217;s fine. It opens a new page, which plays the youtube video.</p>
<p>However, I was clever enough to grab the *embed* names. So, it doesn&#8217;t load a simple youtube page, but simply the video in a website.</p>
<p>So now, I need some HTML help. I would like to create an object that sits next to the dropbox and plays the video when you select &#8216;go&#8217;, instead of it loading a new page.</p>
<p>I know how to make an embedded video. I know how to make the dropbox. Unfortunately, I don&#8217;t know how to make the dropbox and the embedded video interact, so that I can select the video I want to play.</p></blockquote>
<p>This is very easy to do, thanks to <a href="http://code.google.com/p/swfobject/">deconcept&#8217;s excellent SWFObject JavaScript library</a> and the questioner&#8217;s work in extracting the Flash FLV player URLs from all the videos he wants to show.</p>
<p>So, let&#8217;s get right on making a YouTube jukebox!</p>
<p><span id="more-247"></span></p>
<h3>Step 1: The Form</h3>
<p>Our form couldn&#8217;t be simpler: It&#8217;s just a SELECT list that holds all the URLs to our files, which also has an onchange event set to a JavaScript function named playVideo(). We&#8217;ll create that function soon.</p>
<pre class="brush: xml; title: ; notranslate">&lt;form id=&quot;form1&quot; method=&quot;post&quot;&gt;
	&lt;label&gt;Select A Video:
		&lt;select id=&quot;jukeVids&quot; onchange=&quot;playVideo()&quot;&gt;
			&lt;option selected=&quot;selected&quot;&gt;Select ...&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/PrZQIayUnbA&quot;&gt;&quot;The Omega Kawaii Cloud Song&quot; - Nellie Malton&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/171C8yZIj_M&quot;&gt;&quot;How Much You Annoy Me&quot; - Dr. Cox&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/s2Qv2mGCGzQ&quot;&gt;&quot;Resident Evil Montage Rumble&quot; - ShadowLeggy&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/WMvAzYH1xHM&quot;&gt;&quot; Numa Numa&quot; (Resident Evil) - O-Zone&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/9jGFj4gAaxU&quot;&gt;&quot;Beverly Hills&quot; (Halo Version) - Weezer&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/FHGvh3i35Uk&quot;&gt;&quot;He Said, She Said&quot; - Maldroid&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/YxZJYbVd1hE&quot;&gt;&quot;Heck No! (I'll Never Listen to Techno)&quot; - Maldroid&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/8Rp9XvD5kXg&quot;&gt;&quot;Wizard Needs Food Badly&quot; - Five Iron Frenzy&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/KCeQuqMS9Ww&quot;&gt;&quot;Somewhere Over the Rainbow&quot; - Ted's Band&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/3QIWX5CcLi8&quot;&gt;&quot;Casino Royale&quot; (Casino Royal Theme Version) - Chris Cornell&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/if0_gzrIWCM&quot;&gt;&quot;Smoke the Wii&quot; - The FanBoiz&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/91AlqOYkiaE&quot;&gt;&quot;Bananaphone&quot; (Half-Life 2 Version) - sh00rty&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/6NXqbau-CKE&quot;&gt;&quot;Grand Theft Autumn Parody&quot; - Fall Out Boy (Parody)&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/UBbTYaG-_nM&quot;&gt;&quot;Seven Minutes In Heaven Parody&quot; - Fall Out Boy (Parody)&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/q_RZRTYZ2z8&quot;&gt;&quot;Kryptonite&quot; (Resident Evil 4 Version) - Three Doors Down&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/FA9N_2kKQ0w&quot;&gt;&quot;Trogdor&quot; (GH2 Version) - Strong Bad&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/4ttidEl0gXU&quot;&gt;&quot;The Saga Begins&quot; - Weird Al Yankovic&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/24rG_-H2nqo&quot;&gt;&quot;Couch Potato&quot; (Live) - Weird Al Yankovic&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/-xEzGIuY7kw&quot;&gt;&quot;White and Nerdy&quot; - Weird Al Yankovic&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/vpBmrgJtA3s&quot;&gt;&quot;Dance Dance Parody&quot; - Fall Out Boy (Parody)&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/SNygDdAJ8uc&quot;&gt;&quot;Numb&quot; (Phoenix Wright Version) - Linkin Park&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/k52HCHOSpr0&quot;&gt;&quot;All Your Base&quot; - Master Samurai&lt;/option&gt;
			&lt;option value=&quot;http://www.youtube.com/v/Plos2SvAu9Y&quot;&gt;&quot;School of Rock&quot; (GH2 Custom) - School of Rock&lt;/option&gt;
		&lt;/select&gt;
	&lt;/label&gt;
&lt;/form&gt;
</pre>
<h3>Step 2: The DIV</h3>
<p>We also need a simple DIV in which we will dynamically place the Flash player we get from YouTube. That&#8217;s as simple as making a DIV that has an ID of jukePlayer. I&#8217;ve also set aside some CSS code to space for the player once it comes in, by fixing the DIV&#8217;s height and width to the size of the average Flash player.</p>
<pre class="brush: css; title: ; notranslate">div#jukePlayer {
	width: 425px;
	height: 350px;
	margin: 10px 0 10px 0;
}
</pre>
<h3>Step 3: deconcept&#8217;s SWFObject JavaScript</h3>
<p>We need a way to dynamically change the DIV&#8217;s innerHTML to be an embedded instance of the Flash Player. Thankfully, there&#8217;s a great JavaScript library out there already that will do that for us: <a href="http://code.google.com/p/swfobject/">deconcept&#8217;s SWFObject</a>.</p>
<p>All we need to do is download the JavaScript they supply, upload the enclosed swfobject.js file to our Web site, and make reference to it with a SCRIPT tag in our page&#8217;s HEAD segment.</p>
<pre class="brush: jscript; title: ; notranslate">&lt;script src=&quot;swfobject.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</pre>
<h3>Step 4: The playVideo() Script</h3>
<p>To bring it all together, we need to make a script that gets the chosen item in our SELECT menu and drop its video into our DIV. That&#8217;s as easy as getting the SELECT via getElementById, then iterating through all its options until we find the selected item.</p>
<p>Once we find the selected item, we create a new SWFObject, pass it the parameters it needs, and tell it to place the player in our DIV.</p>
<p>Note that we also accept two arguments in the playVideo() function: autoplay and loop. If you send a value of 1 for autoplay, then the video will start playing once it loads; if you send a value of 1 for loop, the video will play back continuously.</p>
<p>You must send values for both parameters, but only values of 1 matter; any other value will be ignored.</p>
<pre class="brush: jscript; title: ; notranslate">
function playVideo(autoplay, loop) {
	var theSelect = document.getElementById(&quot;jukeVids&quot;);
	var theArgs;
	if(autoplay == 1) {
		theArgs = &quot;&amp;amp;autoplay=1&quot;;
	}
	if(loop == 1) {
		theArgs += &quot;&amp;amp;loop=1&quot;;
	}

	for(var i = 0; i &lt; theSelect.length; i++) {
		if(theSelect.options[i].selected) {
			var so = new SWFObject(theSelect.options[i].value + theArgs, &quot;mymovie&quot;, &quot;425&quot;, &quot;350&quot;, &quot;8&quot;, &quot;#fff&quot;);
			so.write(&quot;jukePlayer&quot;);
			break;
		}
	}
}
</pre>
<p>And that&#8217;s all there is to it. You can see the script in action here:</p>
<p><a href="http://www.dougv.com/demo/js_youtube_jukebox/">http://www.dougv.com/demo/js_youtube_jukebox/</a></p>
<p>You can simply save the page to your computer and modify it to your content. My work is distributed under the GNU GPL version 3.</p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2006/12/18/fun-with-javascript-a-simple-test-quiz-script-to-demonstrate-dom-form-handling/" rel="bookmark">Fun With JavaScript: A Simple Test / Quiz Script To Demonstrate DOM Form Handling</a> (25.9)</li>
				<li><a href="https://www.dougv.com/2007/01/15/dynamically-populating-a-listbox-from-a-textbox-via-javascript-dom/" rel="bookmark">Dynamically Populating A Listbox From A Textbox Via JavaScript / DOM</a> (18.6)</li>
				<li><a href="https://www.dougv.com/2007/04/02/changing-an-iframe-source-from-a-drop-down-list-via-javascript-dom/" rel="bookmark">Changing An IFrame Source From A Drop-Down List Via JavaScript / DOM</a> (18.6)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2007/07/02/a-simple-youtube-jukebox-using-javascript-dom-and-deconcepts-swfobject/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dynamically Populating A Listbox From A Textbox Via JavaScript / DOM</title>
		<link>https://www.dougv.com/2007/01/15/dynamically-populating-a-listbox-from-a-textbox-via-javascript-dom/</link>
		<comments>https://www.dougv.com/2007/01/15/dynamically-populating-a-listbox-from-a-textbox-via-javascript-dom/#comments</comments>
		<pubDate>Tue, 16 Jan 2007 00:22:48 +0000</pubDate>
		<dc:creator>Doug Vanderweide</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[drop down / select list]]></category>

		<guid isPermaLink="false">http://www.dougv.com/blog/2007/01/15/dynamically-populating-a-listbox-from-a-textbox-via-javascript-dom/</guid>
		<description><![CDATA[Recently asked on Yahoo! Answers: Where can I find the javascript that lets me move an item from a textbox to a list? I have a text field, an ADD button, a list feld (empty) and a DELETE button. I want the user to be able to type something into the textfield, click ADD, and [...]<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2006/12/14/dynamically-creating-links-with-javascript/" rel="bookmark">Dynamically Creating Links With JavaScript</a> (22.3)</li>
				<li><a href="https://www.dougv.com/2007/01/03/retaining-selections-from-a-single-select-box-in-two-multiple-select-boxes-via-javascript-dom/" rel="bookmark">Retaining Selections From A Single Select Box In Two Multiple Select Boxes Via JavaScript / DOM</a> (20.5)</li>
				<li><a href="https://www.dougv.com/2006/12/18/fun-with-javascript-a-simple-test-quiz-script-to-demonstrate-dom-form-handling/" rel="bookmark">Fun With JavaScript: A Simple Test / Quiz Script To Demonstrate DOM Form Handling</a> (19.4)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.
	</div>
]]></description>
			<content:encoded><![CDATA[<p>Recently asked on Yahoo! Answers:</p>
<blockquote><p><strong><a href="http://answers.yahoo.com/question/index?qid=20070115100350AA1oKMG">Where can I find the javascript that lets me move an item from a textbox to a list?</a></strong></p>
<p>I have a text field, an ADD button, a list feld (empty) and a DELETE button. I want the user to be able to type something into the textfield, click ADD, and have that item appear in the list. If they select an item from the list and click DELETE, then the item would be deleted. Can someone post the code or a link to some free javascript? </p></blockquote>
<p>You can actually find bits and pieces of this code out on the Interweb (as one of my clients calls it) quite easily, but packaged together isn&#8217;t so easy. So, I&#8217;ll tie it all together and explain how it works.</p>
<p><span id="more-120"></span></p>
<p>As always, we start with a simple form, and again, I&#8217;m cheating on layout with a table. Note that we assign onclick events to our buttons that will be the names of our JavaScript functions:</p>
<pre lang="xml">
<form id="form1" name="form1" method="post" action="">
<table>
<tr>
<td>
				<label>Enter Item:
<input name="mytext" type="text" id="mytextbox" />
<input name="myadd" type="button" id="myadd" value="Add Item" onclick="addListItem()" />
				</label>
			</td>
<td>
<select name="mylist" size="10" multiple="multiple" id="mylistbox">
				</select>
</td>
<td>
<input name="mydelete" type="button" id="mydelete" value="Remove Selected Items" onclick="removeListItem();" />
			</td>
</tr>
</table>
</form>
</pre>
<p>We begin the JavaScript with a function that doesn&#8217;t seem related at all: A basic string-trimming function. What this function does is trim all leading and trailing white space from a line. We use this function because we don&#8217;t want to handle bad text input from the user, and that includes simply entering nothing more than white space into the textbox.</p>
<p>Our function merely starts at the beginning of the input string and looks for whitespace characters, removing them if they are found. Then, it finds the end of the string and starts knocking white space characters off the end, one by one.</p>
<pre lang="javascript">
function trimString(input) {
	var output = input;
	while (output.substring(0, 1) == ' ') {
		output = output.substring(1, output.length);
	}
	while (output.substring(output.length - 1, output.length) == ' ') {
		output = output.substring(0, output.length - 1);
	}
	return output;
}
</pre>
<p>We can now begin the project in earnest. First up, the function that will add items to our listbox. We assign two variables the textbox and listbox elements from our page; we declare a Boolean that will help us figure out if the textbox contains a value that&#8217;s already in our list; and we declare an Option variable that will allow us to add items to the listbox.</p>
<pre lang="javascript">
function addListItem() {
	var textbox = document.getElementById('mytextbox');
	var listbox = document.getElementById('mylistbox');
	var inList = false;
	var myText = trimString(textbox.value);
	var myOption;
</pre>
<p>Notice that we trimmed the myText variable before we began; we want to make sure there is something worth processing. Additionally, we want to make sure that we don&#8217;t add list items based on leading or trailing spaces. For example, to humans, &#8220;Hello World!&#8221; is the same as &#8220;Hello World! &#8220;, but to a computer, that trailing space makes the two strings different.</p>
<p>The code below takes that trimmed text and compares it to all the options currently in the listbox. If the item is already in the options, the value of the text box will not be added.</p>
<p>We need to consider case, as well. In the code block below, I cast both the value of the textbox and the values in the listbox to lower case as I compare them, because I don&#8217;t want options in the listbox that repeat an item based on case.</p>
<p>For example, if I don&#8217;t cast my comparisons to lower case, then &#8220;Banana&#8221;, &#8220;banana&#8221;, &#8220;bAnana&#8221; and &#8220;BaNana&#8221; would all be added to the list box as options. If that&#8217;s what you actually want to have happen, just remove the toLowerCase() methods from the code block below.</p>
<p>To add an option to a listbox, we just create an option with the text and value we want, then append it to the end of the options list.</p>
<pre lang="javascript">
if(myText != '') {
	for(var i = 0; i < listbox.options.length; i++) {
		if(myText.toLowerCase() == listbox.options[i].text.toLowerCase()) {
			inList = true;
			break;
		}
	}

	if(!inList) {
		myOption = new Option(myText, myText);
		listbox.options[listbox.options.length] = myOption;
	}
}
</pre>
<p>[<strong>Aside: </strong>You could have this list automatically sort itself alphabetically. To do that, you'd declare a global array and store your options in that array; every time you added an option, you'd add the item to that global array, then sort it.</p>
<p>In turn, you'd remove all options from the listbox as it is now, then rebind all the items in the global array to your listbox as options.]</p>
<p>To remove an item, we simply see if it is checked in the listbox; if it is, we set it to null.</p>
<pre lang="javascript">
function removeListItem() {
	var listbox = document.getElementById('mylistbox');

	for(var i = 0; i < listbox.options.length; i++) {
		if(listbox.options[i].selected) {
			listbox.options[i] = null;
		}
	}
}
</pre>
<p>Here's a working demo:</p>
<p><a href="http://www.dougv.com/demo/js_dynamic_listbox/">http://www.dougv.com/demo/js_dynamic_listbox/</a></p>
<p>You can simply save the page as is to work with it. As always, I distribute code under the most recent version of the Creative Commons Attribution / Share-Alike License.</p>
<div class="yarpp">
	<h5>Related Posts</h5>
		<ol>
				<li><a href="https://www.dougv.com/2006/12/14/dynamically-creating-links-with-javascript/" rel="bookmark">Dynamically Creating Links With JavaScript</a> (22.3)</li>
				<li><a href="https://www.dougv.com/2007/01/03/retaining-selections-from-a-single-select-box-in-two-multiple-select-boxes-via-javascript-dom/" rel="bookmark">Retaining Selections From A Single Select Box In Two Multiple Select Boxes Via JavaScript / DOM</a> (20.5)</li>
				<li><a href="https://www.dougv.com/2006/12/18/fun-with-javascript-a-simple-test-quiz-script-to-demonstrate-dom-form-handling/" rel="bookmark">Fun With JavaScript: A Simple Test / Quiz Script To Demonstrate DOM Form Handling</a> (19.4)</li>
			</ol>
	<p class="note">The numbers inside parentheses are relevance scores. Scoring is based, in order of priority, on title, category, content and tags. The higher the score, the more likely that post relates to this post.</p>
	</div>

	Tags: <a href="https://www.dougv.com/tag/drop-down-select-list/" title="drop down / select list" rel="tag">drop down / select list</a><br />
]]></content:encoded>
			<wfw:commentRss>https://www.dougv.com/2007/01/15/dynamically-populating-a-listbox-from-a-textbox-via-javascript-dom/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

