Here I am trying to add a few classes in this ".ingradient" class element when ".tt-select" select changes. So, I was almost there. But when I select the option, there is a list of ".ingradient" items. I need to perform the below code for that specific one who we selected currently. I know we can use $this keyword, But I can't write the code for it. Please help. Thanks
$('.tt-select').change(function(){
$('.ingradient').addClass('animate__animated animate__heartBeat');
const remClass = setTimeout(fnRemClass, 2000);
function fnRemClass() {
$('.ingradient').removeClass('animate__animated animate__heartBeat');
}
});
What I've tried yet but no success.
$('.tt-select').change(function(){
$('.ingradient', this).addClass('animate__animated animate__heartBeat');
const remClass = setTimeout(fnRemClass, 2000);
function fnRemClass() {
$('.ingradient', this ).removeClass('animate__animated animate__heartBeat');
}
});
Here is the ".tt-select" select fields.
And here is the ".ingradient" class where I need to add classes individually.
Hope, someone can help me to find out how I can use $this keyword properly here. Thanks
[EDIT]
After receiving a suggestion on comments I tried this still with no success:
$('.tt-select').change(function(){
$(this).find(':selected')
.addClass('animate__animated animate__heartBeat');
const remClass = setTimeout(fnRemClass, 2000);
function fnRemClass() {
$(this).find(':selected')
.removeClass('animate__animated animate__heartBeat');
}
});
First things first: options can't be styled
First things first: I should say that you can't properly style <option> elements. I mean it's still legit of course to use classes and perform selection based on such criteria, but the styling itself is very limited for the options. That's why usually very stylish dropdowns are actually custom elements on top of real <select> elements. But yet it's perfectly legit to use them as utility classes.
Function type and scope at time of execution:
Said that...
The problem with your latest approach was trying to use this inside the callback defined inside your change event handler that you are going to pass later to setTimeout.
Such function at time of execution will have this set as window hence the .find operation won't perform returning the desired result. It will instead fetch ALL elements matching that selector in the umbrella of window (global scope).
While instead you needed to retain the scope of the targeted select element.
The quick solution to your problem is properly defining a callback that will retain the correct scope and that will access directly to the variable already holding the selected option instead of querying again the document.
Here I simplified your example adding/removing just one class and having two different dropdowns to show that while doing something on one dropdown the other doesn't get affected.
I used a variable named $selectedOption (using the $ just because it was a convention back then to mark it as a jQuery wrapper object instead of the vanilla HTMLElement) that gets reused inside the callback:
$('.tt-select').change(function(){
//fetching the selected option for the dropdown firing the change event
const $selectedOption = $(this).find(':selected');
$selectedOption.addClass('customclass');
console.log('class added to selected option')
const callback = ()=>{
$selectedOption.removeClass('customclass');
console.log('class removed from selected option')
};
setTimeout(callback, 2000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="tt-select">
<option value="" selected></option>
<option value="option1">option1</option>
<option value="option2">option2</option>
<option value="option3">option3</option>
</select>
<select class="tt-select">
<option value="" selected></option>
<option value="option1">option1</option>
<option value="option2">option2</option>
<option value="option3">option3</option>
</select>
And here I made a very simple demo showing different ways to define functions that will log on console a different value of this (I'm using .constructor.name to show off the type of the value):
$('.tt-select').change(function(){
console.log(`change event handler... 'this' value type: [${this.constructor.name}]`);
//fetching the selected option for the dropdown firing the change event
const selectedOption = $(this).find(':selected');
//callback defined with the function notation and no variable set explicitely
function callback1(){
console.log(`Callback[1] executing... 'this' value type: [${this.constructor.name}]`);
};
//callback defined with the function notation setting the scope variable callback2
const callback2 = function(){
console.log(`Callback[2] executing... 'this' value type: [${this.constructor.name}]`);
};
//callback defined as an arrow function setting the variable callback3
const callback3 = ()=>{
console.log(`Callback[3] executing... 'this' value type: [${this.constructor.name}]`);
};
setTimeout(callback1, 500);
setTimeout(callback2, 500);
setTimeout(callback3, 500);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="tt-select">
<option value="" selected></option>
<option value="option1">option1</option>
<option value="option2">option2</option>
<option value="option3">option3</option>
</select>
Related
I've been trying to get variables to work with drop down options on a page. I was struggling to even get a value out of the function but managed by removing "var" from o1. Now if I type o1 into the js console on chrome i get a value for it but if I set another variable equal to it, such as b1, it comes out as undefined. I'd like to add if statements after the function using its output but they didn't work either. Not sure what i'm doing wrong...
<html>
<head>
<title>Options to variables</title>
</head>
<body>
<form>
Options
<select id="i1" onchange="options()">
<option selected = "true" disabled="disabled">---</option>
<option id="1">Option 1</option>
<option id="2">Option 2</option>
</select><br>
</form>
</body>
<script>
var o1;
function options(){
o1 = i1.options[i1.selectedIndex].id;
return o1;
}
var b1 = o1;
</script>
</html>
The statement var b1 = o1; is not inside the function.
When the page loads you copy the value undefined from o1 to b1.
When the change event fires, you write a new value to o1 but you never change b1, so it remains undefined.
Not sure what i'm doing wrong
Aside from the logic errors described above, your fundamental approach to the problem is wrong. You should read the value of the select element when you want to do something with that value.
You should not try to duplicate the information about what state it is in using a global variable. The state is reliably available from the original select element whenever you need it.
Some notes:
Your code is relying on the automatic globals created when elements have an id. That's generally a bad idea, there's a lot going on in the global namespace and conflicts are rife. Instead, look them up with document.getElementById.
Returning a value out of the function you call from an onxyz-attribute-style event handler is not useful (unless you return false, which would prevent the default action of the event). I suggest you look into modern event handling.
Your var b1 = o1; is outside of your options function, so it's run when the page loads. At that time, o1 is undefined, so of course b1 is undefined. o1 is given a different value later, when options is run, but that doesn't change b1.
Having ids on your option elements is unusual. The normal thing is to give them values. And if you do, you can use .value on the select to get its value.
Here's an example avoiding those issues, and showing the id of the selected option element (along with the select's value) in the console when you change it:
// A scoping function to avoid creating globals
(function() {
// Get the select element
var i1 = document.getElementById("i1");
// Watch for `change`
i1.addEventListener("change", function() {
// Show the ID of the selected option, and the select's value
console.log("ID: " + i1.options[i1.selectedIndex].id + ", value: " + i1.value);
});
})();
<form>
Options
<select id="i1">
<option selected = "true" disabled="disabled">---</option>
<option id="1" value="one">Option 1</option>
<option id="2" value="two">Option 2</option>
</select><br>
</form>
In fact, we can avoid using a variable for the select at all, since inside the event handler, the select box is available as this:
document.getElementById("i1").addEventListener("change", function() {
// Show the ID of the selected option, and the select's value
console.log("ID: " + this.options[this.selectedIndex].id + ", value: " + this.value);
});
<form>
Options
<select id="i1">
<option selected = "true" disabled="disabled">---</option>
<option id="1" value="one">Option 1</option>
<option id="2" value="two">Option 2</option>
</select><br>
</form>
If you need to support obsolete browsers that don't have addEventListener, my answer to this other question has a function you can use.
I have a selectbox with an onchange:
<select id="select" onchange="eventA();">
I'd like to change the "onchange" to something else, for example to eventB();.
I've tried this, based on this post: How to add an onchange event to a select box via javascript?
document.getElementById("select").onchange="eventB()";
However, nothing happens, the onchange does not change.
Any ideas?
Hi You should try out this code.
<html>
<head>
<title> Script </title>
<script type='text/javascript'>
function changeFirst(){
alert('I am first');
}
function changeSecond(){
alert('I am second');
}
function changer(){
document.getElementById('selectinput').attributes.onchange.nodeValue = "changeSecond()";
}
</script>
</head>
<body onload="changer()">
<select id="selectinput" onchange="changeFirst()">
<option value="1"> One </option>
<option value="2"> two </option>
<option value="3"> three </option>
<option value="4"> four </option>
<option value="5"> five </option>
</select>
</body>
</html>
It's little bit easy to use jquery instead of pure javascript. But with javascript you can't directory change any attributes like value or innerHTML. document.getElementById('ELEMENT_ID') will return html tag not an object. you can change value using document.getElementById('ELEMENT_ID').value = 'your_value' but change any event attribute is not done like this.
document.getElementById('ELEMENT_ID').attribute will return all the used attribute of element and you can change it's value using nodeValue as I show you in example.
One more clarification according to your need that if you write this code in your select box change event than every time your first event was called for e.g. if I write changer() function code into changeFirst() function than change event of selectbox will fire changeFirst() at firsttime and from the next time the changeSecond() event will fire. So I suggest you to use jquery change event instead of using pure javascript to prevent this type of confusion.
The answer is in a comment. For your code:
document.getElementById("select").onchange="eventB()";
you should not set the property to a string, you should assign a function reference, so:
document.getElementById("select").onchange = eventB;
Assigning a string may work in some browsers but all browsers support assigning a function.
You might find the MDN onchange article helpful, it also has links to relevant standards.
I would go with a classic vanilla javascript event listener for your class. Like:
var select = document.getElementById("select");
select.addEventListener("change", function(){
eventB();
});
or alternatively:
var select = document.getElementById("select");
select.addEventListener("change", eventB);
ILE, can you try this code:
document.getElementById('select').setAttribute('onchange','eventB();');
<select id="dropdown1" name="dropdown1" onchange="dropdown1_onchange();">
<option selected value=""> Select</option>
<option value="value1">value1</option>
<option value="value2">value2</option>
<option value="value3">value3</option>
</select>
function dropdown1_onchange()
{
alert(this.value);
}
Javascript gets called but this.value comes up undefined. I know I can use
$('dropdown1').value
but I am trying to understand why this sometimes represents a current object and other times - window. Normally when I use inline javascript this is a representation of the current object...
You problems is that this inside function dropdown1_onchange refers to window. You can use argument to retrieve value.
function dropdown1_onchange(elem)
{
alert(elem.value);
}
You shouldn't use inline javascript. Change your code to use event listeners like the following:
<select id="dropdown1" name="dropdown1">
<option selected value=""> Select</option>
<option value="value1">value1</option>
<option value="value2">value2</option>
<option value="value3">value3</option>
</select>
<script>
document.getElementById('dropdown1').addEventListener('click', dropdown1_onchange);
function dropdown1_onchange(event)
{
alert(event.target.value);
}
</script>
You can use this function:
function dropdown1_onchange(el) {
if (el.selectedIndex <= 0)
return null;
alert(el.options[el.selectedIndex].value);
}
JS Bin here.
You can hook into the onchange event of the select element 2 ways.
Inline
Putting the event handler code in the Select elements onchange="" attribute. This becomes your entire event handler function. It is basically wrapped with a function call
<select id="dopdown1" onchange="dropdown1_change">
</select>
// EXAMPLE FUNCTION OF WHAT HAPPENS BEHIND THE SCENES.
// This function exists in the browers/javascript framework.
// Your code will be executed inside its context.
function sudo_eventhandler(event)
{
// Whatever is inside your onchange="" attribute
dropdown1_change(this);
}
function dropdown1_change(element)
{
alert(element.value);
}
So you will have to pass this or any other properties to any method you call outside of this function as this is no longer the element.
Event Handler
You can hook up your own event handler to the element by selecting it out in javascript.
document.getElementById('dropdown1').addEventListener('click', dropdown1_onchange);
function dropdown1_change()
{
alert(this.value);
}
This makes your event handler the actual handler and not just a method called from inside of the handled event. So this is now the element you expect as the element is essentially calling the method, not the window.
I have several select boxes on a page, and basically anytime an onchange event occurs with any of those boxes I want to use the same piece of code instead of making a separate script for each select box's id. The reason is that I could be ending up with dozens of these select boxes on a page and all that repeated code just gets messy.
<select name="drop_list_menu_1" id="drop_list_menu_1">
<option value="letter:a">A</option>
<option value="letter:b">B</option>
<option value="letter:c">C</option>
</select>
<select name="drop_list_menu_2" id="drop_list_menu_2">
<option value="letter:a">A</option>
<option value="letter:b">B</option>
<option value="letter:c">C</option>
</select>
<select name="drop_list_menu_3" id="drop_list_menu_3">
<option value="letter:a">A</option>
<option value="letter:b">B</option>
<option value="letter:c">C</option>
</select>
My code to handle the onchange event:
<script type="text/javascript">
$(document).ready(function () {
// if user chooses an option from the select box...
$("#drop_list_menu_1").change(function () {
//doin some stuff
});
</script>
So, how can I get this:
$("#drop_list_menu_1").change(function () {
//doin some stuff
});
to catch any of the select boxes on the page being used? Something incorporating a regex?
Give the elements a common class (you can keep the id attributes if you want) and then use delegation:
$(document).on("change", "your-select-class", function() {
var changedElement = this;
// ...
});
You just need that one call to set up the event handler, and it'll work for as many copies as you need on the page.
You could use jQuery's attribute starts-with selector to select all drop-downs whose name begins with "drop_list_menu_":
$("select[name^='drop_list_menu_']").change(function(){
//doin some stuff
});
Assign same class to each Select and call it as below.
$(".ClassName").change(function (e) {
var SelectId = e.target.id
});
simple as that
$("select").change(function () {
alert('a');
});
I have a form with a simple drop-down menu when the user selects any of the options, i want to be able to pass that selected value to a JavaScript function
Once the user clicks on an option it will alert the value in the jQuery change function but I want to use the value that was passed through in other functions but it does not get the value for some reason
function getTweet(){
$('#test').change(function() {
var value = $('#test :selected').val();
});
}
want to use the value outside of the change function but it does not grab it
<form>
<select id="test">
<option value="one">1</option>
<option value="two">2</option>
<option value="three">3</option>
</select>
</form>
If you want to use the most current value of the drop-down anywhere in your code, you can just reference it like this:
$('#test').val()
I've removed the :selected, because that's not necessary; .val() will give the right value.
You might use custom events to do something based on that event?
Example:
$('#test').change(function () {
$('mysubscriberselectorshere').trigger('gettweet');
});
// do something based on the custom event
$('mysubscriberselectorshere').on('gettweet', function {
// do good stuff here
alert($('#test').val());
});