jQuery: Cannot select val='' from generated dropdown list - javascript

I have the following JS for generating a dropdown list for provinces/states:
var populateList = function (list, element) {
element.append("<option val=''>Select...</option>")
list.forEach(function (val) {
element.append("<option val=" + val[0] + ">" + val[1] + "</option>");
})
}
var canProvinces = [
['ON', 'Ontario'],
['QC', 'Quebec'],
['NS', 'Nova Scotia'],
['NB', 'New Brunswick'],
['MB', 'Manitoba'],
['BC', 'British Columbia'],
['PE', 'Prince Edward Island'],
['SK', 'Saskatchewan'],
['AB', 'Alberta'],
['NL', 'Newfoundland and Labrador'],
['NT', 'Northwest Territories'],
['YT', 'Yukon'],
['NU', 'Nunavut']];
The idea I'm working towards is when the user switches countries in a form, the system can use populateList() to switch to a new list whenever the user switches countries. Then I use jQuery to put the province abbreviation in a hidden input field. Here is the code in the form:
<script src="list-of-provices/states-from-above.js"></script>
<input id="UserCountry" value="CA" type="text" /> <!-- to be converted to dropdown when issue resolves -->
<select id="province-select" name="province-select"></select>
<input id="Province" type="hidden"/>
<script>
$(document).ready(function () {
if ($('#UserCountry').val() == 'CA') {
populateList(canProvinces, $("#province-select"));
} else if ($('#UserCountry').val() == 'US') {
populateList(usaStates, $("#province-select"));
}
$('#province-select').bind('input propertychange', function () {
//something wrong here? Returns full name, not 2 letter abbreviation.
console.log($("#province-select").val())
$('#Province').val($("#province-select").val())
})
});
</script>
I haven't got to the Country switching part yet because, despite everything I've tried, $("#province-select").val() returns the Text from the dropdown, not the value. I have not been able to find a reason for this. Here is the HTML generated by the code:
<select id="province-select" name="province-select">
<option val="">Select...</option>
<option val="ON">Ontario</option>
<option val="QC">Quebec</option>
<option val="NS">Nova Scotia</option>
<option val="NB">New Brunswick</option>
<option val="MB">Manitoba</option>
<option val="BC">British Columbia</option>
<option val="PE">Prince Edward Island</option>
<option val="SK">Saskatchewan</option>
<option val="AB">Alberta</option>
<option val="NL">Newfoundland and Labrador</option>
<option val="NT">Northwest Territories</option>
<option val="YT">Yukon</option>
<option val="NU">Nunavut</option>
</select>
Is there something I am missing? $("#province-select").val() should return the val="" from the dropdown, but for me it returns the text.
Any thoughts?

You have a small mistake in your code. The attribute to be used for setting the value of option is value and not val. Replace your
element.append("<option val=" + val[0] + ">" + val[1] + "</option>");
with
element.append("<option value='" + val[0] + "'>" + val[1] + "</option>");
and you are good.

Related

Conditional show/hide elements based on previous dropdown list doesn't work on iphone-Safari

The following code doesn't work for iPhone/Safari.
Each dropdown list redirects to a given URL (in the value), which is stored with localstorage and then retrieved. The selected option of the first list conditions the options to be shown in the second and third list, and the one selected in the second list conditions the elements to be shown in the third list.
This works fine in Chrome (and others I've tried), but it's not working on iPhone. What should I change?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="CCAA">Vehicle:</label>
<select id="CCAA" name="vehicle">
<option disabled selected>Select a vehicle</option>
<option class="car" value="/eee?cars"> Cars</option>
<option class="motorcycle" value="/eee?motorcycles"> Motorcycles</option>
</select>
<label for="provincia">Manufacturer:</label>
<select id="provincia" name="manufacturer">
<option disabled selected>Selecct a manufacturer</option>
<option class="car" id="ford" value="/eee?ford"> Ford</option>
<option class="car" id="chevrolet" value="/eee?chevrolet"> Chevrolet</option>
<option class="motorcycle" value="/eee?motorcycles">Motorcycles</option>
<option class="motorcycle" id="honda" value="/eee?honda"> Honda</option>
<option class="motorcycle" id="yamaha" value="/eee?yamaha"> Yamaha</option>
</select>
<label for="model">Model:</label>
<select id="model" name="model">
<option disabled selected>Select a model</option>
<option class="car" id="ford" value="/eee?model=focus">Focus</option>
<option class="car" id="ford" value="/eee?model=mustang">Mustang</option>
<option class="car" id="chevrolet" value="/eee?model=camaro">Camaro</option>
<option class="car" id="chevrolet" value="/eee?model=corvette">Corvette</option>
<option class="motorcycle" id="honda" value="/eee?model=cbr">CBR</option>
<option class="motorcycle" id="honda" value="/eee?model=civic">Civic</option>
<option class="motorcycle" id="yamaha" value="/eee?model=r1">R1</option>
<option class="motorcycle" id="yamaha" value="/eee?model=r6">R6</option>
</select>
<script type="text/javascript">
jQuery(function($){
// On change of the first dropdown
$("#CCAA").on("input",function(){
var levelClass = $('#CCAA').find('option:selected').attr('class');
// Store the selected option value and text for the first dropdown
localStorage.setItem("selectedVehicleValue", $('#CCAA').val());
localStorage.setItem("selectedVehicleOption", $('#CCAA').find('option:selected').text());
// Show options with the same class as the selected option in the first dropdown list
// in the second dropdown list
$('#provincia option.' + levelClass).show();
$('#provincia option:not(.' + levelClass + ')').hide();
// Redirect to the selected option's value
window.open($('#CCAA').val(), '_self');
});
// On change of the second dropdown
$('#provincia').on("input",function(){
var levelClass = $(this).val().split("?")[1];
var selectedOption = $(this).find("option:selected").text();
// Store the selected option value and text for the second dropdown
localStorage.setItem("selectedManufacturerValue", levelClass);
localStorage.setItem("selectedManufacturerOption", selectedOption);
var selectedId = $(this).find("option:selected").attr("id");
// Show options with the same id as the selected option in the second dropdown list
// in the third dropdown list
$('#model option.' + levelClass + '#' + selectedId).show();
$('#model option:not(.' + levelClass + '#' + selectedId + ')').hide();
// Redirect to the selected option's value
window.open($(this).val(), '_self');
});
// On change of the third dropdown
$('#model').on("input",function(){
var getValue = $(this).val();
var selectedOption = $(this).find("option:selected").text();
// Store the selected option value and text for the third dropdown
localStorage.setItem("selectedModelValue", getValue);
localStorage.setItem("selectedModelOption", selectedOption);
// Redirect to the selected option's value
window.open(getValue, '_self');
});
// On page load, check for stored values
var storedVehicleOption = localStorage.getItem("selectedVehicleOption");
var storedManufacturerOption = localStorage.getItem("selectedManufacturerOption");
var storedModelOption = localStorage.getItem("selectedModelOption");
if(storedVehicleOption){
// Set the stored option as selected for the first dropdown
$("#CCAA option:contains(" + storedVehicleOption + ")").prop('selected', true);
// Set the stored option as selected for the second dropdown
$("#provincia option:contains(" + storedManufacturerOption + ")").prop('selected', true);
var levelClass = $('#CCAA').find('option:selected').attr('class');
var selectedId = $('#provincia').find("option:selected").attr("id");
$('#provincia option.' + levelClass).show();
$('#provincia option:not(.' + levelClass + ')').hide();
$('#model option.' + levelClass + '#' + selectedId).show();
$('#model option:not(.' + levelClass + '#' + selectedId + ')').hide();
}
if(storedModelOption){
// Set the stored option as selected for the third dropdown
$("#model option:contains(" + storedModelOption + ")").prop('selected', true);
}
});
</script>
I have tried using the data-* instead of class and ID but still gives me the same error: every option is shown in Safari-iPhone. I have also tried changing the trigger, but sitll happens the same.
I'm probably missing some bits to understand why is the list fully shown in iPhone.

Fill in dropdown after a different dropdown gets selected

I am trying to come up with a way that would automatically populate a drop down based on the value selected in a different drop down.
Lets say I have a drop down for State / Province. Depending which value gets selected it would fill in the Country drop down to be USA / CAN.
<select name="formState" class="form-control modeldropdown" id="state" required>
<option value="">State / Province</option>
<option value="">--- United States ---</option>
<option value="AL">Alabama - AL</option>
...
<option value="MH">Marshall Islands - MH</option>
<option value="">--- Canada ---</option>
<option value="AB">Alberta - AB</option>
<option value="BC">British Columbia - BC</option>
...
</select>
It would be easier to do it the reversed way (select a country then it filters) -- for that I would do something like this
var jsonText = '{"USA":{ '
+ '"Alabama": "Alabama",'
+ '"Alaska": "Alaska",'
+ '},'
+ '"CAN":{'
+ '"Alberta": "Alberta",'
+ '}}';
var json = JSON.parse(jsonText);
And then filter it based on which Country was selected, but is there an easy way to do the reversed?
The only way I can think to do this is by checking the value to see if it is:
var state = $('#state').val();
if ( state == 'Alabama' || state == 'Alaska'...)
...
You could make an object that maps from state/province to country:
const countryOfState = {
'Alabama' : 'USA',
'Alberta' : 'CAN'
};
let state = $('#state').val();
if (countryOfState[state] === 'USA') {
...
You can use indexOf to check if an element exists in an array like so:
const states = {
'USA': ['Alabama'],
'CAN': ['Alberta']
};
function getCountry(state) {
for (let country in states) {
if (states[country].indexOf(state) >= 0) {
return country;
}
}
return null;
}
console.log(getCountry('Alberta')); //CAN
Here's a slightly sideways approach using optgroup which I think works better for your data anyway. I've also utilised data attributes
$('#state').change(function() {
var optGroup = $(this.options[this.selectedIndex]).closest('optgroup');
var label = $(optGroup).prop('label');
var cCode = $(optGroup).data('countrycode');
$('#country').html('<option value="'+ cCode + '">' + label + '</option>');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select name="formState" class="form-control modeldropdown" id="state" required>
<option value="">State / Province</option>
<optgroup label="United States" data-countryCode="USA">
<option value="AL">Alabama - AL</option>
<!-- ... -->
<option value="MH">Marshall Islands - MH</option>
</optgroup>
<optgroup label="Canada" data-countryCode="CA">
<option value="AB">Alberta - AB</option>
<option value="BC">British Columbia - BC</option>
</optgroup>
</select>
<select id="country" name="country"><option disabled selected>Please Select State</option></select>

How can i add value in Option Select?

i have a textarea text "ez.aaaa.value" i want to typing a text and when i select option , redirect automatically to google.com/search?tbm=isch&q= + ((value textarea))
image
Example :
........
<option value="href='http://www.google.com/search?tbm=isch&q=' + ez.aaaa.value">google search</option>
........
This should do it.
the location.href is what you would use to link out.
this refers to the select and selectedIndex returns the number of the selected option.
var sel = document.getElementById('mysel'),
query = document.getElementById('myquery');
sel.addEventListener('change' , function() {
console.log(this.options[this.selectedIndex].value + query.value);
// this would be how to link below
// location.href = this.options[this.selectedIndex].value + query.value;
});
<input type='text' id="myquery">
<select id="mysel">
<option>SELECT ONE</option>
<option value="http://google.com?q=">google</option>
<option value="http://bing.com?q=">bing</option>
</select>
Add select with ID outside of your option and then try this way
JS
var e = document.getElementById("select-menu");
var strUser = e.options[e.selectedIndex].value;
console.log(strUser);
HTML
<select id="select-menu">
<option value="href='http://www.google.com/search?tbm=isch&q=' + ez.aaaa.value">google search 1</option>
<option value="href='http://www.google.com/search?tbm=isch&q=' + ez.aaaa.value" selected="selected">google search 2</option>
</select>

How to pass options combinations to PHP form using js or jquery

So, for example I have three select boxes.
<select name="cat-1" id="cat-1">
<option value="0">A</option>
<option value="1">B</option
</select>
<select name="cat-2" id="cat-2">
<option value="0">AA</option>
<option value="1">BB</option
</select>
<select name="cat-3" id="cat-3">
<option value="0">AAA</option>
<option value="1">BBB</option
</select>
<input type="submit" value="Add">
If I choose options, for example A BB AAA and press ADD, i want this combination to appear as text under add button as: A BB AAA (X) x - to cancel such combination. I would like to add up to 3 combinations with ability to cancel any combination. After submitting form, I want to pass such combinations values in this case I guess array [0, 1, 0] would be fine. Options values cannot be submitted separately, because cat-2 and cat-3 are populated dynamically using ajax - cat-3 depends on cat-2 and cat-2 depends on cat-1 so many combinations are possible.
I am using select2 (http://select2.github.io/examples.html). It would be perfect If I could return combinations in style similar to 'Multiple select boxes' (see link above).
Any idea where do I start? I have no idea how to implement this the right way with ability in future, for example, on click on combination to set select boxes to combination values and etc.
I guess final input to database will be generated array of arrays like [[0,1,0], [0,0,0], [1,0,3], ...] in hidden field?
I have written my own piece of code to handle this problem. Here is working example: http://jsfiddle.net/s2arvdck/13/
<select name="cat_1" id="cat_1">
<option value="0">I</option>
<option value="1">II</option>
<option value="2">III</option>
</select>
<select name="cat_2" id="cat_2">
<option value="0">A</option>
<option value="1">B</option>
<option value="2">C</option>
</select>
<select name="cat_3" id="cat_3">
<option value="0">a</option>
<option value="1">b</option>
<option value="2">c</option>
</select>
<input type="button" id="addButton" value="Add">
<br />Combinations: <span id="combContainer"></span>
<br />Expected hidden: <span id="expected"></span>
$('#addButton').on('click', addButtonClicked);
function addButtonClicked(event) {
var cat1 = $('#cat_1 option:selected').val();
var cat2 = $('#cat_2 option:selected').val();
var cat3 = $('#cat_3 option:selected').val();
if ($('#combContainer:contains("[' + cat1 + ', ' + cat2 + ', ' + cat3 + ']")').length == 0) {
$('#combContainer').append('<div><span class="comb">[' + cat1 + ', ' + cat2 + ', ' + cat3 + ']</span> <span id="combDel">remove</span></div>');
}
var arr = [];
$('.comb').each(function (index, elem) {
arr.push($(this).text());
$('#expected').text(arr.join(''));
});
$("#combContainer").on("click", "#combDel", function () {
var text = $(this).closest("div").children(".comb").text();
if ($('#combContainer:contains("[' + text + ']")').length == 0) {
$(this).closest("div").remove();
var expectedText = $("#expected").text();
var newExpectedText = expectedText.replace(text, '');
$("#expected").text(newExpectedText);
}
});
}

Select empty value in dropdown list with jQuery if not contains string

I'am trying to select the empty (first) value of a dropdown select option if it does not contains the value from an another dropdown select list:
$('#FirstDropdown').change(function() {
if ( $('#SecondDropdown option').filter(':contains(' + this.value + ')') ){
$('#SecondDropdown option').filter(':contains(' + this.value + ')').prop('selected',true);
}else{
$("#SecondDropdown option[value='']").prop('selected',true);
}
});
This code work well if #SecondDropdown option contains this.value but the else statement doesn't reset the dropdown list if not.
Any suggestion please ?
EDIT : The dropdown lists look like this :
<select id="FirstDropdown">
<option value="" selected="selected"> </option>
<option value="VAL1">First Value</option>
<option value="VAL2">Second Value</option>
<option value="VAL3">Third Value</option>
<option value="VAL4">Fourth Value</option>
</select>
<select id="SecondDropdown">
<option value="-1"> </option>
<option value="12">VAL1 SELECT OPTION</option>
<option value="15">VAL2 SELECT OPTION</option>
<option value="10">VAL3 SELECT OPTION</option>
</select>
EDIT : Added a JsFiddle.
You do not have any option element having value=''. You need to use $("#SecondDropdown option[value='-1']").prop('selected',true); . you would also need to change the condition in if statement to this.value!='':
$('#FirstDropdown').change(function() {
if ( this.value!='' ){
$('#SecondDropdown option').filter(':contains(' + this.value + ')').prop('selected',true);
}else{
$("#SecondDropdown option[value='-1']").prop('selected',true);
}});
Working Demo
Try this :There is problem in your if condition as it is getting always true. You can use .length to check if option exist and select the option else select blank
$('#FirstDropdown').change(function() {
if ($('#SecondDropdown option:contains('+this.value +')').length>0){
$('#SecondDropdown option:contains('+this.value +')').prop('selected',true);
}else{
$("#SecondDropdown option[value='-1']").prop('selected',true);
}
});
JSFiddle Demo
This will work for you.
First, you have to check you this.value, because any string contains ''.
Second, as if works fine, you just need to filter options by [value=-1]
Final JS:
$('#FirstDropdown').change(function() {
var $second = $('#SecondDropdown option').filter(':contains(' + this.value + ')');
if (this.value && $second){
$second.prop('selected',true);
}else{
$("#SecondDropdown option[value=-1]").prop('selected',true);
}
});

Categories

Resources