Javascript Change html of next select on change of another select - javascript

I have been trying for days to get this to work but to no avail! I have two dropdown lists. Depending on the selection of the first defines the content of the second. However I am having trouble selecting the second dropdown.
Here is the simple dropdowns.
<div id="advanced-search" class="advanced-search">
<select name="Attribute" id="Attribute" class="advanced-attribute" onChange="AttributeChange()"></select>
<select name="Operator" id="Operator" class="advanced-operator">
<option value="">Select Attribute First</option>
</select>
</div>
Then using an on change event I want to define the content:
function AttributeChange() {
var SearchAttribute = $(this).find(':selected').attr('type');
if (SearchAttribute = 'varchar') {
$(this).next().find('.advanced-operator').html('<option value="">Select Operator</option><option value="=">Is Equal To</option><option value="!=">Is Not Equal To</option><option value="LIKE">Contains</option><option value="NOT LIKE">Does Not Contain</option><option value="Start">Starts With</option><option value="End">Ends With</option><option value="IS NULL">Is Empty</option><option value="IS NOT NULL">Is Not Empty</option>');
} else {
$('.advanced-attribute').siblings('.advanced-operator').html('<option value="">Select Attribute First</option>');
}
}
NOTE: The options for the first select are pulled from the Database via PHP.
Ignore the IF statement as that is already working and a attribute I have defined in the option tags.
What I cannot do is select the second dropdown universally by class (as there will be multiple select's with the same class) and I wont know the ID, as it is automatically generated.
So I have been trying to get the next element, but i cant seem to get it to work.

Problem with you implementation are
this doesn't refers to element which you think
= is assignment operator where as == is equality.
.advanced-operator is immediate sibling so use $(this).next('.advanced-operator')
Inline events handler have been considered bad practice, and leads to potential issues as in your scenario.
You should use .on() to bind event handler.
$('.advanced-attribute').on('change', function() {
var searchAttribute = $(this).find(':selected').attr('type');
var nextSelector = $(this).next('.advanced-operator');
//You need to use ==
if (searchAttribute == 'varchar') {
nextSelector.html('<option value="">Select Operator</option><option value="=">Is Equal To</option><option value="!=">Is Not Equal To</option><option value="LIKE">Contains</option><option value="NOT LIKE">Does Not Contain</option><option value="Start">Starts With</option><option value="End">Ends With</option><option value="IS NULL">Is Empty</option><option value="IS NOT NULL">Is Not Empty</option>');
} else {
nextSelector.html('<option value="">Select Attribute First</option>');
}
})
$(function() {
$('.advanced-attribute').on('change', function() {
var searchAttribute = $(this).find(':selected').attr('type');
var nextSelector = $(this).next('.advanced-operator');
//You need to use ==
if (searchAttribute == 'varchar') {
nextSelector.html('<option value="">Select Operator</option><option value="=">Is Equal To</option><option value="!=">Is Not Equal To</option><option value="LIKE">Contains</option><option value="NOT LIKE">Does Not Contain</option><option value="Start">Starts With</option><option value="End">Ends With</option><option value="IS NULL">Is Empty</option><option value="IS NOT NULL">Is Not Empty</option>');
} else {
nextSelector.html('<option value="">Select Attribute First</option>');
}
}).change();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="advanced-search" class="advanced-search">
<select name="Attribute" id="Attribute" class="advanced-attribute">
<option type="char">1</option>
<option type="varchar">2</option>
</select>
<select name="Operator" id="Operator" class="advanced-operator">
<option value="">Select Attribute First</option>
</select>
</div>

Related

JavaScript - Dropdown value dependent

I have two dropdown right now. I want to when the user selects "NO" the other automatically selects "YES" and vice versa.
I'm assuming I use JS here to make this occur, but not sure where to start. Below is my dropdown html code. If someone could help me get started, it would be helpful.
Code:
<div class="cmicrophone" id="cmicrophone">Currently:
<select id="cmicrophone" name="cmicrophone">
<option value=" " selected = "selected"> </option>
<option value="on">ON</option>
<option value="off">OFF</option>
</select>
</div>
<div class="microphone" id="microphone">Microphone:
<select id="microphone" name = "microphone">
<option value=" " selected="selected"> </option>
<option value="on" >ON</option>
<option value="off">OFF</option>
</select>
</div
You can assign a same class to each select element and bind change event listener.
$('.elem').on('change', function() {
if ($(this).val() == 'on') {
$('.elem').not(this).val('off');
} else {
$('.elem').not(this).val('on');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cmicrophone" id="cmicrophone">Currently:
<select id="cmicrophone" class='elem' name="cmicrophone">
<option value="" selected = "selected"></option>
<option value="on">ON</option>
<option value="off">OFF</option>
</select>
</div>
<div class="microphone" id="microphone">Microphone:
<select id="microphone" class='elem' name="microphone">
<option value="" selected = "selected"></option>
<option value="on">ON</option>
<option value="off">OFF</option>
</select>
</div>
A good starting point might be listening for changes on one select, and when the change happens, selecting the other <select> and setting the right value
Here's a vanilla JS solution (no jquery required).
The idea here is to:
select both <select> elements and save them into variables to refer to later using document.querySelector
add input event listeners on both elements that call a function to handle the event
then use inside the function selectElement.selectedIndex to check the selected index of one element and use that to set the value of the other.
// select the `<select>` elements
const cmicrophone = document.querySelector('#cmicrophone');
const microphone = document.querySelector('#microphone');
// define function to handler the events
function inputHandler(thisSelect, otherSelect) {
if (thisSelect.selectedIndex == 1) {
otherSelect.selectedIndex = 2;
} else if (thisSelect.selectedIndex == 2) {
otherSelect.selectedIndex = 1;
} else {
thisSelect.selectedIndex = 0;
otherSelect.selectedIndex = 0;
}
}
// add event listeners that will 'fire' when the input of the <select> changes
cmicrophone.addEventListener('input', event => {
inputHandler(cmicrophone, microphone);
});
microphone.addEventListener('input', event => {
inputHandler(microphone, cmicrophone);
});
<div>Currently:
<select id="cmicrophone" name="cmicrophone">
<option value=" " selected = "selected"> </option>
<option value="on">ON</option>
<option value="off">OFF</option>
</select>
</div>
<div>Microphone:
<select id="microphone" name="microphone">
<option value=" " selected="selected"> </option>
<option value="on" >ON</option>
<option value="off">OFF</option>
</select>
</div>
One more thing to add: You assigned the same value to multiple ids. You should only assign one unique id per element.

How to change a border color of html select tag if value is empty or 0

I have 4 select tag with class name select2 assigned to it. I want to make the border turn to red if there's no selected options or has an value equal to empty or 0. I've tried to add class using jquery but it makes all select.select2 border turns red.
Style
<style>
.errorType {
border-color: #F00 !important;
}
</style>
HTML
<select name="category" class="form-control select2" id="category" onChange="search_Operator(this.value)">
<option value="0"> Select Operator Category</option>
<option value="1">one</option> <option value="2"> two</option>
</select>
<select name="operatorName" class="form-control select2" id="operatorName" onChange="">
<option value="0"> Select operator Name</option>
<option value="1">one</option>
<option value="2"> two</option>
</select>
<select name="regionName" class="form-control select2" id="regionName">
<option value="0"> Select region Name</option>
<option value="1">one</option>
<option value="2"> two</option>
</select>
<select name="type" class="form-control select2" id="type">
<option value="0"> Select type </option>
</select>
JQUERY
$(function () {
$(".select2").select2();
});
$(".select2-selection").addClass('errorType');
Any idea?
Thanks in advance.
I've attached a function to the click event of the submit button, in order to check the value of every select element on the page:
$(function () {
$('.form-control-select2').select2();
$('#submit_btn').on('click', function(){
var submit_form = true;
$(".form-control-select2").each(function(){
var selected_value = $(this).val();
if (selected_value==0 || selected_value=='') {
$(this).next().find('.select2-selection').addClass('errorType');
submit_form = false;
} else {
$(this).next().find('.select2-selection').removeClass('errorType');
}
});
return submit_form;
});
});
Fiddle here: https://jsfiddle.net/64a41thz/21/.
Also, if you want to remove the red border when valid selection is made, add the following code:
$('.form-control-select2').on('change', function(){
if ($(this).val()!=0 && $(this).val()!='') {
$(this).next().find('.select2-selection').removeClass('errorType');
}
});
Fiddle here: https://jsfiddle.net/64a41thz/24/.
This does the trick. You just need to replace #yourButton with the actual ID you use.
$(document).on("click", "#yourButton", function() {
$(".select2").each(function(index, element) {
$(element).removeClass("errorType");
if ($(element).val() === "0") {
$(element).addClass("errorType");
}
});
});
Put your select tag inside a form with an id="submit" as shown
<form class="" action="" method="post" id="submit">
and add a button below the 4 select tags with this attribute
onclick="return submit_form('form#submit')"
the button should be like this,
<button type="button" class="btn btn-default" onclick="return submit_form('form#submit')">Submit</button>
In your jquery
function submit_form (form_id) {
$(form_id).find('select[name]').each(function (index, node) {
if (node.value == 0) {
var id = "select#" + node.id;
$(id).addClass('errorType');
}
});
}
This will search select tag with name as attribute, if found, it will get the value of the name and check of its empty or not. If found empty it will add new class that turns that select tag into a red border.
Hope this will help

Set class from <select> if selected option contains ID='answer' in HTML/JavaScript (JQuery)

I am completely new to HTML and JQuery, and I can't figure out how I can set a class for my select element if the currently selected option has an ID="answer". I want to do this to check if the multiple choice question is correct.
If this is impossible to do this in JQuery, JavaScript would also be fine. I just want to prevent making a DataBase query and thought that JQuery would be the best route to take.
This is the current html section that I have:
<form id="ansForm" class="testClass1">
<div id="QuestionForm" name="QuestionForm">
<label>Question 1: This is a question </label>
<select class="form-control select-class">
<option value="1" class="ans-class" id="answer">Answer1</option>
<option value="2" class="ans-class">Answer2</option>
<option value="3" class="ans-class">Answer3</option>
<option value="4" class="ans-class">Answer4</option>
</select>
<label>Question 2: This is another question </label>
<select class="form-control select-class">
<option value="1" class="ans-class">Another Answer</option>
<option value="2" class="ans-class">Just some text</option>
<option value="3" class="ans-class" id="answer">Test</option>
<option value="4" class="ans-class">Test2</option>
</select>
</div>
<button type="button" class="btn btn-primary"
onclick="checkAnswers()">Check</button>
</form>
When I click the button it runs a Javascript function called: "checkAnswers()".
This function should check if the option that is selected in the dropdown box, has an id="answer". In this case, that would be if option one is selected. And if that option is selected, I want the background color of the select element to change.
How would I go about checking the currently selected dropdown options' ID? And how do I do this for more than 1 question at a time?
And how would I add a class programaticly in JavaScript to that select element so it can change BG color?
This is what I tried in JavaScript:
var s = document.getElementsByClassName("select-class");
var idSelectedOption = s[s.selectedIndex].id;
alert(idSelectedOption);
But that returns an error: "Uncaught TypeError: Cannot read property 'id' of undefined"
I think that is because it returns an array from all classes. How would I go about checking every single one of them? And changing the background colors of the ones that have the correct option selected?
Thanks in advance,
Mats.
Use data-* attributes instead of id as you should not have multiple elements having same id value in a document.
getElementsByClassName will return nodelist hence you need to iterate through elements and then apply conditions accordingly. Array.prototype.forEach.call is used in example below to iterate through elements.
Try this:
function checkAnswers() {
var s = document.getElementsByClassName("select-class");
Array.prototype.forEach.call(s, function(elem) {
var idSelectedOption = elem[elem.selectedIndex].getAttribute('data-id');
if (idSelectedOption == 'answer') {
var selectedAnswer = elem[elem.selectedIndex].getAttribute('value');
alert(selectedAnswer);
}
});
}
<form id="ansForm" class="testClass1">
<div id="QuestionForm" name="QuestionForm">
<label>Question 1: This is a question</label>
<select class="form-control select-class">
<option value="1" class="ans-class" data-id="answer">Answer1</option>
<option value="2" class="ans-class">Answer2</option>
<option value="3" class="ans-class">Answer3</option>
<option value="4" class="ans-class">Answer4</option>
</select>
<label>Question 2: This is another question</label>
<select class="form-control select-class">
<option value="1" class="ans-class">Another Answer</option>
<option value="2" class="ans-class">Just some text</option>
<option value="3" class="ans-class" data-id="answer">Test</option>
<option value="4" class="ans-class">Test2</option>
</select>
</div>
<button type="button" class="btn btn-primary" onclick="checkAnswers()">Check</button>
</form>
Fiddle here
You can't have two elements with the same id. Use a custom data attribute or a class instead
After fixing that, this code should to the trick. I tried to use vanilla JavaScript since you didn't indicate using jQuery.
// Lazy: Bind the event to the form.
document.getElementById('ansForm').addEventListener('change', function(event) {
var selectElement = event.target;
// Only respond if the clicked element is one of the selects.
if (selectElement.classList.contains('select-class')) {
// Get the option that is currently selected.
var selectedOption = selectElement[selectElement.selectedIndex];
// Check if this option contains the class 'answer'.
var isAnswerSelected = selectedOption.classList.contains('answer');
console.log(isAnswerSelected);
// Remove the indicators. You could easily use classList.toggle, but the second
// argument is not supported in IE.
// selectElement.classList.toggle('right', isAnswerSelected);
// selectElement.classList.toggle('wrong', !isAnswerSelected);
// So, second best. Just remove both and re-add the class we want.
selectElement.classList.remove('right');
selectElement.classList.remove('wrong');
selectElement.classList.add(isAnswerSelected?'right':'wrong');
} else {
// Ignore clicks on any other element.
}
});
.right {
color: green;
}
.wrong {
color: red;
}
<form id="ansForm" class="testClass1">
<div id="QuestionForm" name="QuestionForm">
<label>Question 1: This is a question </label>
<select class="form-control select-class">
<option value="1" class="ans-class answer">Answer1</option>
<option value="2" class="ans-class">Answer2</option>
<option value="3" class="ans-class">Answer3</option>
<option value="4" class="ans-class">Answer4</option>
</select>
<label>Question 2: This is another question </label>
<select class="form-control select-class">
<option value="1" class="ans-class">Another Answer</option>
<option value="2" class="ans-class">Just some text</option>
<option value="3" class="ans-class answer">Test</option>
<option value="4" class="ans-class">Test2</option>
</select>
</div>
<button type="button" class="btn btn-primary"
onclick="checkAnswers()">Check</button>
</form>
Try this for jQuery approach,
$(function(){
// This will bind 'click' event handler to element with id 'checkBtn'
$('#checkBtn').on('click', function(){
// This gets all selects element which has class containing 'select-class'.
var $selects = $('select.select-class');
// Iterate all the selects element.
$selects.each(function(k, v){
// Get the option for this current select element which has an id of 'answer'.
var $selectAnswerOpt = $(this).children('option#answer');
// Get the value attribute of the option element.
var answer = $selectAnswerOpt.attr('value');
// Get the selected value for the select element.
var selectedValue = $(this).val();
// Checking if the selected value for the select element is the option that has an id of 'answer'
if (selectedValue == answer)
{
// If the selected value has the id of 'answer'
$(this).css('background-color', 'green');
}
else
{
// Else
$(this).css('background-color', 'yellow');
}
});
});
});
And the FIDDLE

JavaScript events orders returning different values

So, I have 2 events attached to several select elements. A click event and a change event. When the user selects an option, I keep track of previously selected options on a JS object to tell the user that the option is already used and can't be reused and reset that select to the default value. If the select had a previous value that is not default, I remove the property from the object. Now, on each click event, I would have a JS variable give me the value of that select before the change happens. But, because of the difference in order of events been trigger (Firefox and Chrome) for example, in one I get the default which was when it reset, and the other I get the value right before the reset.
HTML:
<html>
<head>
<title>Objects test on Browsers</title>
</head>
<body>
<div class="container">
<select name="dd1">
<option value="0">-Select-</option>
<option value="cat">cat</option>
<option value="dog">dog</option>
<option value="bear">bear</option>
</select>
<br />
<br />
<select name="dd2">
<option value="0">-Select-</option>
<option value="cat">cat</option>
<option value="dog">dog</option>
<option value="bear">bear</option>
</select>
<br />
<br />
<select name="dd3">
<option value="0">-Select-</option>
<option value="cat">cat</option>
<option value="dog">dog</option>
<option value="bear">bear</option>
</select>
<br />
<br />
</div>
</body>
</html>
JavaScript:
var alreadyUsed = {};
var prevField = "";
$(function() {
// Events for drop downs
$("select[name^='dd']").on("focus", function(event) {
prevField = $(this).val();
console.log(prevField);
}).on("change", function(event) {
var fieldInUsed = checkNotUsedAlready("fields", $(this).val());
if (fieldInUsed === true) {
delete alreadyUsed[prevField];
$(this).val(0);
} else {
var selectField = $("select[name='" + event.target.name + "']" + " option:selected");
if (selectField.html() != "-Select-") {
alreadyUsed[selectField.html()] = $(this).val();
} else {
delete alreadyUsed[prevField];
}
}
});
});
function checkNotUsedAlready(type, value) {
var fieldColInUse = false;
if (type == "fields") {
for (var prop in alreadyUsed) {
if (alreadyUsed.hasOwnProperty(prop)) {
if (prop == value) {
fieldColInUse = true;
alert("Field is already in use.\nPlease, select a different field.");
break;
}
}
}
} else if (type == "columns") {
for (var prop in alreadyUsed) {
if (alreadyUsed.hasOwnProperty(prop)) {
if (alreadyUsed[prop] == value) {
fieldColInUse = true;
alert("Column is already in use.\nPlease, select a different column or custom.");
break;
}
}
}
}
return fieldColInUse;
}
I select cat on first drop down. Object now is Object{cat:"cat"}
I select dog on second drop down. Object is now Object {cat:"cat", dog:"dog"}
I select cat on second drop down.
At this point, firefox returns me dog as the previous value, which is what I want, but Chrome returns me zero because of the reset and when it set the value because of the events triggering order. Any ideas how can I deal with this in a different way?
One of the reasons for the JS object is that I need to have a list of which values are used to submit later and which are not used yet. A value needs to be unique.
NOTE: Choose cat for Drop down 1, dog for Drop down 2 and bear for Drop Down 3. Then, choose dog from Drop Down 1. On chrome, it will delete bear but on Firefox, it will delete cat.
Thanks in advance.
Maybe it would help to simplify things a bit. This works for me in Chrome, IE 9+, and Firefox:
var alreadyUsed = [];
$(document).ready( function() {
$("select[name^='dd']").data("previous","0");
$("select[name^='dd']").on("change", function(event) {
var newValue = $(this).val();
var prevValue = $(this).data("previous");
if(alreadyUsed.indexOf(newValue) == -1){
if(prevValue != "0") alreadyUsed.splice( alreadyUsed.indexOf(prevValue), 1 );
alreadyUsed.push(newValue);
$(this).data("previous",newValue);
}else{
alert("Field is already in use.\nPlease, select a different field.");
$(this).val(prevValue);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<select name="dd1">
<option value="0">-Select-</option>
<option value="cat">cat</option>
<option value="dog">dog</option>
<option value="bear">bear</option>
</select>
<br />
<br />
<select name="dd2">
<option value="0">-Select-</option>
<option value="cat">cat</option>
<option value="dog">dog</option>
<option value="bear">bear</option>
</select>
<br />
<br />
<select name="dd3">
<option value="0">-Select-</option>
<option value="cat">cat</option>
<option value="dog">dog</option>
<option value="bear">bear</option>
</select>
<br />
<br />
</div>
You code is a bit more complicated, and obviously does other things, but perhaps this simple working version will help.

Remove <option> by .class AND when custom attribute NOT equal to x

What I have:
I have a select element. Some of the options have both a class (.filterable_option) and custom attribute (data-clienturn).
What I need:
Based on the on change event of another element, I need to remove options from the select element that:
...are classed as .filterable_option.
...have a data-customattribute value NOT EQUAL TO the value of a predefined variable (var = $some_value).
My code:
HTML:
<select name="myselect_a">
<option selected="selected"></option>
<option value="Apply filter">Apply filter</option>
</select>
<select name="myselect_b">
<option selected="selected"></option>
<option data-customattribute="58" value="1" class="filterable_option">Dog</option>
<option data-customattribute="58" value="2" class="filterable_option">Cat</option>
<option data-customattribute="60" value="3" class="filterable_option">Parrot</option>
<option>I have no class or custom attribute.</option>
</select>
jQuery:
$('#myselect_a').on('change', function() {
var $myselect_a_option = $("#myselect_a").val();
if($myselect_a_option === 'Apply filter'){
var $some_value = '58';
$("select[name=myselect_b] option.filterable_option[data-customattribute!=" + $some_value + "]").remove();
}
});
JSFiddle:
For your convenience: http://jsfiddle.net/clarusdignus/L82UH/
My problem:
My code is not removing the required in options. Nothing happens.
You have used a name in your selector. Use an id instead as shown below
<select id="myselect_a">
<option selected="selected"></option>
<option value="Apply filter">Apply filter</option>
</select>
http://jsfiddle.net/L82UH/1/
Or if you still want to go for name, try the below code:
$('select[name="myselect_a"]').on('change', function() {
//your code
});
You have wrong selector for select and also following bit is corrected:
name='myselect_b']
Demo: http://jsfiddle.net/aamir/L82UH/2/
$('select[name="myselect_a"]').on('change', function() {
var $myselect_a_option = $(this).val();
if($myselect_a_option === 'Apply filter'){
var $some_value = '58';
$("select[name='myselect_b'] option.filterable_option[data-customattribute!=" + $some_value + "]").remove();
}
});
See you have name attribute in your markup:
<select name="myselect_a">
and you are using a id selector:
$('#myselect_a')
this is the issue.

Categories