I am looking to have two custom attributes for products, where the second custom attribute has unique options depending on the first attribute selected.
My particular circumstance is selling art that will have many different formats and sizes, where the price of the sizes will be different depending on which format is selected (IE: Print, Framed, Canvas, etc.).
The obvious alternative is to just have different product listings for each format, and not have the double drop down menu's. However, that is not ideally what I am looking to do.
This is the code provided in the documentation for a single select box and custom attribute:
<label>Frame color</label>
<select id="frame_color">
<option value="Black">Black</option>
<option value="Brown">Brown</option>
<option value="Gold">Gold</option>
</select>
<button
id="starry-night"
class="snipcart-add-item"
data-item-id="starry-night"
data-item-price="79.99"
data-item-url="/paintings/starry-night"
data-item-description="High-quality replica of The Starry Night by the Dutch post-impressionist painter Vincent van Gogh."
data-item-image="/assets/images/starry-night.jpg"
data-item-name="The Starry Night"
data-item-custom1-name="Frame color"
data-item-custom1-options="Black|Brown|Gold"
data-item-custom2-name="Gift note">
Add to cart
</button>
<script>
const button = document.querySelector('#starry-night')
const select = document.querySelector('#frame_color')
select.addEventListener('change', () => {
// Sets the default frame color when adding the item
button.setAttribute("data-item-custom1-value", select.value)
})
</script>
This can be done by having multiple products behind the scenes, but making it appear to the user that there is only one product (per item). Then, changing which products (and custom attribute selection boxes) are visible depending on the first selection box.
I am a novice so there may be a simpler way to accomplish this, but this is what I came up with and it works well. Also, I am using a little jQuery in this code so it will require modifications to work without it.
<style>
.hidden{
display:none;
}
</style>
<select id="item-1">
<option value="1">Type 1</option>
<option value="2">Type 2</option>
</select>
<div id="type-1-1" class="item-content-1">
<select id="size-1-1">
<option value="8x8 ($50)">8x8 ($50)</option>
<option value="12x12 ($100)">12x12 ($100)</option>
<option value="20x20 ($200)">20x20 ($200)</option>
</select>
<button id="add-to-cart-1-1" class="snipcart-add-item"
data-item-id="product-1-1"
data-item-price="0.00"
data-item-url="https://example.com"
data-item-description="Product 1 type 1 description"
data-item-image="/img.jpg"
data-item-name="Product 1 type 1"
data-item-custom1-name="Size"
data-item-custom1-options="8x8 ($50)[+50.00]|12x12 ($100)[+100.00]|20x20 ($200)[+200.00]"
data-item-custom1-value="8x8 ($50)"
data-item-custom1-required="true">Add To Cart
</button>
</div>
<div id="type-1-2" class="item-content-1 hidden">
<select id="size-1-2">
<option value="8x8 ($90)">8x8 ($90)</option>
<option value="12x12 ($170)">12x12 ($170)</option>
<option value="20x20 ($300)">20x20 ($300)</option>
</select>
<button id="add-to-cart-1-2" class="snipcart-add-item"
data-item-id="product-1-2"
data-item-price="0.00"
data-item-url="https://example.com"
data-item-description="Product 1 type 2 description"
data-item-image="/img.jpg"
data-item-name="Product 1 type 2"
data-item-custom1-name="Size"
data-item-custom1-options="8x8 ($90)[+90.00]|12x12 ($170)[+170.00]|20x20 ($300)[+300.00]"
data-item-custom1-value="8x8 ($90)"
data-item-custom1-required="true">Add To Cart
</button>
</div>
<select id="item-2">
<option value="1">Type 1</option>
<option value="2">Type 2</option>
</select>
<div id="type-2-1" class="item-content-2">
<select id="size-2-1">
<option value="8x8 ($50)">8x8 ($50)</option>
<option value="12x12 ($100)">12x12 ($100)</option>
<option value="20x20 ($200)">20x20 ($200)</option>
</select>
<button id="add-to-cart-2-1" class="snipcart-add-item"
data-item-id="product-2-1"
data-item-price="0.00"
data-item-url="https://example.com"
data-item-description="Product 2 type 1 description"
data-item-image="/img.jpg"
data-item-name="Product 2 type 1"
data-item-custom1-name="Size"
data-item-custom1-options="8x8 ($50)[+50.00]|12x12 ($100)[+100.00]|20x20 ($200)[+200.00]"
data-item-custom1-value="8x8 ($50)"
data-item-custom1-required="true">Add To Cart
</button>
</div>
<div id="type-2-2" class="item-content-2 hidden">
<select id="size-2-2">
<option value="8x8 ($90)">8x8 ($90)</option>
<option value="12x12 ($170)">12x12 ($170)</option>
<option value="20x20 ($300)">20x20 ($300)</option>
</select>
<button id="add-to-cart-2-2" class="snipcart-add-item"
data-item-id="product-2-2"
data-item-price="0.00"
data-item-url="https://example.com"
data-item-description="Product 2 type 2 description"
data-item-image="/img.jpg"
data-item-name="Product 2 type 2"
data-item-custom1-name="Size"
data-item-custom1-options="8x8 ($90)[+90.00]|12x12 ($170)[+170.00]|20x20 ($300)[+300.00]"
data-item-custom1-value="8x8 ($90)"
data-item-custom1-required="true">Add To Cart
</button>
</div>
<script>
var item_count = 2; //number of items in shop
var type_count = 2; //number of type subdivisions
var i = 1;
for (i = 1; i <= item_count; i++) {
const type_select = document.querySelector('#item-' + i);
const count = i
type_select.addEventListener('change', () => {
$('.item-content-' + count).addClass("hidden");
$('#type-' + count + "-" + type_select.value).removeClass("hidden");
});
var ii = 1;
for (ii = 1; ii <= type_count; ii++) {
const addToCart = document.querySelector('#add-to-cart-' + i + "-" + ii);
const size = document.querySelector('#size-' + i + "-" + ii);
size.addEventListener('change', () => {
addToCart.setAttribute("data-item-custom1-value", size.value);
});
};
};
</script>
I believe you can do this with data-item-custom1-value:
data-item-custom1-name="Color"
data-item-custom1-options="Blue|Dark Gray|Light Gray"
data-item-custom1-value="Dark Gray"
Then use Javascript to change the data-item-custom1-value when a select is changed to the value of the select.
Complete Example
<div>
<label for="color">Color</label>
<select name="color" id="color">
<option value="Blue">Blue</option>
<option value="Dark Gray">Dark Gray</option>
<option value="Light Gray">Light Gray</option>
</select>
</div>
<button id="poster-cart-btn" class="snipcart-add-item btn btn-dark"
data-item-id="1"
data-item-price="9.95"
data-item-url="/"
data-item-name="Poster"
data-item-image="img/poster.png"
data-item-description="A pretty poster"
data-item-custom1-name="Color"
data-item-custom1-options="Blue|Dark Gray|Light Gray"
data-item-custom1-value="Blue">
Add to cart
</button>
<script type="text/javascript">
window.addEventListener('load', function() {
document.getElementById('color').onchange = function() {
const val = document.getElementById('color').value;
document.getElementById('poster-cart-btn').setAttribute('data-item-custom1-value', val);
}
});
</script>
iam not realy good in js, is there anyway to give .setAttribute more then 1 value to altering the price? Thanks alot
<select id="size-2-2">
<option value="8x8 ($90)">8x8 ($90)</option>
<option value="12x12 ($170)">12x12 ($170)</option>
<option value="20x20 ($300)">20x20 ($300)</option>
</select>
<select id="color-2-3">
<option value="color_1 ($90)">8x8 ($90)</option>
<option value="color_2 ($170)">12x12 ($170)</option>
<option value="color_3 ($300)">20x20 ($300)</option>
</select>
<button id="add-to-cart-2-2" class="snipcart-add-item"
data-item-id="product-2-2"
data-item-price="0.00"
data-item-url="https://example.com"
data-item-description="Product 2 type 2 description"
data-item-image="/img.jpg"
data-item-name="Product 2 type 2"
data-item-custom1-name="Size"
data-item-custom1-options="8x8 ($90)[+90.00]|12x12 ($170)[+170.00]|20x20 ($300)[+300.00]"
data-item-custom1-value="8x8 ($90)"
data-item-custom1-required="true"
data-item-custom2-name="Color"
data-item-custom2-options="color_1 ($90)[+90.00]|color_2 ($170)[+170.00]|color_3($300)[+300.00]"
data-item-custom2-value="color_1 ($90)"
data-item-custom2-required="true">Add To Cart
</button>
...
addToCart.setAttribute("data-item-custom1-value", size.value);
addToCart.setAttribute("data-item-custom2-value", size.value);
...
Thanks a lot #justin I modify your way dirty and it works fine for me! Now snipcart snacks all the values from the select fields with one button. I know there is a better way to load "window.addEventListener" x times. Feel free to post a better and simpler solution.
<div>
<label for="color-1">Color 1</label>
<select name="Color select 1" id="color_1">
<option value="color_1_1">0</option>
<option value="color_1_2">+11</option>
<option value="color_1_3">+111</option>
</select>
<label for="color-2">Color 2</label>
<select name="Color select 2" id="color_2">
<option value="color_2_1">0</option>
<option value="color_2_2">+12</option>
<option value="color_2_3">+112</option>
</select>
<label for="color-3">Color 3</label>
<select name="Color select 3" id="color_3">
<option value="color_3_1">0</option>
<option value="color_3_2">+13</option>
<option value="color_3_3">-113</option>
</select>
</div>
<button id="poster-cart-btn" class="snipcart-add-item"
data-item-id="1"
data-item-price="0.00"
data-item-url="/"
data-item-name="Poster"
data-item-image="img/poster.png"
data-item-description="A pretty poster"
data-item-custom1-name="Color 1"
data-item-custom1-options="color_1_1|color_1_2[+11.00]|color_1_3[+111.00]"
data-item-custom1-value="color_1_1"
data-item-custom2-name="Color 2"
data-item-custom2-options="color_2_1|color_2_2[+12.00]|color_2_3[+112.00]"
data-item-custom2-value="color_2_1"
data-item-custom3-name="Color 3"
data-item-custom3-options="color_3_1|color_3_2[+13.00]|color_3_3[+113.00]"
data-item-custom3-value="color_3_1">
Add to cart
</button>
<script type="text/javascript">
window.addEventListener('load', function() {
document.getElementById('color_1').onchange = function() {
const val = document.getElementById('color_1').value;
document.getElementById('poster-cart-btn').setAttribute('data-item-custom1-value', val);
}
document.getElementById('color_2').onchange = function() {
const val = document.getElementById('color_2').value;
document.getElementById('poster-cart-btn').setAttribute('data-item-custom2-value', val);
}
document.getElementById('color_3').onchange = function() {
const val = document.getElementById('color_3').value;
document.getElementById('poster-cart-btn').setAttribute('data-item-custom3-value', val);
}
});
</script>
Related
I am trying to show a table of reviews by taking the value of two dropdowns. When I was having one dropdown(positive, negative etc) that works fine but when I introduce another dropdown(food, drinks etc) it is not working.
It only works when I change the first dropdown and second dropdown but if I kept the first dropdown unchanged then it's not working
I tried by adding onchange method to the second dropdown. I just started with Javascript so not much idea about what to try.
function printResult(form) {
var output = {
{
output | safe
}
};
var sel = form.list;
var sel2 = form.list2;
var selectedVal = sel.options[sel.selectedIndex].value;
var selectedVal2 = sel2.options[sel.selectedIndex].value;
//document.getElementById("showResult").innerText = "Your number is: " + selectedVal;
//console.log(output);
document.getElementById("showResult").innerText = "Your number is: " + selectedVal2;
}
<form action="dropdown" onSubmit="return printResult(this);">
<label for="sentiment">Sentiment</label>
<div class="styled-select blue semi-square">
<select name="list">
<option value="all">All</option>
<option value="positive">Positive</option>
<option value="negative">Negative</option>
<option value="neutral">Neutral</option>
</select>
</div>
<div>
<select name="list2" onChange="printResult()">
<option value="menu">Menu Range</option>
<option value="food">Food</option>
<option value="drinks">Drinks</option>
<option value="desserts">Desserts</option>
</select>
</div>
<input type="submit" value="Filter">
<span id="showResult"></span>
</form>
You need to pass the form on the change too and return false to not submit the form:
function printResult(form) {
var sel = form.list;
var sel2 = form.list2;
var selectedVal = sel.value;
var selectedVal2 = sel2.value;
document.getElementById("showResult").innerText = "Your number is: " + selectedVal2;
return false;
}
<form action="dropdown" onSubmit="return printResult(this);">
<label for="sentiment">Sentiment</label>
<div class="styled-select blue semi-square">
<select name="list">
<option value="all">All</option>
<option value="positive">Positive</option>
<option value="negative">Negative</option>
<option value="neutral">Neutral</option>
</select>
</div>
<div>
<select name="list2" onChange="printResult(this.form)">
<option value="menu">Menu Range</option>
<option value="food">Food</option>
<option value="drinks">Drinks</option>
<option value="desserts">Desserts</option>
</select>
</div>
<input type="submit" value="Filter">
<span id="showResult"></span>
</form>
Perhaps you wanted this instead
window.addEventListener("load", function() {
document.getElementById("form1").addEventListener("submit", function(e) {
e.preventDefault(); // stop submission
var sel = this.list;
var sel2 = this.list2;
var selectedVal = sel.value;
var selectedVal2 = sel2.value;
document.getElementById("showResult").innerText = (selectedVal && selectedVal2) ? selectedVal + ":" + selectedVal2 : "Please select both";
});
});
<form action="dropdown" id="form1">
<label for="sentiment">Sentiment</label>
<div class="styled-select blue semi-square">
<select name="list">
<option value="">All</option>
<option value="positive">Positive</option>
<option value="negative">Negative</option>
<option value="neutral">Neutral</option>
</select>
</div>
<div>
<select name="list2">
<option value="">Menu Range</option>
<option value="food">Food</option>
<option value="drinks">Drinks</option>
<option value="desserts">Desserts</option>
</select>
</div>
<input type="submit" value="Filter">
<span id="showResult"></span>
</form>
I have select dropdown i have 2 different shipping methods available in that dropdown. If i select sipping 1 i want to hide the Rest fexex shipping options
& vice versa if i selected any of the fedex method i want to hide freeshipping
please check js fiddle below
<fieldset>
<select name="shipping_method" id="shipping_method" style="width:250px;" class="required-entry">
<option value="">Please select a shipping method...</option>
<optgroup label="Free Shipping" style="font-style:normal;">
<option value="freeshipping_freeshipping">
Shipping1 - $0.00
</option>
</optgroup>
<optgroup label="FedEx" style="font-style:normal;">
<option value="fedex_FEDEX_GROUND">
Fedex1 - $18.07
</option>
<option value="fedex_FEDEX_2_DAY">
Fedex2 - $30.62
</option>
<option value="fedex_STANDARD_OVERNIGHT">
Fedex3 - $81.34
</option>
</optgroup>
</select>
</fieldset>
Clear Shipping Selection
<p class="actions">
<button id="update_shipping_method_submit" type="submit" class="button" style="display: none;"><span><span>Update Shipping Method</span></span></button>
</p>
jsfiddle
Try something like this(not tested)
$('select').on('change', function() {
var arr1 = $('#shipping_method option:not(:selected)');
for (var i = 0; i < arr1.length; i++) {
$("#shipping_method").children("optgroup[label='" + arr1[i].value + "']").remove();
console.log("removed");
}
})
I'm able to clone the #ingredient_1 div with the Add button. However, after pressing Add several times, then deleting random cloned divs with their specific X buttons, the Add button stops working.
I've replicated this problem across several browsers. Any advice would go a long way.
$('#add_more').click(function() {
var num = $('.clone').length;
var newNum = num + 1;
var newElem = $('#ingredient_1').clone().attr('id', 'ingredient' + '_' + newNum);
$('#ingredient_' + num).after(newElem);
});
$('#main').on('click', '.remove', function() {
$(this).parent().remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<div id="ingredient_1" class="clone">
<select id="1">
<option selected="selected">Please Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<input type="text" name="name" placeholder="Amount" />
<select id="2">
<option selected="selected">Units</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<select id="3">
<option selected="selected">Time</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<button class="remove">X</button>
</div>
<div id="add_button">
<input type="button" id="add_more" value="Add" />
</div>
</div>
Once you delete the first row the element you're cloning no longer exists. Clone the element outside your click function so it's not overwritten:
var newElem = $('#ingredient_1').clone().attr('id', 'ingredient' + '_' + newNum);
var num = 1;
$('#add_more').click(function() { ... });
Also, declare your ID incrementor outside the function and simply add 1 each time the click function runs with num++. I'm guessing that it doesn't really matter what the ID values are, so as long as they're unique this works.
The problem is that you're using .length to calculate newNum. If you delete DIVs in the middle, you'll end up with duplicate IDs. For instance, suppose you first add 3 DIVs, you'll have DIVs numbered 1, 2, 3, 4. Then you delete #3. The next time you click Add, $(".clone").length will be 3, so you'll set newNum = 4;. But there's still a DIV with that ID.
Instead of using $(".clone").length, get the ID of $(".clone:last"), get the number at the end of it, and add 1 to that.
You're cloning, which if you have at least one static item, is fine. I fixed up your code so your initial row is hidden, and you have an ID variable that is auto incremented. On top of which, on load, it creates clones and creates the first row. Your back end code will just have to ignore a case where the style is set to display:none.
var id = 1;
$(function () {
var first = $('.clone');
first.attr('style', 'display:none');
NewRow();
});
$('#add_more').click(function () {
NewRow();
});
function NewRow() {
console.log('num = ' + id++);
var newElem = $('.clone:last').clone().attr('id', 'ingredient' + '_' + id + '_x');
newElem.attr('style', '');
$('.clone:last').after(newElem);
}
$('#main').on('click', '.remove', function () {
$(this).parent().remove();
});
You'll notice that I changed your click event to call the function NewRow(), this was done so that you can call a function in the Document.Ready event, as well as on the button click.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<div id="ingredient_1" class="clone">
<select id="1">
<option selected="selected">Please Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<input type="text" name="name" placeholder="Amount" />
<select id="2">
<option selected="selected">Units</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<select id="3">
<option selected="selected">Time</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<button class="remove">X</button>
</div>
<div id="add_button">
<input type="button" id="add_more" value="Add" />
</div>
</div>
Working JSFiddle is here
I have a set of dropdown fields (using knockout.js) that is "dynamically" building two javascript functions that I use on my website and that I am triggering with a link.
The first function is building perfectly.
The second function uses the dropdown "Duration" to make the "VIP Plus 1 year" or "VIP Plus 2 years" options to appear/disappear and build the second function.
The problem is when I select "1 year" in "Duration" and then "Vip Plus 1" option, the correct sku is added to my second function, BUT if I change my mind and select "2 years" in Duration, the value stays in the second function and is added to the new "VIP Plus 2 years" sku in my output.
Ideally, if nothing is selected from the "VIP Plus 1 year" or "VIP Plus 2 years" dropdowns, the second function would just not appear at all.
This is probably very easy to solve but since I am a beginner in js, I'm stucked there...
See my preview at http://jsfiddle.net/X6fJ5/3/
<p>Membership : <select name="no1" data-bind="value: membership" />
<option value="NEW">New membership</option>
<option value="RENEW">Renew membership</option>
<option value="GIFT">Gift membership</option>
</select>
</p>
<p>Category : <select name="no2" data-bind="value: category" />
<option value="1400">VIP Individual</option>
<option value="709">VIP Family</option>
<option value="703">VIP ang Guest</option>
<option value="1389">VIP Student</option>
</select>
</p>
<p>Duration : <select name="no3" data-bind="value: duration" id="opts" onchange="showForm();" />
<option value="1" selected="selected">1 an</option>
<option value="2">2 ans</option>
</select>
</p>
<div id="f1" style="display:none">
<p>VIP Plus 1 year : <select name="no4" data-bind="value: vipplus1" id="opts" />
<option value="" selected="selected">No thanks</option>
<option value="DON-VIPPLUS1-125">VIP Plus 1</option>
<option value="DON-VIPPLUS1-250">VIP Plus 2</option>
<option value="DON-VIPPLUS1-500">VIP Plus 3</option>
</select>
</div>
<div id="f2" style="display:none">
VIP Plus 2 years : <select name="no5" data-bind="value: vipplus2" id="opts" />
<option value="" selected="selected">No thanks</option>
<option value="DON-VIPPLUS2-250">VIP Plus 1</option>
<option value="DON-VIPPLUS2-500">VIP Plus 2</option>
<option value="DON-VIPPLUS2-1000">VIP Plus 3</option>
</select>
</p></div>
<br />
Add to cart
<br />
<h3><span data-bind="html: mvipsku"> </span></h3>
<script type="text/javascript">
var ViewModel = function(membership, category, duration, vipplus1, vipplus2) {
this.membership = ko.observable(membership);
this.category = ko.observable(category);
this.duration = ko.observable(duration);
this.vipplus1 = ko.observable(vipplus1);
this.vipplus2 = ko.observable(vipplus2);
this.mvipsku = ko.computed(function() {
return "addMembershipToCart('" + "MVIP-" + this.membership() + "-" + this.duration() + "-" + this.category() + "');" + "<br />" + "addProductToCart('" + this.vipplus1() + this.vipplus2() + "');";
}, this);
};
ko.applyBindings(new ViewModel()); // This makes Knockout get to work
function showForm() {
var selopt = document.getElementById("opts").value;
if (selopt == 1) {
document.getElementById("f1").style.display = "block";
document.getElementById("f2").style.display = "none";
}
if (selopt == 2) {
document.getElementById("f2").style.display = "block";
document.getElementById("f1").style.display = "none";
}
}
</script>
You should subscribe to the change of duration and clear the apprpropriate VIP Plus setting:
self.duration.subscribe(function(newValue) {
if(newValue == '1') {
self.vipplus2(null);
} else if(newValue == '2') {
self.vipplus1(null);
}
});
JSFiddle
My code below is showing the proper city/state div's when the matching country is selected from the drop down, but it's not hiding the previous one if the user decides to select another state. Do I have to create an if/else each for each div i want to hide?
<script type="text/javascript">
$(document).ready(function() {
...
//city & state display
$("#ctry").change(function() {
$(".state").hide();
var stateSelect = $("#state_" + $(this).val());
if (stateSelect.length === 0)
$("#state_label").hide();
else {
$("#state_label").show();
stateSelect.show();
}
});
});
</script>
html code:
<label>Country/Locale:</label>
<select id="ctry" name="country">
<option value="">-- Select</option>
<option value="US">United States</option>
<option value="CA">Canada</option>
<option value="GB">United Kingdom</option>
<option value="AU">Australia</option>
</select><br />
<!-- US -->
<div id="state_US" style="display:none">
<label id="state_label" style="display:none">State:</label>
<span class="rstate">
<select name="u_state">
<option value="">-- State US</option>
<option value="AL">Alabama</option>
</select>
</span>
Zip or City:<input style="margin-left:43px;" type="text" name="locus" id="locus" size="30" />
</div>
<!-- CA -->
<div id="state_CA" style="display:none">
<label id="state_label" style="display:none">Province:</label>
<span class="rstate">
<select name="c_state">
<option value="">-- Prov CA</option>
<option value="ON">Windsor</option>
</select>
</span>
Postal or Place:<input style="margin-left:43px;" type="text" name="locca" id="locca" size="30" />
</div>
<!-- GB -->
<div id="state_GB" style="display:none">
<label id="state_label" style="display:none">City or Region:</label>
<span class="rstate">
<select name="k_state">
<option value="">-- Place</option>
<option value="AU">UK!</option>
</select>
</span>
</div>
<!-- AU -->
<div id="state_AU" style="display:none">
<label id="state_label" style="display:none">City or Region:</label>
<span class="rstate">
<select name="a_state">
<option value="">-- Place</option>
<option value="AU">UK!</option>
</select>
</span>
</div>
Remove the state_label ids..
Add the unused class state to the state_CA, state_US etc. elements..
So each state group should be
<div id="state_US" class="state" style="display:none">
<label style="display:none">State:</label>
<span class="rstate">
<select name="u_state">
<option value="">-- State US</option>
<option value="AL">Alabama</option>
</select>
</span>
Zip or City:<input style="margin-left:43px;" type="text" name="locus" id="locus" size="30" />
</div>
And change your script to be
<script type="text/javascript">
$(document).ready(function() {
...
//city & state display
$("#ctry").change(function() {
$(".state").hide();
var stateSelect = $("#state_" + $(this).val());
stateSelect.show();
});
});
</script>
Demo at http://jsfiddle.net/gaby/PYx2v/
You cannot have multiple elements with the same ID. Your label state_Label is not unique. You should change this, otherwise some browsers will not show your label.
You hide all elements having the css-class "state". But there is no element having this class. I guess that you need to add class="state" to all of your state_*-divs.
Something like this logic might work for you:
var previous;
$(document).ready(function() {
$("#ctry").change(function() {
$(".state").hide();
var stateSelect = $("#state_" + $(this).val());
if (stateSelect.length === 0) {
$("#state_label").hide();
} else {
if (previous) {
previous.hide(function() {
$("#state_label").show();
stateSelect.show();
previous = stateSelect;
});
} else {
$("#state_label").show();
stateSelect.show();
previous = stateSelect;
}
}
});
});
Though it would be easier if they all had the same CSS class, with which you could easily hide them and then show the one that was selected.