Below is what I currently have. I am now looking to be able to: When they click on artist one it will then take them to another drop down menu where there will be more options about Artist One. And the same if they chose Artist Two etc. Instead of just having an alert.
How would I go about that?
Thank you :)
<form>
<select id="mySelect">
<option value="void">Choose your answer</option>
<option value="artistOne">One</option>
<option value="artistTwo">Two</option>
<option value="artistThree">Three</option>
</select>
</form>
<button id="button" onclick="artist();" type="button">Confirm</button>
Javascript:
function artist() {
var select = document.getElementById("mySelect");
var artist = select.options[select.selectedIndex].value;
if(artist == "artistOne"){
alert("You have chosen Artist One!");
}
else if (artist == "artistTwo"){
alert("You have chosen Artist Two!");
}
}
function artist() {
var select = document.getElementById("mySelect");
var artist = select.options[select.selectedIndex].value;
var newSelectContainer = document.getElementById("artistDetails");
if(artist == "artistOne"){
createArtistSelect(newSelectContainer, ["Artist Detail 1", "Artist Detail 2", "Artist Detail 3"]);
}
else if (artist == "artistTwo"){
createArtistSelect(newSelectContainer, ["Artist2 Detail 1", "Artist2 Detail 2"]);
}
}
function createArtistSelect(elem, options){
//Create and append select list
var dynamicSelect = document.getElementById("dynamicSelect");
if(dynamicSelect)
dynamicSelect.outerHTML = "";
var selectList = document.createElement("select");
selectList.id = "dynamicSelect";
elem.appendChild(selectList);
//Create and append the options
for (var i = 0; i < options.length; i++) {
var option = document.createElement("option");
option.value = options[i];
option.text = options[i];
selectList.appendChild(option);
}
}
If you change your javascript code to this you will generate a drop down menu with the passed options.
You need to change a bit your html:
<form>
<div id="artistDetails">
<select id="mySelect">
<option value="void">Choose your answer</option>
<option value="artistOne">One</option>
<option value="artistTwo">Two</option>
<option value="artistThree">Three</option>
</select>
</div>
</form>
<button id="button" onclick="artist();" type="button">Confirm</button>
I created a function that is called on the onChange of the select (you can change it to be on the onClick of the input)
var details1 = ["1-1", "1-2", "1-3"];
var details2 = ["2-1", "2-2", "2-3", "2-4"];
var details3 = ["3-1", "3-2"];
function CreateCmb(artist) {
var cmbDetails = document.getElementById('cmbDetails');
if (cmbDetails !== null) {
while (cmbDetails.options.length > 0)
cmbDetails.remove(0);
} else {
cmbDetails = document.createElement("select");
cmbDetails.id = "cmbDetails";
body.appendChild(cmbDetails);
}
var currentDetails = [];
if (artist === "artistOne") currentDetails = details1;
else if (artist === "artistTwo") currentDetails = details2;
else if (artist === "artistThree") currentDetails = details3;
for (var i = 0; i < currentDetails.length; i++) {
var option = document.createElement("option");
option.text = currentDetails[i];
option.value = currentDetails[i];
cmbDetails.appendChild(option);
}
}
How it works:
First it get the dynamic select, then check if he is NOT null (is created). If this is the case, it delete all the option. If the select is null (not yet created), it create it and place it in the body.
Then it check wich details he need to show (the if else if block).
To finish, I looped the details and create the new options.
The nice part about this is that you will always have only one dynamic select because if he already exist, he reuse it ! That allow you to manually create and place it somewhere and he will use it if he have the correct id (in this case 'cmbDetails')
See this FIDDLE for an example !
Related
I'd like to add the same options elements to more than one select, using one JavaScript function.
<select id="select1" name="select1"></select>
<select id="select2" name="select2"></select>
I want selects become:
<select id="select1" name="select1">
<option value="0">Txt1</option>
<option value="1">Txt2</option>
<option value="2">Txt3</option>
</select>
<select id="select2" name="select2">
<option value="0">Txt1</option>
<option value="1">Txt2</option>
<option value="2">Txt3</option>
</select>
Here is part of function to fill selects with options:
function window_onload(){
var SpecTxt = new Array("Txt1","Txt2","Txt3");
for(var i=0; i<SpecTxt.length; i++) {
var oOption = document.createElement("OPTION");
oOption.text = SpecTxt[i];
oOption.value=i;
select1.add(oOption); // Option to first SELECT
select2.add(oOption); // Option to second SELECT
}
}
But I've got Internet Explorer Script Error "Invalid argument", result is only one first option in "select1" and no options in "select2". If I remove from function window_onload() the last string select2.add(oOption);, there are no IE errors and "select1" is filled as must be, but "select2" is empty. How is it possible in JS to add the same options to different SELECTs?
Update
The reason why the Demo didn't work for IE is because it doesn't recognize the property .valueAsNumber.
From:
var opts = qty.valueAsNumber;
To:
var opts = parseInt(qty.value, 10);
When you create an option within the loop:
var oOption = document.createElement("OPTION");
That is only one <option> not two <option>s. So that is the reason why:
select1.add(oOption); // Succeeds
select2.add(oOption); // Fails
You can either make 2 <option>s per loop:
var oOption1 = document.createElement("OPTION");
var oOption2 = document.createElement("OPTION");
OR try cloneNode(). See Demo below:
Demo
// See HTMLFormControlsCollection
var form = document.forms.ui;
var ui = form.elements;
var qty = ui.qty0;
var s0 = ui.sel0;
var s1 = ui.sel1;
// Declare a counter variable outside of loop
var cnt = 0;
// Add event handler to the change event of the input
qty.onchange = addOpt;
/* Get the value of user input as a number
|| within the for loop...
|| create an <option> tag...
|| add text to it with an incremented offset...
|| add a incremented value to it...
|| then clone it...
|| add original <option> to the first <select>...
|| add duplicate <option> to the second <select>
*/
function addOpt(e) {
var opts = parseInt(qty.value, 10);
for (let i = 0; i < opts; i++) {
var opt = document.createElement('option');
opt.text = 'Txt' + (cnt + 1);
opt.value = cnt;
var dupe = opt.cloneNode(true);
s0.add(opt);
s1.add(dupe);
cnt++;
}
}
input,
select,
option {
font: inherit
}
input {
width: 4ch;
}
<form id='ui'>
<fieldset>
<legend>Enter a number in the first form field</legend>
<input id='qty0' name='qty0' type='number' min='0' max='30'>
<select id="sel0" name="sel0"></select>
<select id="sel1" name="sel1"></select>
</fieldset>
</form>
Reference
HTMLFormControlsCollection
Trying to get my second select element's options to populate from an array based on the value of the first select element. I can't seem to understand why it only populates the items from the array of the first select element. I know the appendChild is causing the items to keep tacking on at the need, but I've tried to clear the variables, but it seems the option elements that were created stay.
Any help would be great, thanks!
<select id="makeSelect" onChange="modelAppend()">
<option value="merc">Mercedes</option>
<option value="audi">Audi</option>
<option value="bmw">BMW</option>
</select>
<select id="modelSelect">
</select>
<script>
var audiModels = ["TT", "R8", "A4", "A6"]; //audimodels
var mercModels = ["C230", "B28", "LTX",]; //mercmodels
var bmwModels = ["328", "355", "458i",]; //bmwmodels
var selectedMake = document.getElementById("makeSelect"); //grabs the make select
var selectedModel = document.getElementById("modelSelect"); //grabs the model select
var appendedModel = window[selectedMake.value + "Models"]; // appends "Models" to selectedMake.value and converts string into variable
function modelAppend() {
for (var i = 0; i < appendedModel.length; i ++) { // counts items in model array
var models = appendedModel[i]; // // sets "models" to count of model array
var modelOptions = document.createElement("option"); //create the <option> tag
modelOptions.textContent = models; // assigns text to option
modelOptions.value = models; // assigns value to option
selectedModel.appendChild(modelOptions); //appeneds option tag with text and value to "modelSelect" element
}
}
</script>
This line is fishy:
var appendedModel = window[selectedMake.value + "Models"];
You need to get the element when the value has changed, not on page load. Then you need to remove the options on change too, or you will get a very long list if the user selects multiple times. Use an object to store the arrays, that makes it much easier to access them later. Also better use an event listener instead of inline js (though that's not the main problem here).
Try below code:
let models = {
audiModels: ["TT", "R8", "A4", "A6"],
mercModels: ["C230", "B28", "LTX"],
bmwModels: ["328", "355", "458i"]
}
document.getElementById('makeSelect').addEventListener('change', e => {
let el = e.target;
let val = el.value + 'Models';
let appendTo = document.getElementById('modelSelect');
Array.from(appendTo.getElementsByTagName('option')).forEach(c => appendTo.removeChild(c));
if (!models[val] || !Array.isArray(models[val])) {
appendTo.style.display = 'none';
return;
}
models[val].forEach(m => {
let opt = document.createElement('option');
opt.textContent = opt.value = m;
appendTo.appendChild(opt);
});
appendTo.style.display = '';
});
<select id="makeSelect">
<option value=""></option>
<option value="merc">Mercedes</option>
<option value="audi">Audi</option>
<option value="bmw">BMW</option>
</select>
<select id="modelSelect" style="display:none">
</select>
I am trying to make an HTML Select control display a different set of strings when clicked (or opened) than what is displayed after an item is selected. For example, when opened I want to see "one", two", "three" displayed as choices. But if the user selects two, I want "2" to be displayed as the selected item. My onclick handler reloads the Select options list with the long version of the strings and the onchange handler repopulates the control with the short strings and then re-selects the selected item. This works in Firefox, but not in IE, Safari nor Chrome. It's been almost 10 years since I last had the pleasure of coding in JavaScript. Any help would be appreciated. Here's my code:
var selectedIndex = -1;
function onChanged() {
//once selected, replace verbose with terse forms
var myList = document.getElementById("myList");
selectedIndex = myList.selectedIndex;
var optionArray = ["One|1", "Two|2", "Three|3"];
myList.options.length = 0;
for (var option in optionArray) {
var pair = optionArray[option].split("|");
var newOption = document.createElement("option");
newOption.value = pair[1];
newOption.innerHTML = pair[1];
myList.options.add(newOption);
}
myList.selectedIndex = selectedIndex;
}
function onClicked() {
var myList = document.getElementById("myList");
var optionArray = ["1|One", "2|Two", "3|Three"];
myList.options.length = 0;
for (var option in optionArray) {
var pair = optionArray[option].split("|");
var newOption = document.createElement("option");
newOption.value = pair[1];
newOption.innerHTML = pair[1];
myList.options.add(newOption);
}
if (selectedIndex > -1)
myList.selectedIndex = selectedIndex;
}
<select id="myList" onchange="onChanged()" onclick="onClicked()">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
An alternate approach would be to have each option store the full version of the text, and only change the displayed text of the selected item to the abbreviated version upon selection.
(function() {
var valueMap = {
"1": "One (1)",
"2": "Two (2)",
"11": "Eleven (11)",
"ITAR": "International Traffic in Arms Regulation (ITAR)",
"ACA": "Affordable Care Act (ACA)",
"FUBAR": "Fluffed Up Beyond All Recognition (FUBAR)"
};
var myList = document.getElementById("myList");
for (var prop in valueMap) { // populate the dropdown from our object
var opt = document.createElement("option");
opt.value = prop;
opt.text = valueMap[prop];
myList.add(opt);
}
myList.selectedIndex = -1; // nothing selected by default
myList.addEventListener("change", function() {
this.options[this.selectedIndex].text = this.options[this.selectedIndex].value;
this.blur();
});
myList.addEventListener("mousedown", function() {
if (this.selectedIndex > -1) {
var newValue = valueMap[this.options[this.selectedIndex].value];
if (this.options[this.selectedIndex].text !== newValue) {
this.options[this.selectedIndex].text = newValue;
}
}
});
})();
<select id="myList" style="width:6em"></select>
This gets you most of the way there, but still has the annoying problem that #hopkins-matt alluded to; namely that if the user opens the drop-down list and either selects the already selected item or moves off of the list without selecting anything, the selection will retain the long version of the text.
The other downside to this approach is that you need to specify the select element's width to keep it from expanding to the maximum length of its hidden option elements.
It's a timing issue.
Change:
<select id="myList" onchange="onChanged()" onclick="onClicked()">
to:
<select id="myList" onchange="onChanged()" onmousedown="onClicked()">
If the user opens the list and moves off the list without clicking, the list will not revert to original unless you call onChanged() on onmouseout as well.
<select id="myList" onchange="onChanged()" onmousedown="onClicked()" onmouseout="onChanged()">
Update: To achieve the best cross browser (onfocus is required for FF, but breaks IE) support without browser sniffing us this combination:
<select id="myList" onchange="onChanged()" onblur="onChanged()" onfocus="onClicked()" onmousedown="onClicked()">
This will also correct the second selection of the same event, but only after the user clicks away from the element.
Update:
Solved... I think.
I rewrote the function you were using to change the options. IE was not firing onchange due to you removing all the option elements and adding new option elements. Which was causing IE to not be able to reference if the user had changed the selection index. The function now just modifies the value and innerHTML of the current option elements. I am using browser sniffing to eliminate the onmouseout call for FF. FireFox was calling onmouseout if you moved the cursor to the dropdown menu. This does cause a side effect in FF. If the user selects the same option in FF, the options do not return to the original state until the onblur is fired.
Demo: http://jsfiddle.net/hopkins_matt/3m1syk6c/
JS:
function changeOptions() {
var selectedIndex = -1;
var click = 0;
var myList = document.getElementById("myList");
var optionArray = ["One|1", "Two|2", "Three|3"];
var fireFox = /Firefox/i.test(navigator.userAgent);
console.log(fireFox);
if (fireFox == false) {
myList.onmouseout=function(){changeList(false)};
}
myList.onblur=function(){changeList(false)};
myList.onchange=function(){changeList(false)};
myList.onmousedown=function(){changeList(true)};
function changeList(listOpen) {
var isListOpen = listOpen;
if (isListOpen == true) {
for (i = 0; i < myList.options.length; i++) {
var pair = optionArray[i].split("|");
myList.options[i].value = pair[0];
myList.options[i].innerHTML = pair[0];
}
}
if (isListOpen == false) {
for (i = 0; i < myList.options.length; i++) {
var pair = optionArray[i].split("|");
myList.options[i].value = pair[1];
myList.options[i].innerHTML = pair[1];
}
}
}
}
changeOptions();
HTML:
<select id="myList">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
How can I cancel a select menu choice using a confirm dialog?
The idea is that when a user changes a select menu, they're prompted to confirm their choice. if they choose "cancel", the select menu goes back to its previously selected value. If they choose "OK", the select menu behaves as expected.
Here is the code I'm working on:
HTML:
<select class="selector" name="selector1">
<option value="yes">Yes</option>
<option value="no" selected="">No</option>
<option value="maybe">Maybe</option>
</select>
<select class="selector" name="selector2" >
<option value="yes">Yes</option>
<option value="no" selected="">No</option>
<option value="maybe">Maybe</option>
</select>
JavaScript
var selects = document.querySelectorAll('.selector');
var lastSelected = {};
for (i = 0; i < selects.length; i++) {
var select = selects[i];
lastSelected[select.name] = select.options[select.selectedIndex];
select.addEventListener('change', function (e) {
lastSelected = select.options[select.selectedIndex];
if (confirm("Are you want to choose this?") == true) {
return;
} else {
select.value = lastSelected[select.name];
}
});
}
I'm not entirely sure why this isn't working, any help is much appreciated.
Here is the fiddle I'm working on http://jsfiddle.net/je36eu78/2/
n.b I'd like to do this in native JavaScript (no jquery)
you overwrite lastSelected here:
lastSelected = select.options[select.selectedIndex];
you must also store the new value when the user hits OK
Another approach(stores the previous value as a property of the select)
var selects = document.querySelectorAll('.selector');
for (i = 0; i < selects.length; i++) {
var select = selects[i];
select.defaultValue=select.value;
select.addEventListener('change', function (e) {
if (confirm("Are you want to choose this?") == true) {
this.defaultValue=this.value;
} else {
this.value=this.defaultValue;
}
});
}
Try the snippet below
var select = document.querySelectorAll('.selector');
for (i = 0; i < select.length; i++) {
select[i]['last'] = select[i].options[select[i].selectedIndex].value;
(function(i){
select[i].onchange = function(){
if(confirm("Sure?")){
select[i]['last'] = this.value;
}else{
this.value = select[i]['last'];
}
};
})(i);
}
Working jsBin
I have a small bit of a delema.
I have the following static select box below, however, the database will compare its cell value to that of the select box and select it.
My question to you is how can I design a function that would dynamically add a new select option (at the end of the existing list) if it already isn't in the list?
This doesn't seem to be working for me?
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function test() {
//document.getElementById('name').innerHTML = "test"
document.getElementById('name').text = "test"
}
</script>
</head>
<body>
<select id="name">
<option value=""></option>
<option value="John">John</option>
<option value="Patrick">Patrick</option>
<option value="Jean">Jean</option>
<option value="Jackie">Jackie</option>
<option value="Stephanie">Stephanie</option>
<option value="Nicole">Nicole</option>
<option value="Lucie">Lucie</option>
</select>
<input id="btn1" type="button" value="testme" onclick="test()" />
</body>
</html>
You'll have to check each one:
function test() {
var checkWhat = 'test'; // value to check for
var options = document.getElementById('name').getElementsByTagName('option'),
exists = false;
for (var i=options.length; i--;) {
if ( options[i].value == checkWhat ) {
exists = true; // an option with that value already exists
break;
}
}
if (!exists) {
var option = document.createElement('option');
option.value = 'test';
option.innerHTML = 'test';
document.getElementById('name').appendChild(option);
}
}
You could create a function which loops through all the options in the select element and if the option value doesn't already exist, append it to the select tag.
var addOption = function(value){
var select = document.getElementById('name'), // get the select tag
options = select.getElementsByTagName('option'), // get all option tags within that select
alreadyExists = false;
for(var i = 0, l = options.length; i < l; i++){ // loop through the existing options
if(options[i].value == value) // check if value already exists
alreadyExists = true;
}
if(!alreadyExists){ // if value doesn't already exist
var newOption = document.createElement('option');// create a new option and add it to the select
newOption.value = value;
newOption.innerHTML = value;
select.appendChild(newOption);
}
};
Demo: http://jsfiddle.net/2TZ45/