I am working on a form with multiple drop down options.
I stripped everything down to three questions in the form below, to illustrate my issue.
I have tried this code (and a few variations):
function update_variables(el, standard_val, var_list) {
standard_val.value = var_list[el.getElementsByTagName('option')[el.selectedIndex].value];
}
var select2 = document.getElementById('think_question'),
hidden_answer = document.getElementsByName('thought_goes_here')[0];
var why_options = {
'yes': '',
'no': 'Well, you tried.'
};
select2.addEventListener('change', function() {
update_variables(select2, hidden_answer, why_options);
});
var sel_group_control = document.getElementById('follower_question');
var sel_free_will = document.getElementById('think_question');
sel_group_control.addEventListener('change', answer_bypass);
function answer_bypass() {
var user_choice = sel_group_control.value;
if (user_choice === 'no') {
sel_free_will.selectedIndex = 2;
sel_free_will.style.backgroundColor = "#D3D3D3";
sel_free_will.disabled = true;
}
}
<h2>Life Decisions</h2>
<form>
Be exactly like everone else?
<select id='follower_question'>
<option disabled selected value> -- select an option -- </option>
<option>yes</option>
<option>no</option>
</select>
<br> Think for yourself?
<select id='think_question'>
<option disabled selected value> -- select an option -- </option>
<option>yes</option>
<option>no</option>
</select>
<br> Original thought:<input name="thought_goes_here" size="50" value="" id="your_thoughts">
</form>
If question 2 is set to 'no' then the answer to question 3 is known and filled in with a response. If question 1 is 'no' then question 2 should be set to 'no' and read-only. I expected question 3 to be updated automatically too when choosing 'no' in response to question 1 but that function seems to be ignored.
You need to register an event to trigger the second select change.
Like so:
function answer_bypass() {
var user_choice = sel_group_control.value;
if (user_choice === 'no') {
sel_free_will.selectedIndex = 2;
sel_free_will.style.backgroundColor = "#D3D3D3";
sel_free_will.disabled = true;
// Create a new 'change' event
var event = new Event('change');
// Dispatch it.
select2.dispatchEvent(event);
}
}
Related
I am trying to write a script for changing the hidden input value according to selected options.
I have hindi data stored on a variable and I need to pick this hindi data according to english data selected in select feild. The select options are working fine so far, but I am unable to fectch the related hindi data.
var stateObject = {
"Bihar": {
"Begusarai": ["Bachhwara", "Bakhari", "Balia", "Barauni", "Begusarai", "Bhagwanpur", "Birpur", "Cheriya Bariyarpur", "Chhorahi", "Dandari", "Garhpura", "Khudabandpur", "Mansoorchak", "Matihani", "Nawkothi", "Sahebpur Kamal", "Samho Akha Kurha", "Teghra"],
},
}
var stateObjectHindi = {
"बिहार": {
"बेगूसराय": ["बछवारा", "बखरी", "बलिया", "बरौनी", "बेगुसराय", "भगवानपुर", "बीरपुर", "चेरिया बरियारपुर", "छौराही", "डंडारी", "गढ़पुरा", "खोदाबंदपुर", "मंसूरचक", "मटिहानी", "नावकोठी", "साहेबपुर कमाल", "साम्हो अखा कुरहा", "तेघरा"],
},
}
window.onload = function() {
var stateList = document.getElementById("stateList"),
stateListHindi = document.getElementById("stateListHindi"),
districtList = document.getElementById("districtList"),
districtListHindi = document.getElementById("districtListHindi"),
blockList = document.getElementById("blockList"),
blockListHindi = document.getElementById("blockListHindi");
for (var country in stateObject) {
stateList.options[stateList.options.length] = new Option(country, country);
}
stateList.onchange = function() {
districtList.length = 1; // remove all options bar first
blockList.length = 1; // remove all options bar first
if (this.selectedIndex < 1) return; // done
for (var state in stateObject[this.value]) {
districtList.options[districtList.options.length] = new Option(state, state);
}
}
stateList.onchange(); // reset in case page is reloaded
districtList.onchange = function() {
blockList.length = 1; // remove all options bar first
if (this.selectedIndex < 1) return; // done
var district = stateObject[stateList.value][this.value];
for (var i = 0; i < district.length; i++) {
blockList.options[blockList.options.length] = new Option(district[i], district[i]);
stateListHindi.value = this.value;
}
}
}
<select name="state" id="stateList">
<option value="" selected="selected">Select State</option>
</select>
<select name="district" id="districtList">
<option value="" selected="selected">Select District</option>
</select>
<select name="block" id="blockList">
<option value="" selected="selected">Select Block</option>
</select>
<br/> State in Hindi: <input type="hidden" class="stateListHindi" id="stateListHindi" name="stateListHindi" value="" /><br/> District in Hindi: <input type="hidden" class="districtListHindi" id="districtListHindi" name="districtListHindi" value="" /><br/>Block in Hindi: <input type="hidden" class="blockListHindi" id="blockListHindi" name="blockListHindi" value="" /><br/>
JSFiddle Demo
Your data structure is perhaps not too well-suited for what you want here. You need to find the corresponding property in both objects, for the first two levels, by their position - so you will have to extract the keys first, and use indexOf to locate them.
So for the state first of all, that would be
var selectedKeyIndex = Object.keys(stateObject).indexOf(this.value);
stateListHindi.value = Object.keys(stateObjectHindi)[selectedKeyIndex];
Extract the keys from the English object, and find the index of the property matching the current selection in there. Then use that index, to extract the corresponding property name from the Hindi object.
Now, for the district, you'll have to do the same thing, but for one more level:
var selectedKeyIndex = Object.keys(stateObject[stateList.value]).indexOf(this.value);
districtListHindi.value = Object.keys(stateObjectHindi[stateListHindi.value])[selectedKeyIndex];
And then for the Blocks, which are in an array, you can select directly by index,
var selectedKeyIndex = stateObject[stateList.value][districtList.value].indexOf(this.value);
blockListHindi.value = stateObjectHindi[stateListHindi.value][districtListHindi.value][selectedKeyIndex];
All of it put together here: https://jsfiddle.net/6g5ad4cz/.
(I made the hidden fields into normal text fields, so that the result can be visually checked straight away.)
I'm using a <datalist>
<datalist id="items"></datalist>
And using AJAX to populate the list
function callServer (input) {
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
//return the JSON object
console.log(xmlhttp.responseText);
var arr = JSON.parse(xmlhttp.responseText);
var parentDiv = document.getElementById('items');
parentDiv.innerHTML = "";
//fill the options in the document
for(var x = 0; x < arr.length; x++) {
var option = document.createElement('option');
option.value = arr[x][0];
option.innerHTML = arr[x][1];
//add each autocomplete option to the 'list'
option.addEventListener("click", function() {
console.log("Test");
});
parentDiv.appendChild(option);
};
}
}
xmlhttp.open("GET", "incl/search.php?value="+input.value, true);
xmlhttp.send();
}
However I can't get it to perform an action when I click on a selection in the datalist, for example if I type in "Ref F" and the item "Ref flowers" comes up, if I click on it I need to execute an event.
How can I do this?
option.addEventListener("click", function() {
option.addEventListener("onclick", function() {
option.addEventListener("change", function() {
Sorry for digging up this question, but I've had a similar problem and have a solution, that should work for you, too.
function onInput() {
var val = document.getElementById("input").value;
var opts = document.getElementById('dlist').childNodes;
for (var i = 0; i < opts.length; i++) {
if (opts[i].value === val) {
// An item was selected from the list!
// yourCallbackHere()
alert(opts[i].value);
break;
}
}
}
<input type='text' oninput='onInput()' id='input' list='dlist' />
<datalist id='dlist'>
<option value='Value1'>Text1</option>
<option value='Value2'>Text2</option>
</datalist>
This solution is derived from Stephan Mullers solution. It should work with a dynamically populated datalist as well.
Unfortunaltely there is no way to tell whether the user clicked on an item from the datalist or selected it by pressing the tab-key or typed the whole string by hand.
Due to the lack of events available for <datalist> elements, there is no way to a selection from the suggestions other than watching the input's events (change, input, etc). Also see my answer here: Determine if an element was selected from HTML 5 datalist by pressing enter key
To check if a selection was picked from the list, you should compare each change to the available options. This means the event will also fire when a user enters an exact value manually, there is no way to stop this.
document.querySelector('input[list="items"]').addEventListener('input', onInput);
function onInput(e) {
var input = e.target,
val = input.value;
list = input.getAttribute('list'),
options = document.getElementById(list).childNodes;
for(var i = 0; i < options.length; i++) {
if(options[i].innerText === val) {
// An item was selected from the list!
// yourCallbackHere()
alert('item selected: ' + val);
break;
}
}
}
<input list="items" type="text" />
<datalist id="items">
<option>item 1</option>
<option>item 2</option>
</datalist>
Use keydown
Contrary to the other answers, it is possible to detect whether an option was typed or selected from the list.
Both typing and <datalist> clicks trigger the input's keydown listener, but only keyboard events have a key property. So if a keydown is triggered having no key property, you know it was a click from the list
Demo:
const opts = document.getElementById('dlist').childNodes;
const dinput = document.getElementById('dinput');
let eventSource = null;
let value = '';
dinput.addEventListener('keydown', (e) => {
eventSource = e.key ? 'input' : 'list';
});
dinput.addEventListener('input', (e) => {
value = e.target.value;
if (eventSource === 'list') {
alert('CLICKED! ' + value);
}
});
<input type="text" id="dinput" list="dlist" />
<datalist id="dlist">
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
</datalist>
Notice it doesn't alert if the value being clicked is already in the box, but that's probably desirable. (This could also be added by using an extra tracking variable that will be toggled in the keydown listener.)
Datalist actually don't have an event (not all browsers), but you can detect if a datalist option is selected in this way:
<input type="text" list="datalist" />
<datalist id="datalist">
<option value="item 1" />
<option value="item 2" />
</datalist>
window.addEventListener('input', function (e) {
let event = e.inputType ? 'input' : 'option selected'
console.log(event);
}, false);
demo
Shob's answer is the only one which can detect when an option gets clicked as well as not trigger if an intermediary written text matches an option (e.g.: if someone types "Text1" to see the options "Text11", "Text12", etc. it would not trigger even if "Text1" is inside the datalist).
The original answer however did not seem to work on newer versions of Firefox as the keydown event does not trigger on clicks so I adapted it.
let keypress = false;
document.getElementById("dinput").addEventListener("keydown", (e) => {
if(e.key) {
keypress = true;
}
});
document.getElementById("dinput").addEventListener('input', (e) => {
let value = e.target.value;
if (keypress === false) {
// Clicked on option!
console.debug("Value: " + value);
}
keypress = false;
});
<input type="text" id="dinput" list="dlist" />
<datalist id="dlist">
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
</datalist>
Datalist don't support click listener and OnInput is very costly, checking everytime all the list if anything change.
What I did was using:
document.querySelector('#inputName').addEventListener("focusout", onInput);
FocusOut will be triggered everytime a client click the input text and than click anywhere else. If they clicked the text, than clicked somewhere else I assume they put the value they wanted.
To check if the value is valid you do the same as the input:
function onInput(e) {
var val = document.querySelector('#inputName').value;
options = document.getElementById('datalist').childNodes;
for(var i = 0; i < options.length; i++) {
if(options[i].innerText === val) {
console.log(val);
break;
}
}
}
<input type="text" id="buscar" list="lalista"/>
<datalist id="lalista">
<option value="valor1">texto1</option>
<option value="valor2">texto2</option>
<option value="valor3">texto3</option>
</datalist>
//0 if event raised from datalist; 1 from keyboard
let idTimeFuekey = 0;
buscar.oninput = function(){
if(buscar.value && idTimeFuekey==0) {
alert('Chévere! vino desde la lista')
}
};
buscar.onkeydown = function(event){
if(event.key){ //<-- for modern & non IE browser, more direct solution
window.clearInterval(idTimeFuekey);
idTimeFuekey = window.setInterval(function(){ //onkeydown --> idTimeFuekey++ (non 0)
window.clearInterval(idTimeFuekey);
idTimeFuekey = 0 //after 500ms onkeydown --> 0 (could work 500, 50, .. 1)
}, 500)
}
}
Well, at least in Firefox the onselect event works on the input tag
<input type="text" id="dinput" list="dlist" onselect="alert(this.value)"/>
<datalist id="dlist">
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
</datalist>
After having this problem and not finding a suitable solution, I gave it a shot.
What I did was look at the "inputType" of the given input event on top of the event toggle variable from above, like so:
eventSource = false;
const selector = document.getElementById("yourElementID");
selector.addEventListener('input', function(evt) {
if(!eventSource) {
if(evt.inputType === "insertReplacementText") {
console.log(selector.value);
}
}
});
selector.addEventListener('keydown', function(evt) {
eventSource = !evt.key;
});
This works if you want to allow the user to search a field but only hit a specific function/event on selection from the datalist itself. Hope it helps!
Edit: Forgot to mention this was done through Firefox and has not been tested on other browsers.
I have a select with loads of options. (Code below shortened for sake of example).
I want it to set the value of the input textfield "hoh" to "10" when you click/select all dropdown options, except one, that should set it to 50.
I imagined something like this would work, but its not. What am I doing wrong here?
<select>
<option onselect="document.getElementById('hoh').value = '50'">Hey</option>
<option onselect="document.getElementById('hoh').value = '10'">Ho</option>
<option onselect="document.getElementById('hoh').value = '10'">Lo</option>
....
</select>
<input type="text" id="hoh" value="10">
Something like this should work:
<script>
function myFunc(val) {
if (val == '50') {
document.getElementById('hoh').value = val;
} else {
document.getElementById('hoh').value = '10';
}
}
</script>
<select onchange="myFunc(this.value)">
<option value="1">one</option>
<option value="2">two</option>
<option value="50">fifty</option>
</select>
http://jsfiddle.net/isherwood/LH57d/3
The onselect event refers to selecting (or highlighting) text. To trigger an action when a dropbox selection changes, use the onchange event trigger for the <select> element.
E.g. Since you didn't already set the value attribute of your option tags.
<select id="myselect" onchange="myFunction()">
<option value="50">Hey</option>
<option value="10">Ho</option>
<option value="10">Lo</option>
....
</select>
and somewhere inside of a <script> tag (presumably in your HTML header) you define your javascript function.
<script type="text/javascript>
function myFunction() {
var dropbox = document.getElementById('myselect');
document.getElementById('hoh').value = dropbox[dropbox.selectedIndex].value;
}
</script>
I'm not sure it's wise to repeat the same value among different options in a droplist, but you could expand on this to implement the result other ways, such as if the sole option which will have value 50 is in a certain position, you could compare the selectedIndex to that position.
you could add an onchange event trigger to the select, and use the value of an option to show in the textbox
see http://jsfiddle.net/Icepickle/5g5pg/ here
<select onchange="setValue(this, 'hoh')">
<option>-- select --</option>
<option value="10">Test</option>
<option value="50">Test 2</option>
</select>
<input type="text" id="hoh" />
with function setValue as
function setValue(source, target) {
var tg = document.getElementById(target);
if (!tg) {
alert('No target element found');
return;
}
if (source.selectedIndex <= 0) {
tg.value = '';
return;
}
var opt = source.options[source.selectedIndex];
tg.value = opt.value;
}
Try this code
var inp = document.getElementById('hoh');
sel.onchange = function(){
var v = this.value;
if( v !== '50'){
v = '10';
}
inp.value = v;
};
Javascript and I will never be best friends.
I try to set a checkbox to checked by changing the elements from a dropdownlist.
This is the snippet
<select name="change_status_to" id="sel">
<option>....</option>
<option>....</option>
</select>
<input type="checkbox" name="do_status_change" value="on">
How could I use Javascript with the onchange-event to set the checkbox to the state checked?
You can set its .checked property:
document.getElementById("do_status_change").checked = true;
document.getElementById("do_status_change").checked = false;
However, you need to set an id; the name attribute will not suffice.
> Example <
Here is an example of why you should be friends with javascript.
JSFiddle - http://jsfiddle.net/juc7Q/1/
HTML
You're feeling toward Javascript
<select name="friends" id="friends">
<option value="love">I love JS</option>
<option value="weird">JS is weird</option>
<option value="misunderstood">Are we speaking the same language?</option>
</select>
<button id="selectWeird">Keep JS Weird</button>
<div>
<input type="checkbox" id="we_friends"> - Friends?
</div>
JavaScript
//Select this using js
var list = document.getElementById('friends');
var cb = document.getElementById('we_friends');
//Add event when change happens
list.onchange = function () {
var value = list.value;
if(value == 'love') {
alert('I knew you would come around');
cb.setAttribute('checked', '');
} else if(value == 'weird') {
alert('And I like being weird :-)!!');
cb.removeAttribute('checked');
} else {
alert('And you think I understand you?');
cb.removeAttribute('checked');
}
}
//Change to 'Weird' when I click on it
var btn = document.getElementById('selectWeird');
btn.onclick = function () {
list.options.selectedIndex = 1;
}
I have an HTML page in which I have 2 selects.
<select id="field" name="field" onchange="checkValidOption();">
<option />
<option value="Plugin ID">Plugin ID</option>
<option value="Name">Name</option>
</select>
<select id="operator" name="operator" onchange="checkValidOption();">
<option />
<option value="EQUALS">EQUALS</option>
<option value="CONTAINS">CONTAINS</option>
<option value="NOT CONTAINS">NOT CONTAINS</option>
<option value="REGEX">REGEX</option>
</select>
What I'd like to happen is that checkValidOption() could make it so that if "Plugin ID" is selected in field that the only option is EQUALS (and it's selected) and otherwise all the other options are available. Any idea on how to approach this?
I tried changing the innerHTML of the operator select in JS:
document.getElementById("operator").innerHTML =
"<option value='EQUALS'>EQUALS</option>";
However this results in an empty select (this would also include manually setting the many options for going back to having all the ones listed above).
I can't think of another solution, any help would be greatly appreciated.
Try this:
Demo here
var field = document.getElementById('field');
var operator = document.getElementById('operator');
field.onchange = function () { fieldcheck(); }
operator.onchange = function () { fieldcheck(); }
fieldcheck();
function fieldcheck() {
if (field.value == 'Plugin ID') {
for (i = 0; i < operator.options.length; ++i) {
if (operator.options[i].value != 'EQUALS') {
operator.options[i].disabled = true;
}
};
operator.value = 'EQUALS';
} else {
for (i = 0; i < operator.options.length; ++i) {
operator.options[i].disabled = false;
};
}
}
To manipulate options when Plugin ID was selected:
function checkValidOption(){
var x=document.getElementById("field");
var y=document.getElementById("operator");
if (x.options[1].selected === true){
document.getElementById("operator").options[1].selected = true;
for(var i=0; i<y.length; i++){
if (i !== 1){
//disabling the other options
document.getElementById("operator").options[i].disabled = true;
}
}
}
else{
for(var i=0; i<y.length; i++){
//enabling the other options
document.getElementById("operator").options[i].disabled = false;
}
}
}
Here's a link to fiddle
A select field doesn't use the innerHTML method, you need to use value.
document.getElementById("operator").value = "...";
heres a jquery solution.
every time the first select changes, it produces new options from an array for the 2nd select. issue here is i had to change the option values of the first select to 0 and 1 to select which value in the array, you can manipulate those later if you are storing this info somewhere
http://jsfiddle.net/2TZJh/
$(document).ready(function() {
$("#field").change(function() {
var val = $(this).val();
$("#operator").html(options[val]);
});
var options = [
'<option value="EQUALS">EQUALS</option>',
'<option></option><option value="EQUALS">EQUALS</option><option value="CONTAINS">CONTAINS</option> <option value="NOT CONTAINS">NOT CONTAINS</option> <option value="REGEX">REGEX</option>'
];
});