Here is my problem. I am trying to have this second select option be dependent on the previous select option. The first select option determines color of shoe. The second select option, size, is based on the color of the shoe. How can I make this dynamic enough to change available sizes based on color?
Here is my code:
<SCRIPT type="text/javascript">
$(document).ready(function()
{
$("#color").change(function()
{
var element = $(this);
if(element.val() === "brn")
{
$("#size").append('<option value="5">5</option>');
$("#size").append('<option value="6">6</option>');
$("#size").append('<option value="7">7</option>');
$("#size").append('<option value="8">8</option>');
$("#size").append('<option value="9">9</option>');
$("#size").append('<option value="10">10</option>');
$("#size").append('<option value="11">11</option>');
$("#size").append('<option value="12">12</option>');
$("#size").append('<option value="13">13</option>');
}
else if(element.val() === "blk")
{
$("#size").append('<option value="7">7</option>');
$("#size").append('<option value="8">8</option>');
$("#size").append('<option value="9">9</option>');
$("#size").append('<option value="10">10</option>');
$("#size").append('<option value="11">11</option>');
$("#size").append('<option value="12">12</option>');
$("#size").append('<option value="13">13</option>');
}
else if(element.val() === "nav")
{
$("#size").append('<option value="5">5</option>');
$("#size").append('<option value="6">6</option>');
$("#size").append('<option value="7">7</option>');
$("#size").append('<option value="8">8</option>');
$("#size").append('<option value="9">9</option>');
$("#size").append('<option value="10">10</option>');
}
else if(element.val() === "sbl")
{
$("#size").append('<option value="5">5</option>');
$("#size").append('<option value="6">6</option>');
$("#size").append('<option value="7">7</option>');
$("#size").append('<option value="8">8</option>');
$("#size").append('<option value="9">9</option>');
$("#size").append('<option value="10">10</option>');
}
else if(element.val() === "pnk")
{
$("#size").append('<option value="5">5</option>');
$("#size").append('<option value="6">6</option>');
$("#size").append('<option value="7">7</option>');
$("#size").append('<option value="8">8</option>');
$("#size").append('<option value="9">9</option>');
$("#size").append('<option value="10">10</option>');
}
});
});
<form action="#" method="post">
<p align="center">
<label for="color">Color:
<select name="color" id="color">
<option value="brn">Brown</option>
<option value="blk">Black</option>
<option value="nav">Navy</option>
<option value="sbl">Sky Blue</option>
<option value="pnk">Pink</option>
</select>
</label>
</p>
<p align="center">
<label for="size">Size:
<select name="size" id="size">
function();
</select>
</label>
</p>
<div align="center">
<input type="submit" value="Add To Cart" />
</div>
</form>
The base problem as Glorfindel stated is that your quotes need to be escaped. (Also, since your values for the sizes are the same as your options you don't actually need to specify a value for the sizes).
However, I thought I'd mention a few other things I noticed. You state that you'd like to make this dynamic enough to change the available sizes based on color. Your JavaScript will actually append the new values whenever you change the color, meaning that switching from one color to the next will result in the first colors size options and the second options.
In order to fix this you will want to call
.empty()
on your size element so that the new options will replace the older ones.We can make this even better though!
By calling
$('#size')
on almost every line we are creating a brand new jQuery object for each addition to the option element. Also, we end up searching the DOM for that selector as well. You can make this perform better by doing a couple of different things.Take advantage of jQuery chaining.
Most methods in jQuery return the original object after they are done executing. This means that you can continue running jQuery methods one after another. By chaining your calls together you ensure that you do not have to create a new jQuery object on each line. This makes your JavaScript perform better (if even a little bit).
Example:
So. if we add chaining we end up with some JavaScript that performs better. But we are also calling
.append()
a lot. Each time we call.append()
we are also triggering a reflow.Reduce Reflows
Rather than calling append multiple times adding an element one at a time, we can call append once and add the elements we want once. This makes it so we don't tell the browser to reflow the document more than is necessary. (Aside: this concept is similar to what RActive and React do by creating a VirtualDOM).
Well, since we already know what is going to be appended we can simply remove all the appends and replace them with one gigantic string.
$("#size").append("<option>7</option><option>8</option><option>9</option><option>10</option><option>11</option><option>12</option><option>13</option>");
But - that makes my eyes bLLeeed. It's ugly. So let's refactor this some more.
Continuing to Refactor
The only thing different between one option and the next option is the actual numeric size. The opening
<option>
and closing</option>
are the same for each one. Maybe we move this out to a method likegetOptions(color)
?We are using
element.val()
a lot to get the selected color. However, we don't use theelement
for anything else. Maybe we could just store that color in a variable - so we don't have to get it all of the time?var selectedColor = element.val();
Also, we could probably get rid of the if statements if we setup an object to contain our sizes. That object would consist of color key values, and then an array of sizes for those keys.
Eventually, we might end up with something like this:
And in fiddle form: http://jsfiddle.net/h1navan2/3/
It's a start. You might find ways of refactoring this more. However, remember the key things that we did.
var $sizes = $('#sizes');
. Then we can use that variable.In any case, I know this is much more than what you bargained for. But maybe it'll help in the future. Hopefully it's helpful.
Good luck Javascripting! :)