Whitespace on option value - javascript

I am trying to do a select menu thats the code:
<select>
<option value='Hello World'></option>
</select>
In later when I try to get this options value he returns 'Hello'. not 'Hello World'
and I create options like that:
function getTeams(tournamentTeams){
tournamentTeams.forEach(element => {
players += "<option value="+element[0]+">"+element[0]+"</option>";
console.log(players + "\n")
})
return players;}
tournamentTeams is array :
tournamentTeams = [
['Team A', 'player1', 'player2'],
['Team B', 'player1', 'player2']
]
and thats the options that getTeams() function made:
<option value='Team' A>Team A</option>
<option value='Team' B>Team B</option>
How can I fix that?

You don't quote your value at "<option value="+element[0]+">" so it becomes <option value=Team A> which will will result in <option value='Team' A>.
To avoid such problem you should not create your HTML by concatenating strings, use the DOM API instead.
By using setAttribute and innerText you done need to take care about escaping and the quotes, as this is done by the DOM API for you.
function addTeamsToSelect(tournamentTeams, selectElement) {
tournamentTeams.forEach(element => {
// create the option element
let option = document.createElement('option')
// set its value
option.setAttribute('value', element[0])
// set the text that is displayed
option.innerText = element[0]
// append the option element to the select element
selectElement.appendChild(option)
})
}
let tournamentTeams = [
['Team A', 'player1', 'player2'],
['Team B', 'player1', 'player2']
]
addTeamsToSelect(tournamentTeams, document.querySelector('select'))
<select></select>
If you want want to stay with your approach that returns the option elements you can use a document fragment (document.createDocumentFragment):
function getTeams(tournamentTeams, selectElement) {
let fragment = document.createDocumentFragment()
tournamentTeams.forEach(element => {
// create the option element
let option = document.createElement('option')
// set its value
option.setAttribute('value', element[0])
// set the text that is displayed
option.innerText = element[0]
// append the option element to the document fragment
fragment.appendChild(option)
})
return fragment
}
let tournamentTeams = [
['Team A', 'player1', 'player2'],
['Team B', 'player1', 'player2']
]
document.querySelector('select').appendChild(getTeams(tournamentTeams))
<select></select>

Related

Get the value of Span class inside a Select Option

I know it might seem a duplicate but its not.
Here is what my select looks like:
<select id="avpMy4Y7E4cH_-iIRmmAK6-2GsEOu6Sjr-0-0">
<option value="1Ltr [ <span class=money>Rs.1,495.00</span> ]">...</option> 
</select>
I want to get the value of the class "money" only.
Here is what I tried:
var val = $('#avpMy4Y7E4cH_-iIRmmAK6-2GsEOu6Sjr-0-0 option:selected').find('.money').val();
But this return empty value.
How can I get that specific value?
I'm a bit unclear as to what you want returned, but this will return the textContent of the span as well as the classNames. Span elements don't have value properties.
You can use DOMParser to convert the selected option text to an HTML document, select the elements from the document matching that selector, and extract the textContent
window.addEventListener("DOMContentLoaded", () => {
const opt = document
.querySelector('#avpMy4Y7E4cH_-iIRmmAK6-2GsEOu6Sjr-0-0 option:checked');
const parser = new DOMParser();
//convert the value of the selected option to html document
const htmldoc = parser.parseFromString(opt.value, "text/html");
//select all elements with className money from html document
const moneys = htmldoc.querySelectorAll('.money');
//iterate each and display it's textContent
moneys.forEach((a) => {
console.log(a.textContent);
//if you want to read the classNames
a.classList.forEach((b) => {
console.log(b);
});
});
});
<select id="avpMy4Y7E4cH_-iIRmmAK6-2GsEOu6Sjr-0-0">
<option selected value="1Ltr [ <span class=money>Rs.1,495.00</span> ]"></option>
</select>

How to populate select options from an array based on a select value?

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>

JavaScript dropdown list with objects

I would like to create a dropdown list with JavaScript that contains actual objects instead of just a single value.
For example, I have an object with two members, ID and Name. On the dropdown list, I would like the name to be displayed for each object. However, if someone selects a name, I would like to easily be able to get the associated ID.
Not sure of how to do this without two separate containers, one for what's in the DDL and one that has corresponding indices for IDs.
If i understand you correctly, select already supports this. Option text and option value are two separate things
<select>
<option value="1">Volvo</option>
<option value="2">Saab</option>
<option value="3">Opel</option>
<option value="4">Audi</option>
</select>
Check this fiddle
https://jsfiddle.net/pg92tqka/
When you get the value of the selected option you can get stored id and by this value access the actual object (id can be index in array, ...)
html
<select id="selector"></select>
JS
var data = [
{ name :'david', id:1 },
{ name :'daniel', id:2 }
]
data.forEach(function(item){
var option = document.createElement('option');
option.value = item.id;
option.innerHTML = item.name;
selector.appendChild(option)
})'
selector.onchange = function(){
alert(this.value);
}
see the following fiddle : https://jsfiddle.net/1jcrxoy9/
There's a few ways of doing this, however this is my favorite currently:
JavaScript
var data = [{
id : 1,
name : 'Foo'
}, {
id : 2,
name : 'Bar'
}, {
id : 3,
name : 'Baz'
}];
var select = document.createElement('select');
select.innerHTML = data.map(function(v){
return '<option value="' + v.id + '">' + v.name + '</option>';
}).join('');
Then you can append the select somewhere in your body with all the options.
Use the value attribute for your ID.
var ddl_items = [{ ID: 1, Text: "One" }, { ID: 2, Text: "Two" }];
for (var i = 0; i < ddl_items.length; i++ ) {
$("#ddl").append("<option value='" + ddl_items[i].ID + "'>" + ddl_items[i].Text + "</option>");
}
<select id="ddl">
</select>
Fiddle: https://jsfiddle.net/dap3x83v/

access nested object's keys using variable object name

Not 100% sure my question's title accurately states my question, I apologize in advance. Please correct me if my terminology is off here.
Basically, I have a select box. When the user makes a selection I want to create a new select box setting its options using the values stored in an object:
jsFiddle showing my attempt
My Code:
HTML :
<SELECT id="mainIssueType" style="color:#888"size=0>
<OPTION style="color:#888" selected> Issue Type </option>
<OPTION style="color:#888" value="Hotel"> Hotel </option>
<OPTION style="color:#888" value="Flights"> Flights </option>
</SELECT>
SCRIPT :
var tree = {
"Hotel": [{val: "Htl1", text: 'Cancel'},
{val: "Htl2", text: 'Modify'},
{val: "Htl3", text: 'Research'},
{val: "Htl4", text: 'Complaint'}],
"Flights": [{val: "Flt1", text: 'Void'},
{val: "Flt1", text: 'Cancel'},
{val: "Flt1", text: 'Change Flight'},
{val: "Flt1", text: 'Schedule Change'},
{val: "Flt1", text: 'Name Change'}, ]
};
$(function() {
$('#mainIssueType').change(function() {
//get current selected option
var selectVal = $('#mainIssueType :selected').val();
//create a new select box and add to body
var sel = $('<select>').appendTo('body');
//give the new element an id matching
//the selected value from the previous element
sel.attr('id', selectVal);
//set the select box's options using the values
//from the "selectVal" object within the "tree" object
$(tree.selectVal).each(function() {
//tree.selectVal seems to be the problem
sel.append($("<option>").attr('value', this.val).text(this.text));
});
});
});
The tree.selectVal in $(tree.selectVal).each seems to be the problem here. I guess this is not the same as saying tree.Hotel directly as I can get it to work using tree.Hotel as shown here
How can I access the object in tree whose name matches my selectVal variable?
Use $(tree[selectVal]) instead of $(tree.selectVal)
$(function(){
$('#mainIssueType').change(function() {
//get current selected option
var selectVal = $('#mainIssueType :selected').val();
//create a new select box and add to body
var sel = $('<select>').appendTo('body');
//give the new element an id matching
//the selected value from the previous element
sel.attr('id',selectVal);
//set the select box's options using the values
//from the "selectVal" object within the "tree" object
$(tree[selectVal]).each(function() {
//_____^_____________________
//tree.selectVal seems to be the problem
sel.append($("<option>").attr('value',this.val).text(this.text));
});
});
});
FIDDLE DEMO

set option "selected" attribute from dynamic created option

I have a dynamically created select option using a javascript function. the select object is
<select name="country" id="country">
</select>
when the js function is executed, the "country" object is
<select name="country" id="country">
<option value="AF">Afghanistan</option>
<option value="AL">Albania</option>
...
<option value="ID">Indonesia</option>
...
<option value="ZW">Zimbabwe</option>
</select>
and displaying "Indonesia" as default selected option. note : there is no selected="selected" attribute in that option.
then I need to set selected="selected" attribute to "Indonesia", and I use this
var country = document.getElementById("country");
country.options[country.options.selectedIndex].setAttribute("selected", "selected");
using firebug, I can see the "Indonesia" option is like this
<option value="ID" selected="selected">Indonesia</option>
but it fails in IE (tested in IE 8).
and then I have tried using jQuery
$( function() {
$("#country option:selected").attr("selected", "selected");
});
it fails both in FFX and IE.
I need the "Indonesia" option to have selected="selected" attribute so when I click reset button, it will select "Indonesia" again.
changing the js function to dynamically create "country" options is not an option. the solution must work both in FFX and IE.
thank you
You're overthinking it:
var country = document.getElementById("country");
country.options[country.options.selectedIndex].selected = true;
Good question. You will need to modify the HTML itself rather than rely on DOM properties.
var opt = $("option[val=ID]"),
html = $("<div>").append(opt.clone()).html();
html = html.replace(/\>/, ' selected="selected">');
opt.replaceWith(html);
The code grabs the option element for Indonesia, clones it and puts it into a new div (not in the document) to retrieve the full HTML string: <option value="ID">Indonesia</option>.
It then does a string replace to add the attribute selected="selected" as a string, before replacing the original option with this new one.
I tested it on IE7. See it with the reset button working properly here: http://jsfiddle.net/XmW49/
Instead of modifying the HTML itself, you should just set the value you want from the relative option element:
$(function() {
$("#country").val("ID");
});
In this case "ID" is the value of the option "Indonesia"
So many wrong answers!
To specify the value that a form field should revert to upon resetting the form, use the following properties:
Checkbox or radio button: defaultChecked
Any other <input> control: defaultValue
Option in a drop down list: defaultSelected
So, to specify the currently selected option as the default:
var country = document.getElementById("country");
country.options[country.selectedIndex].defaultSelected = true;
It may be a good idea to set the defaultSelected value for every option, in case one had previously been set:
var country = document.getElementById("country");
for (var i = 0; i < country.options.length; i++) {
country.options[i].defaultSelected = i == country.selectedIndex;
}
Now, when the form is reset, the selected option will be the one you specified.
// get the OPTION we want selected
var $option = $('#SelectList').children('option[value="'+ id +'"]');
// and now set the option we want selected
$option.attr('selected', true);​​
What you want to do is set the selectedIndex attribute of the select box.
country.options.selectedIndex = index_of_indonesia;
Changing the 'selected' attribute will generally not work in IE. If you really want the behavior you're describing, I suggest you write a custom javascript reset function to reset all the other values in the form to their default.
This works in FF, IE9
var x = document.getElementById("country").children[2];
x.setAttribute("selected", "selected");
Make option defaultSelected
HTMLOptionElement.defaultSelected = true; // JS
$('selector').prop({defaultSelected: true}); // jQuery
HTMLOptionElement MDN
If the SELECT element is already added to the document (statically or dynamically), to set an option to Attribute-selected and to make it survive a HTMLFormElement.reset() - defaultSelected is used:
const EL_country = document.querySelector('#country');
EL_country.value = 'ID'; // Set SELECT value to 'ID' ("Indonesia")
EL_country.options[EL_country.selectedIndex].defaultSelected = true; // Add Attribute selected to Option Element
document.forms[0].reset(); // "Indonesia" is still selected
<form>
<select name="country" id="country">
<option value="AF">Afghanistan</option>
<option value="AL">Albania</option>
<option value="HR">Croatia</option>
<option value="ID">Indonesia</option>
<option value="ZW">Zimbabwe</option>
</select>
</form>
The above will also work if you build the options dynamically, and than (only afterwards) you want to set one option to be defaultSelected.
const countries = {
AF: 'Afghanistan',
AL: 'Albania',
HR: 'Croatia',
ID: 'Indonesia',
ZW: 'Zimbabwe',
};
const EL_country = document.querySelector('#country');
// (Bad example. Ideally use .createDocumentFragment() and .appendChild() methods)
EL_country.innerHTML = Object.keys(countries).reduce((str, key) => str += `<option value="${key}">${countries[key]}</option>`, '');
EL_country.value = 'ID';
EL_country.options[EL_country.selectedIndex].defaultSelected = true;
document.forms[0].reset(); // "Indonesia" is still selected
<form>
<select name="country" id="country"></select>
</form>
Make option defaultSelected while dynamically creating options
To make an option selected while populating the SELECT Element, use the Option() constructor MDN
var optionElementReference = new Option(text, value, defaultSelected, selected);
const countries = {
AF: 'Afghanistan',
AL: 'Albania',
HR: 'Croatia',
ID: 'Indonesia', // <<< make this one defaultSelected
ZW: 'Zimbabwe',
};
const EL_country = document.querySelector('#country');
const DF_options = document.createDocumentFragment();
Object.keys(countries).forEach(key => {
const isIndonesia = key === 'ID'; // Boolean
DF_options.appendChild(new Option(countries[key], key, isIndonesia, isIndonesia))
});
EL_country.appendChild(DF_options);
document.forms[0].reset(); // "Indonesia" is still selected
<form>
<select name="country" id="country"></select>
</form>
In the demo above Document.createDocumentFragment is used to prevent rendering elements inside the DOM in a loop. Instead, the fragment (containing all the Options) is appended to the Select only once.
SELECT.value vs. OPTION.setAttribute vs. OPTION.selected vs. OPTION.defaultSelected
Although some (older) browsers interpret the OPTION's selected attribute as a "string" state, the WHATWG HTML Specifications html.spec.whatwg.org state that it should represent a Boolean selectedness
The selectedness of an option element is a boolean state, initially false. Except where otherwise specified, when the element is created, its selectedness must be set to true if the element has a selected attribute.
html.spec.whatwg.org - Option selectedness
one can correctly deduce that just the name selected in <option value="foo" selected> is enough to set a truthy state.
Comparison test of the different methods
const EL_select = document.querySelector('#country');
const TPL_options = `
<option value="AF">Afghanistan</option>
<option value="AL">Albania</option>
<option value="HR">Croatia</option>
<option value="ID">Indonesia</option>
<option value="ZW">Zimbabwe</option>
`;
// https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/MutationObserver
const mutationCB = (mutationsList, observer) => {
mutationsList.forEach(mu => {
const EL = mu.target;
if (mu.type === 'attributes') {
return console.log(`* Attribute ${mu.attributeName} Mutation. ${EL.value}(${EL.text})`);
}
});
};
// (PREPARE SOME TEST FUNCTIONS)
const testOptionsSelectedByProperty = () => {
const test = 'OPTION with Property selected:';
try {
const EL = [...EL_select.options].find(opt => opt.selected);
console.log(`${test} ${EL.value}(${EL.text}) PropSelectedValue: ${EL.selected}`);
} catch (e) {
console.log(`${test} NOT FOUND!`);
}
}
const testOptionsSelectedByAttribute = () => {
const test = 'OPTION with Attribute selected:'
try {
const EL = [...EL_select.options].find(opt => opt.hasAttribute('selected'));
console.log(`${test} ${EL.value}(${EL.text}) AttrSelectedValue: ${EL.getAttribute('selected')}`);
} catch (e) {
console.log(`${test} NOT FOUND!`);
}
}
const testSelect = () => {
console.log(`SELECT value:${EL_select.value} selectedIndex:${EL_select.selectedIndex}`);
}
const formReset = () => {
EL_select.value = '';
EL_select.innerHTML = TPL_options;
// Attach MutationObserver to every Option to track if Attribute will change
[...EL_select.options].forEach(EL_option => {
const observer = new MutationObserver(mutationCB);
observer.observe(EL_option, {attributes: true});
});
}
// -----------
// LET'S TEST!
console.log('\n1. Set SELECT value');
formReset();
EL_select.value = 'AL'; // Constatation: MutationObserver did NOT triggered!!!!
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();
console.log('\n2. Set HTMLElement.setAttribute()');
formReset();
EL_select.options[2].setAttribute('selected', true); // MutationObserver triggers
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();
console.log('\n3. Set HTMLOptionElement.defaultSelected');
formReset();
EL_select.options[3].defaultSelected = true; // MutationObserver triggers
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();
console.log('\n4. Set SELECT value and HTMLOptionElement.defaultSelected');
formReset();
EL_select.value = 'ZW'
EL_select.options[EL_select.selectedIndex].defaultSelected = true; // MutationObserver triggers
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();
/* END */
console.log('\n*. Getting MutationObservers out from call-stack...');
<form>
<select name="country" id="country"></select>
</form>
Although the test 2. using .setAttribute() seems at first the best solution since both the Element Property and Attribute are unison, it can lead to confusion, specially because .setAttribute expects two parameters:
EL_select.options[1].setAttribute('selected', false);
// <option value="AL" selected="false"> // But still selected!
will actually make the option selected
Should one use .removeAttribute() or perhaps .setAttribute('selected', ???) to another value? Or should one read the state by using .getAttribute('selected') or by using .hasAttribute('selected')?
Instead test 3. (and 4.) using defaultSelected gives the expected results:
Attribute selected as a named Selectedness state.
Property selected on the Element Object, with a Boolean value.
select = document.getElementById('selectId');
var opt = document.createElement('option');
opt.value = 'value';
opt.innerHTML = 'name';
opt.selected = true;
select.appendChild(opt);
// Get <select> object
var sel = $('country');
// Loop through and look for value match, then break
for(i=0;i<sel.length;i++) { if(sel.value=="ID") { break; } }
// Select index
sel.options.selectedIndex = i;
Begitu loh.
This should work.
$("#country [value='ID']").attr("selected","selected");
If you have function calls bound to the element just follow it with something like
$("#country").change();
You could search all the option values until it finds the correct one.
var defaultVal = "Country";
$("#select").find("option").each(function () {
if ($(this).val() == defaultVal) {
$(this).prop("selected", "selected");
}
});
Vanilla JS
Use this for Vanilla Javascript, keeping in mind that you can feed the example "numbers" array with any data from a fetch function (for example).
The initial HTML code:
<label for="the_selection">
<select name="the_selection" id="the_selection_id">
<!-- Empty Selection -->
</select>
</label>
Some values select tag:
const selectionList = document.getElementById('the_selection_id');
const numbers = ['1','3','5'];
numbers.forEach(number => {
const someOption = document.createElement('option');
someOption.setAttribute('value', number);
someOption.innerText = number;
if (number == '3') someOption.defaultSelected = true;
selectionList.appendChild(someOption);
})
You'll get:
<label for="the_selection">
<select name="the_selection" id="the_selection_id">
<!-- Empty Selection -->
<option value="1">1</option>
<option value="3" selected>3</option>
<option value="5">5</option>
</select>
</label>
You can solve this on ES6 like this:
var defaultValue = "ID";
[...document.getElementById('country').options].map(e => e.selected = (e.value == defaultValue));
I haven't test in other browsers but in Chrome works just fine.
...document.getElementById('country').options using the spread operator you cast options as an array.
.map allows you to apply a function to each element of your array.
e represents each <option> element of your object so you can access its attributes like .select and .value as getter and setter.
Because you .select receives a boolean option you want to assign when its value is equal to your default value.
To set the input option at run time try setting the 'checked' value. (even if it isn't a checkbox)
elem.checked=true;
Where elem is a reference to the option to be selected.
So for the above issue:
var country = document.getElementById("country");
country.options[country.options.selectedIndex].checked=true;
This works for me, even when the options are not wrapped in a .
If all of the tags share the same name, they should uncheck when the new one is checked.
Realize this is an old question, but with the newer version of JQuery you can now do the following:
$("option[val=ID]").prop("selected",true);
This accomplishes the same thing as Box9's selected answer in one line.
The ideas on this page were helpful, yet as ever my scenario was different. So, in modal bootstrap / express node js / aws beanstalk, this worked for me:
var modal = $(this);
modal.find(".modal-body select#cJourney").val(vcJourney).attr("selected","selected");
Where my select ID = "cJourney" and the drop down value was stored in variable: vcJourney
I was trying something like this using the $(...).val() function, but the function did not exist. It turns out that you can manually set the value the same way you do it for an <input>:
// Set value to Indonesia ("ID"):
$('#country').value = 'ID'
...and it get's automatically updated in the select. Works on Firefox at least; you might want to try it out in the others.
To set value in JavaScript using set attribute , for selected option tag
var newvalue = 10;
var x = document.getElementById("optionid").selectedIndex;
document.getElementById("optionid")[x].setAttribute('value', newvalue);

Categories