Javascript to hide select box elements not working in IE - javascript

Hey, not sure if I'm going about this the right way. I have two different select boxed. What needs to happen is when a certain item in box 1 is selected, certain items in box 2 are hidden. What I have works fine in FF but not in IE....thoughts?
<div>
<label class="form_label">Apparel</label>
<select id="Choices" size="1" style="clear: right;" onchange"changeThis();">
<option value="select">Pick Your Product</option>
<option value="1">choice 1</option>
<option value="2">choice 2/option>
<option value="3">choice 3</option>
</select>
</div>
<div>
<label class="form_label">Size</label>
<select id="Sizes" size="1" style="clear: right;">
<option value="select">Choose Your Size</option>
<option value="SC">Small Child</option>
<option value="IC">Intermediate Child</option>
<option value="MC">Medium Child</option>
</select>
</div>
...
function changeThing(choice)
{
var item = document.getElementById("Choices");
var size = document.getElementById("Sizes");
var selitem = item.options[item.selectedIndex].value;
if(selitem == '2546')
{
for(i=0; i<2; i++)
{
size[i].style.display = 'none';
//alert(size[i]);
}
}

Try using this instead:
http://www.w3schools.com/CSS/pr_class_visibility.asp
It would come out as:
size[i].style.visibility='hidden';
EDIT
Oh, welcome to StackOverflow!

I had the same problem some days ago. IE does not allow the using of visible:hidden or display:none for option element.
You can solve this problem storing the options of select1 in a variable. This variable will have all possible values, so when the value of select1 was changed you can remove all values of select2 and then get the options you need from variable to put into select2.
To summarize:
Store all possible values in a variable
When select1 was changed remove all options of select2
Filter the options(get these values from varible of step1) you need and put into select2

You cannot display:none remove will completely remove it, if you want the user not to choose it use disabled. you could do something like this
function changeThing()
{
var item = document.getElementById("Choices");
var size = document.getElementById("Sizes");
var selitem = item.options[item.selectedIndex].value;
if(selitem == '3')
{
for(i=1; i<2; i++) // filter logic here
{
size[i].disabled = true; //false - to reset
//alert(size[i]);
}
}
size.selectedIndex = 0; // reset the selection so a disabled item may not be selected. }

It depends on how you are firing off the event that calls the changeThing() function. Not sure about IE9, but IE8 and on back has issues with the onChange event. It basically avoids it in IE. You'll have to use onClick instead.
If you are using jQuery to fire the event, the onchange event should work correctly in all browser (even IE). Not sure how other Javascript libraries do it.

You need to remove this options completely to make it work in IE.
size.remove(i);
So you need to store your options in array and load it back when needed.

Related

When registering both onchange and onclick on a select, the click event is triggered twice

Goal: Have a select whose option have nested structure when user clicks on the select, but when user selects an option the option should be displayed "normally" (ie with no leading spaces).
Attempted solution using JS and Jquery: My JS is far from sophisticated so I apologize in advance :)
I attempted to use .on("change") and .on("click") to change the selected option value (by calling .trim() since I achieve the "nested" structure with ). I'm also storing the original value of the selected option because I want to revert the select menu to its original structure in case the user selects another option.
The problem: The function registered for .on("click") is called twice, thus the select value immediately resets itself to its original value.
I suspect there is a much, much easier solution using CSS. I will be happy to accept an answer that will suggest such solution.
JSFiddle: https://jsfiddle.net/dv6kky43/9/
<form>
<select id="select">
<option value=""></option>
<option value="a"> a</option>
<option value="b"> b</option>
</select>
</form>
<textarea id="output"/>
var orig;
var output = $("#output");
output.val("");
function onDeviceSelection(event){
output.val(output.val() + "\nonDeviceSelection");
var select = event.target;
orig = select.selectedOptions[0].text;
select.selectedOptions[0].text = select.selectedOptions[0].text.trim()
}
function resetDeviceSelectionText(event) {
output.val(output.val() + "\nresetDeviceSelectionText");
var select = event.target;
if (orig !== undefined){
select.selectedOptions[0].text = orig;
}
}
$("#select").on("change", onDeviceSelection);
$("#select").on("click", resetDeviceSelectionText);
If you are already using jQuery, why not utilize data function to store the original value. This way you will also be able to specify different nest levels.
(function($){
$(document).on('change', 'select', function(event) {
$(this).find('option').each(function(index, element){
var $option = $(element);
// Storing original value in html5 friendly custom attribute.
if(!$option.data('originalValue')) {
$option.data('originalValue', $option.text());
}
if($option.is(':selected')) {
$option.html($option.data('originalValue').trim());
} else {
$option.html($option.data('originalValue'));
}
})
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<select id="select">
<option value=""></option>
<option value="a"> a</option>
<option value="b"> b</option>
</select>
</form>
Once caveat I see is, the selected option will appear trimmed on the list as well, if dropdown is opened after a previous selection has been made:
Will it still work for you?
Instead of keeping the state of the selected element i would simply go over all options and add the space if that option is not selected:
function onDeviceSelection(event){
// Update textarea
output.val(output.val() + "\nonDeviceSelection");
// Higlight the selected
const {options, selectedIndex} = event.target;
for(let i = 0; i < options.length; i++)
options[i].innerHTML = (i === selectedIndex ? "":" ") + options[i].text.trim();
}
$("#select").on("change", onDeviceSelection);
Note that you need to use innerHTML to set the whitespace...

How to I modify the code to apply it for three drop-downs? (Jquery)

I have a jquery code which changes according to the previously selected value of drop-down.
I use it when I have two drop-downs and it works flawlessly.
Now the problem is that I am working with 3 drop-downs and I am unable to modify the code according to 3 drop-downs (reason my being new to jquery).
This is the code:
Jquery:
jQuery(function(){
var $cat = $('select[name=coursename]'),
$items = $('select[name=semno]');
$cat.change(function(){
var $this = $(this).find(':selected'),
rel = $this.attr('rel'),
$set = $items.find('option.' + rel);
if ($set.size() < 0) {
$items.hide();
return;
}
$items.show().find('option').hide();
$set.show().first().prop('selected', true);});});
I used two drop-downs namely, coursename and semno, with this code and it works perfectly fine.
Now I want to add another dropdown, subnm which comes after semno.
So what I exactly want is that when a person makes a particular selection in coursename the relevant items should appear in semno and among those relevant items, when a value is selected, the items are listed on subnm accordingly.
I have used rel and class in the option element.
HTML Code
Course:
<select name="coursename" id="coursename">
<option value="xyz" rel="xyz">XYZ</option>
<option value="abc" rel="abc">ABC</option>
</select>
Semester:
<select name="semno" id="sem">
<option value="one" class="xyz">I</option>
<option value="two" class="xyz">II</option>
<option value="three" class="abc">III</option>
</select>
Subject:
<select name="subnm" id="subnm">
<option value="p">p</option>
<option value="q">q</option>
<option value="r">r</option>
</select>
I guess I will need a rel option on the semno drop-down and then class on the subnm drop-down in accordance to the semno rel.
Forgive me if I am not 100% comprehensible. I am new to this site and I really need help.
Thank You in advance!
Hope this is what you want. I have used the same function for change event for the second select menu.
$items.change(function(){
var $this = $(this).find(':selected'),
rel = $this.attr('rel'),
$set = $third.find('option.' + rel);
if ($set.size() < 0) {
$third.hide();
return;
}
$third.show().find('option').hide();
$set.show().first().prop('selected', true);
});
Also I have triggered the change event for second select in change event handler of first select.
$items.trigger("change");
Please refer this fiddle

make a select dependent with js

I would like to do a select option dependent of another select, i saw there's a way using array with fixed values, but my array is reloaded every time we add a new form field on the form. I would like something like when i select op1, then it just show op1 options on second select.
<select id="id1" name="optionshere">
<option relone="op1">opt one</option>
<option relone="op2">opt two</option>
</select>
<select id="id2" name="resulthere">
<option relone="op1">ans 1 op1</option>
<option relone="op1">ans 2 op2</option>
<option relone="op2">ans 1 op2</option>
</select>
Any idea?
thanks all
Here's a method without jQuery:
When you select an option in the first selectbox, it will hide everything that doesn't match its relone.
var id1 = document.getElementById("id1");
var id2 = document.getElementById("id2");
id1.addEventListener("change", change);
function change() {
for (var i = 0; i < id2.options.length; i++)
id2.options[i].style.display = id2.options[i].getAttribute("relone") == id1.options[id1.selectedIndex].getAttribute("relone") ? "block" : "none";
id2.value = "";
}
change();
<select id="id1" name="optionshere">
<option relone="op1">opt one</option>
<option relone="op2">opt two</option>
</select>
<select id="id2" name="resulthere">
<option relone="op1">ans 1 op1</option>
<option relone="op1">ans 2 op1</option>
<option relone="op2">ans 1 op2</option>
</select>
If Jquery is an option you may go with something like this:
<script type='text/javascript'>
$(function() {
$('#id1').change(function() {
var x = $(this).val();
$('option[relone!=x]').each(function() {
$(this).hide();
});
$('option[relone=x]').each(function() {
$(this).show();
});
});
});
</script>
Then to expand:
There really are many ways in which you can solve this predicament, depending on how variable your pool of answers is going to be.
If you're only interested in using vanilla javascript then let's start with the basics. You're going to want to look into the "onchange" event for your html, so as such:
<select onchange="myFunction()">
Coming right out of the w3schools website, on the Html onchange event attribute:
The onchange attribute fires the moment when the value of the element
is changed.
This will allow you to make a decision based on this element's value. Then inside your js may branch out from here:
You may use Ajax and pass to it that value as a get variable to obtain those options from a separate file.
You may get all options from the second div through a combination of .getElementbyId("id2") and .getElementsByTagName("option") then check for their individual "relone" attribute inside an each loop, and hide those that don't match, and show those that do.
Really, it's all up to what you want to do from there, but I personally would just go for the Jquery approach

Getting a Select Value after appending

This is for javascript and jquery.
I have in my body...
<select id="option1_select" name="courseCodeSelectName">
<option></option>
<option>Word1</option>
<option>Word2</option>
</select>
<script>
$("select").change(function () {
functionLoadOpt2() }).trigger("change" );
</script>
<select id="option2_select" name="courseNumSelectName">
<option></option>
</select>
<button onclick="changePage()">Load Textbook Page!</button>
As we see above, the web page has 2 select boxes and a button. Depending on what you select in the first select box loads what is in the second one, using the functionLoadOpt2 function locating higher up in my code.
if (result == "Word1") {
$("#option2_select").append('<option>Letter1</option>');
...
There is more but it follows the same code different values.
Result is the following, above the if statement(just a row up),
var result = (document.getElementById('option1_select').value);
now on the button click, the function changePage() runs,
and all I want is ...
var result = (document.getElementById('option1_select').value);
var result2= (document.getElementById('option2_select').value);
Assume they selected and option for both. Result2 doesnt work. I'd imagine because I'm appending it but how would I work around this. So that when I click changePage() I get the selected value of option1_select and option2_select.
functionLoadOpt2:
function functionLoadOpt2(){
var opt1Val = (document.getElementById('option1_select').value);
$("#option2_select").find('option').remove().end().append('<option></option>');
if (opt1Val == "Word1") {
$("#option2_select").append('<option>Letter1</option>');
$("#option2_select").append('<option>Letter2</option>');
$("#option2_select").append('<option>Letter3</option>');
$("#option2_select").append('<option>Letter4</option>');
$("#option2_select").append('<option>Letter5</option>');
}else if (opt1Val == "Word2") {
$("#option2_select").append('<option>Letter3</option>');//they have similar ones in some cases
$("#option2_select").append('<option>Letter6</option>');
$("#option2_select").append('<option>Letter7</option>');
$("#option2_select").append('<option>Letter8</option>');
$("#option2_select").append('<option>Letter9</option>');
$("#option2_select").append('<option>Letter10</option>');
$("#option2_select").append('<option>Letter11</option>');
$("#option2_select").append('<option>Letter12</option>');
$("#option2_select").append('<option>Letter13</option>');
$("#option2_select").append('<option>Letter14</option>');
$("#option2_select").append('<option>Letter15</option>');
$("#option2_select").append('<option>Letter16</option>');
$("#option2_select").append('<option>Letter17</option>');
//this works
}
}
use jQuery to get and set the value of <select> with .val()
Both your select elements have the same id, fix it the it should be fine
<select id="option1_select" name="courseCodeSelectName">
<option></option>
<option>Word1</option>
<option>Word2</option>
</select>
<select id="option2_select" name="courseNumSelectName">
<option></option>
</select>
<button onclick="changePage()">Load Textbook Page!</button>
Demo: Fiddle
Note: You can improve the script a lot by using proper jQuery constructs, like this

Removing and adding options from a group of select menus with jQuery

This is a little more complicated than the title makes it out to be, but here are the essential business rules:
There are three select menus on the
page, each filled with the same
options and values.
There will always be three select
menus.
There will always be the same number
of options/values in each select
menu.
Selecting a question in any of the
menus will remove that question as an option from
the other two menus.
Re-selecting a different question
from any of the menus will bring
back the question that was
previously removed from the other
two menus at the index it was at previously.
I've tried this a few different ways, and the thing that is killing me is number 5. I know that it wouldn't be inserted at the exact index because some questions may have already been removed, which would reorder the index. It basically needs an insertBefore or insertAfter that puts it in the same "slot".
Even if you don't post any code, some thoughts on how you might approach this would be extremely helpful. The select menus and jQuery look something like this, but I've had numerous tries at it in different variations:
jQuery:
$(function() {
$(".questions").change(function() {
var t = this;
var s = $(t).find(":selected");
// Remove, but no "insert previously selected" yet...
$(".questions").each(function(i) {
if (t != this) {
$(this).find("option[value=" + s.val() + "]").remove();
}
});
});
});
HTML:
<select name="select1" class="questions">
<option value="1">Please select an option...</option>
<option value="2">What is your favorite color?</option>
<option value="3">What is your pet's name?</option>
<option value="4">How old are you?</option>
</select>
<select name="select2" class="questions">
<option value="1">Please select an option...</option>
<option value="2">What is your favorite color?</option>
<option value="3">What is your pet's name?</option>
<option value="4">How old are you?</option>
</select>
<select name="select3" class="questions">
<option value="1">Please select an option...</option>
<option value="2">What is your favorite color?</option>
<option value="3">What is your pet's name?</option>
<option value="4">How old are you?</option>
</select>
Don't remove the elements, hide them. With removing, you are causing you a lot more problems than necessary. This works for me:
$(function() {
$('select.questions').change(function() {
var hidden = [];
// Get the values that should be hidden
$('select.questions').each(function() {
var val = $(this).find('option:selected').val();
if(val > 0) {
hidden.push($(this).find('option:selected').val());
}
});
// Show all options...
$('select.questions option').show().removeAttr('disabled');
// ...and hide those that should be invisible
for(var i in hidden) {
// Note the not(':selected'); we don't want to hide the option from where
// it's active. The hidden option should also be disabled to prevent it
// from submitting accidentally (just in case).
$('select.questions option[value='+hidden[i]+']')
.not(':selected')
.hide()
.attr('disabled', 'disabled');
}
});
});
I made a small change to your HTML also, I denoted an option that should always be visible with a value of 0. So the valid options go from 1 to 3.
Here's a working example, tell me if I misunderstood you:
http://www.ulmanen.fi/stuff/selecthide.php
I was working on a solution of this recently and modified this code to remove rather than disable/hide. For my solution it was required (I'm also using UI to style the select elements). Here's how I did it:
// Copy an existing select element
var cloned = $('select[name="select1"]').clone();
// Each time someone changes a select
$('select.questions').live('change',function() {
// Get the current values, then reset the selects to their original state
var hidden[];
$('select.questions').each(function() {
hidden.push($(this).val());
$(this).html(cloned.html());
});
// Look through the selects
for (var i in hidden) {
$('select.questions').each(function() {
// If this is not the current select
if ((parseInt(i)) != $(this).parent().index()) {
// Remove the ones that were selected elsewhere
$(this).find('option[value="'+hidden[i]+'"]').not('option[value="0"]').remove();
} else {
// Otherwise, just select the right one
$(this).find('option[value="'+hidden[i]+'"]').not('option[value="0"]').attr('selected','selected');
}
});
}
});

Categories

Resources