Passing additional parameter through Event Listener - javascript

this code:
var messageLine = "this is a line of text";
myTextField.addEventListener('change', textHasBeenChanged, false);
calls this function:
function textHasBeenChanged(e) { var target = e.target; messageLine = target.value;}
Now I want to pass an additional piece of data... like a simple number 1. Like this:
myTextField.addEventListener('change', function(){textHasBeenChanged(theValueOfTheTextField, theNumber1);});
How can this be done? I'm still a programming newbie, so please keep your answer as close as possible to the syntax you see above.

You can call/invoke the function inside of an anonymous function by passing the additional parameter. Also you can consider using input event instead of change which is fired synchronously when the value of an <input>, <select>, or <textarea> element is altered:
var messageLine = "this is a line of text";
var myTextField = document.getElementById('myTextField');
myTextField.addEventListener('input', function(){textHasBeenChanged(event, 1)}, false);
function textHasBeenChanged(e, other) {
var target = e.target;
messageLine = target.value;
console.clear(); //clear the previous data in console
console.log(messageLine);
console.log(other);
}
<input id="myTextField"/>

If you're not going to take the even listener off afterward than you should be able to just pass the argument right to the function you're giving to the event listener
myTextField.addEventListener('change', textHasBeenChanged(1), false);
you dont have to pass e for the event because when provide a named function to an event listener e is already assumed to be the first argument

Related

Click event returns undefined, but when I run a load event on the window the function works

I am trying to simply put a word from my array into the DOM. When the button is clicked it returns undefined and if I console.log the randIndex I get NaN.
Ok, so I have tried to figure this out but I think I am missing something. When I click on the mealBtn it should run a function to show a meal item above the button. However, it returns undefined and puts undefined in the DOM. The thing that most confuses me is if I run an initialize function on window.load it does exactly what its suppose to.
//load an item from menu on window load
window.addEventListener('load', init);
const mealBtn = document.getElementById('mealBtn');
const currentMeal = document.getElementById('current-meal');
const message = document.getElementById('message');
const menu = [
'Macaroni',
'Burgers',
'Chili',
'Breakfast',
'Chicken',
'Take Out?'
];
function init(){
showMeal(menu);
}
mealBtn.addEventListener('click', showMeal);
//show a meal from menu array
function showMeal(menu){
const randIndex = Math.floor(Math.random() * menu.length);
currentMeal.innerHTML = menu[randIndex];
message.innerHTML = 'How about this?';
message.style.color = '#003b6f'
};
I expect that when I click the button it should give a menu suggestion in the DOM right above the button. It works on the init function when the window is loaded just not when the button is clicked.
mealBtn.addEventListener('click', showMeal);
the argument being passed to showMeal when this is triggered is the event, not menu
you want either
mealBtn.addEventListener('click', () => showMeal(menu));
// or
mealBtn.addEventListener('click', showMeal.bind(null, menu));
The second is an example of partial application... it's succinct but not exactly immediately readable.
Event listener callback in javascript accepts single parameter: object based on Event (see here).
MouseEvent (click) has a detail property, whoch can be used as obj.addEventListener("click", (e) => doSomethingWith(e.detail))
In your case, the Event parameter is no use to you and you want to pass custom parameters to the handler. Tyler's answer shows you the way to adapt the handler. However, you could also simply
mealBtn.addEventListener('click', init);

Qualtrics API functions not working within custom function called in EventListener

I defined a custom function in the header section that checks, alerts the user, and resets the value of a particular slider bar when it fails certain restrictions.
This function works beautifully when called on question clicks:
this.questionclick = chkVals;
I would like to also run the function when the user are exiting the text input field (as some users are using the keyboard to do the survey). I implemented an Event Listener for each sliders' text input field that runs the function when the focus is out of the text input field.
// choices is an array of choice ids
for (i = 0; i < choices.length; i++) {
var x = document.getElementById(choices[i]);
x.addEventListener("blur", chkVals, true);
};
I know that the event listener works, because the correct alerts are popping up. It is just not able to reset the values as this.setChoiceValue is not a function within the environment. I have tried setting var that = this; and calling that.setChoiceValue in the function, but it still does not work.
Any help will be greatly appreciated!
You haven't shown all your code, so I'm making some assumptions.
this is the Qualtrics question object in the addOnload function. Since chkVals is outside the addOnload function, this (or that) is undefined. So, you need to pass it in your function call (function chkVals(qobj)) then use qobj.setChoiceValue in the chkVals function. Then your function calls become:
this.questionClick = chkVals(this);
and
x.addEventListener("blur", chkVals(this), true);
#T. Gibbons 's answer helped me get to this point. As suggested I needed to add a parameter to chkVals() to be able to reference the this object. However,
this.questionClick = chkVals(this);
does not work due to this being a reserved object, so the whole header script will not run. I ended up changing all reference of this to that in my custom function and adding the parameter that as suggested:
function chkVals(that) {
...
... that.setChoiceValue(x, y)
}
To call the function with a parameter, I had to explicitly defined an anonymous function that called chkVals, otherwise it will not work (I am not sure why):
var that = this;
this.questionclick = function() {chkVals(that);}
for (i = 0; i < choices.length; i++) {
var x = document.getElementById(choices[i]);
x.addEventListener("blur", function() {chkVals(that);}, true);
};
The above works!

.addEventListener vs .onclick

I keep reading that there is no difference between the two but I am writing a quiz app and am seeing some differences
For example:
Quiz.prototype.handleGuess = function (id, guess) {
let button = document.getElementById(id);
button.addEventListener('click', function(){
quiz.guess(guess);
console.log(guess);
}
if(!quiz.hasEnded){
quiz.displayNext();
} else {
quiz.displayScore();
};
};
When using an event listener, I will log the guess to the console on the first button choice. When I choose an answer for the second question the console will read not only the new selection but also the choice I made from the previous question. This does not happen when using .onclick() and I am not sure why!
Consider the following code:
var el1 = document.getElementById("someEl1"),
el2 = document.getElementById("someEl2");
function firstHandler() {
alert("First handler");
}
function secondHandler() {
alert("Second handler");
}
el1.addEventListener("click", firstHandler);
el1.addEventListener("click", secondHandler);
el2.onclick = firstHandler;
el2.onclick = secondHandler;
<div id="someEl1">First Element</div>
<div id="someEl2">Second Element</div>
In case 1, clicking on el1 will alert with both messages. In case 2, clicking on el2 will only alert with the second because we overwrote what onclick does with the second assignment.
addEventListener effectively assigns a callback to some internal array of listener callbacks that will all be called whenever the event is triggered.
onclick is a single property with a single value. When you assign to it, the old value is replaced by the new assignment.
I would highly suggest that you do not use the onclick method. It makes code harder to maintain. If you are in a large code base and you set the onclick of an element and then later on another coder also sets the onclick without knowing that that element already had its onclick set, then you will run into a difficult time trying to figure out why your code is broken all of a sudden. Using the event listener pattern makes for more extensible and decoupled code.

My EventListener to a button continues to fire despite ownership being changed, why? (JavaScript)

I have a function, which at the end of its task assigns a button to a new id.
function altChecker() {
var doc = document,
out = [],
appButton = doc.getElementById('appButton'),
//re = /click-me/gi,
output = doc.createElement('p');
output.setAttribute('id', 'output');
EventUtility.addHandler(appButton, 'click', function(e) {
//I have not included all the function details to concentrate on the question
appButton.id = 'appButtonNextChecker';
var appButtonNextChecker = doc.getElementById('appButtonNextChecker');
nextChecker(appButtonNextChecker);
});
}
function nextChecker(newBtnName) {
EventUtility.addHandler(newBtnName, 'click', function(e) {
$('#output').innerHTML = "";
console.log('next Checker, button!')
});
}
So basically there is one button in the DOM assigned to appButton ID initially, and then I change it doing:
appButton.id = 'appButtonNextChecker';
when the altChecker function fires...
Then I assign the button to a new variable, and pass in the variable to the next function...
var appButtonNextChecker = doc.getElementById('appButtonNextChecker');
nextChecker(appButtonNextChecker);
While I can see the buttons' ID change in the DOM, and I see the console.log fire in the nextChecker function,
$('#output').innerHTML = ""; //doesn't fire
AND the altChecker function fires as well (again)?! Haven't I severed the connection to the click function when I reassigned the new ID?
Any help would be appreciated!
Javascript doesn't remember that you initially attached the event through it's id. The event is attached to the element itself, not the ID. It's not like CSS that way.
In fact your variables are still holding the same element as well, so there's no need to create a new variable after changing the ID, either. Since you're using jQuery you can just type $(appButton).unbind(); to remove the event handler. You may also want to look into .on() and .off()
The problem is that you're trying to use the innerHTML property in a jQuery's object.
That property belongs to Element, and it will not work in the way you're using it.
You can use the document.getElementById method, and it will work fine:
document.getElementById('output').innerHTML = '';
Or you can use jQuery's html method:
$('#output').html('');
And you can even use the first element of the jQuery's array, and use innerHTML again:
$('#output')[0].innerHTML = '';
It's up to you, but the first option will be faster, for sure.

Call an object as a function in JavaScript

I'm trying to execute JavaScript functions that are called when a event (for example onClick event) is performed on a web page with JavaScript code. I'm getting the function from the event like this :
var attributval = document.getElementsByTagName("a").getAttribute('onClick');
and I'm trying to execute this object (which a JavaScript function in fact) as a function (suppose we have <a onClick = alert('whatever');> on this example, I tried:
var attributval = document.getElementsByTagName("a").getAttribute('onClick');
attributval() = function(){attributval};
attributval();
but it didn't work.
A DOM attribute is not the same as a JavaScript property (even though they can have the same name onclick). You should use
var attributval = document.getElementsByTagName("a")[0].onclick;
to retrieve a function (or null) from the JS object (as opposed to getAttribute(), which will most likely return a toString() for the property).
Now, attributval() = is illegal syntax, as attributval() is not an l-value (you cannot assign to it).
attributval(); will work but without the second line (which is illegal JavaScript) it will invoke the original A element onclick handler (if one is defined) or throw an exception (if the onclick handler is null).
Skip trying to create a function around the function. Just call it:
var attributval = document.getElementsByTagName("a")[0].onclick;
attributval();
try
var attributval = document.getElementsByTagName("a")[0].getAttribute('onClick');
By using get attribute you are returning a string so your only way is to use eval(onclickString) or var fn = new Function(onClickString); fn();
attributval is simply a string, correct? If you trust this code, execute it with eval(attributval) -- however any reference to this won't work.
What you probably want is to manually trigger an event. jQuery makes that easy.
If you want to do more than a click, then Chris McDonald's answer at Is it possible to trigger a link's (or any element's) click event through JavaScript? seems to fit the bill, although you might need to heed the third comment.
I thought I'd add a short answer on how to work with events using jQuery, since it seems relevant.
// Select the link using it's ID field (assuming it has one)
var myLink = $('a#myLink')
// Add a click event to the link
myLink.on('click', function(e) {
console.log("I've been clicked!");
});
// Trigger the click event manually. This would result in the above
// function being run. Interestingly, this will not cause the browser
// to follow the link like a real click would
myLink.trigger('click');
// Remove the click event (this removes ALL click events)
myLink.off('click');
// Add a click event to the link that only runs once, then removes itself
myLink.one('click', function() {
alert("I'll only bother you once!");
});
// Add a click event that you can identify from other click events.
// This means that you can trigger it or remove it without bothering other
// click events
myLink.on('click.myClick', function() {
alert("This click event has been identified as 'myClick'");
});
// Now you can trigger it without triggering other click events
myLink.trigger('click.myClick');
// And remove it, also with no harm coming to other click events
myLink.off('click.myClick');
Hope this helps

Categories

Resources