How to determine which button called a function? - javascript

How would I know which button caused this function to run? Specifically, if I want to set the value of the function to be equivalent to the value of the button?
var foo_button = document.getElementById("foo_button");
var bar_button = document.getElementById("bar_button");
foo_button.onclick = foo_or_bar;
bar_button.onclick = foo_or_bar;
Then in a function later on:
function foo_or_bar(){
//this should return the value of the button that was pressed (in this case "foo"
//or "bar"
return button_that_sent_me;
}
Is there a way I can detect the value of which button caused this to occur?

You can use this as #A1rPun says or access the button through window.event, which also helps when you use inline onclicks, and other unrecommended practices:
JS
function foo_or_bar() {
console.log(window.event.target.value);
console.log(this.value);
}
HTML
<button id="foo_button" value="foo">internals</button>
Gives you the following console log:
foo
foo

'this' sends all information associated with the element fire the event:
<button onclick="foo_or_bar(this.id);" id="foo">Foo</button>
function foo_or_bar(id) {
button_that_sent_me = id;
}

Related

How to link the variable for the function to the button's variable?

Im new to javascript, is there any way to link my function's var to the button so that the function can be executed properly.I cant seem to link the function's variable to the button's id or even the button itself.
//My button
var btn1 = document.createElement('button');
btn1.textContent = questions[0].A
btn1.id = 'optionA'
document.body.appendChild(btn1);
btn1.addEventListener('click', fSubmit);
//My Function
var score=0;
function fSubmit(){
var correctanswer=btn1;
if(correctanswer.checked==true){
score++;
alert("Answer is correct! "+"Your Score is now "+score++)}
else{
alert("Answer is incorrect!")}
}
what I think you are trying to say is that you want to bind the "correctness" of a button's data to the score. What I would do is add a custom data attribute to each button containing 'true' or 'false' value for that button.
Like so:
btn1.dataset.correctOrNot = true
Then you test that value in your fSubmit function:
if (btn1.dataset.correctOrNot === true) {
// etc. etc.
}

Error adding event listener, says element is null

I'm removing inline event handlers and replacing them with event listeners. When the page loads there is the error message TypeError: document.getElementById(...) is null. What am I doing wrong?
//adding function listeners
var inputEl = document.getElementById('us');
inputEl.addEventListener('keyup', availability, false); // error here
function availability(name, availabilityDiv)
{
var name = document.getElementById('us').value;
//code sniped
}
<input type="text" name="us" id="us" />
I know my code is rather strange so let me explain. I want to call a function each time a character is entered into an input field and I want the characters entered to be passed to the function as an argument. If there's a better way of doing this do tell.
If you are placing your script in the header, then it has to be run on the onload event
ex
window.onload = function(){
//adding function listeners
var inputEl = document.getElementById('us');
inputEl.addEventListener('keyup', availability, false); // error here
function availability(name, availabilityDiv)
{
var name = document.getElementById('us').value;
//code sniped
}
}

Not working my javascript onblur function

I am having some problems with a javascipt function which I'm working on.
Here is what I am trying to do with the function:
I have a table element with a given value, and when there is a click on it, it calls my javasript function which is supose to appendChild an INPUT element with the value of the element, so the user can change that value. I want the INPUT element to call a function whit the onblur() event, so the modified value could be display again on the table element.
My problem is that the element does not respect the onblur() event. The function is executed right after the Input element is created, and does not wait to be an onblur() event.
Here is the code of the two functions:
var elemento = true;
function prueba(clave,cantidad) {
if(elemento){
var percent = document.getElementById('porciento' + clave);
percent.innerHTML = "";
var input = document.createElement("input");
input.setAttribute('type','text');
input.setAttribute('size','5');
input.setAttribute('value',cantidad);
input.setAttribute('id','child'+clave);
percent.appendChild(input);
input.focus();
child = document.getElementById("child" + clave);
child.onblur = blurPrueba();
}
}
function blurPrueba() {
if(elemento)
alert("Hello");
}
The alert is displayed without being an onblur()
Does anyone knows why this is happening???
Your problem is: child.onblur = blurPrueba(), where you execute blurPrueba immediately. Should be a reference: child.onblur = blurPrueba
Changing the line, you tell the browser: "on blur for the child element, activate the blurPrueba function".
If you use blurPrueba() you activate the function and assign it's result to the blur event, blurPrueba() doesn't return anything. So your line actually says: "onblur = undefined"
In summary, if you want the browser to handle an event (here blur) you need to provide a reference to the handler function (here blurPrueba).
Change
child.onblur = blurPrueba();
to
child.onblur = function(){blurPrueba()};

AJAX addEventListener - passing parameters to another function

I'll keep this short - I've got a list of buttons, that I create using a loop, and when one of them gets clicked I want to be able to pass its id attribute to another file in order to dynamically generate a new page.
Here's the code:
for (var i in data.contacts) {
var temp = document.createElement('div');
temp.className = "contacts";
var dude = document.createElement('input');
dude.type = "button";
dude.value = data.contacts[i];
dude.id = data.contacts[i];
dude.className = "dude_button" + data.contacts[i];
dude.addEventListener('click', function(event) { gotoProfile(dude.id); }, false);
temp.appendChild(dude);
temp.appendChild(document.createElement('br'));
theDiv.appendChild(temp);
}
// and now in another file, there's gotoProfile():
function gotoProfile(x) {
var username = document.getElementById(x).value;
if (xmlHttp) {
try {
.... etc.
Now see this works, sort of, but the problem is that when I click any button, it only passes the last dude.id value from the list data.contacts. Obviously I want every button's addEventListener to pass its own data.contacts[i] value, instead of just the last one.
Help appreciated, thanks guys.
Because JavaScript has no block scope, dude will refer to the last assigned element (because the loop finished) when the event handler is called. You have to capture the reference to the current dude by e.g. using an immediate function:
dude.addEventListener('click', (function(d) {
return function(event) {
gotoProfile(d.id);
}
}(dude)), false);
This is a common error when creating functions in a loop.
But you can make it even easier. The event object has a property target that points to the element the event was raised on. So you can just do:
dude.addEventListener('click', function(event) {
gotoProfile(event.target.id);
}, false);
And with that said, you don't need to add a handler for every button. As you are doing the same for every button, you could attach the same event handler above to the parent of the buttons (or a common ancestor) and it would still work. You just have to filter out the clicks that don't happen on a button:
parent.addEventListener('click', function(event) {
if(event.target.nodeName == 'INPUT' && event.target.type == "button") {
gotoProfile(event.target.id);
}
}, false);

Detect programmatical changes on a html select box

Is there a way to make a HTML select element call a function each time its selection has been changed programmatically?
Both IE and FF won't fire 'onchange' when the current selection in a select box is modified with javascript. Beside, the js function wich changes the selection is part of framework so I can't change it to trigger an onchange() at then end for example.
Here's an example:
<body>
<p>
<select id="sel1" onchange="myfunction();"><option value="v1">n1</option></select>
<input type="button" onclick="test();" value="Add an option and select it." />
</p>
<script type="text/javascript">
var inc = 1;
var sel = document.getElementById('sel1');
function test() {
inc++;
var o = new Option('n'+inc, inc);
sel.options[sel.options.length] = o;
o.selected = true;
sel.selectedIndex = sel.options.length - 1;
}
function myfunction() {
document.title += '[CHANGED]';
}
</script>
</body>
Is there any way to make test() call myfunction() without changing test() (or adding an event on the button)?
Thanks.
If you can extend/modify the framework to give a hook/callback when they change the select options, it would be better (one way could be to use the dynamic capabilities of js to duck type it in?).
Failing that, there is an inefficient solution - polling. You could set up a setTimeout/setInteval call that polls the desired select option dom element, and fire off your own callback when it detects that something has changed.
as for the answer to your question
Is there any way to make test() call
myfunction() without changing test()
(or adding an event on the button)?
yes, by using jquery AOP http://plugins.jquery.com/project/AOP , it gives an easy-ish solution.
<body>
<p>
<select id="sel1" onchange="myfunction();"><option value="v1">n1</option></select>
<input type="button" onclick="test();" value="Add an option and select it." />
</p>
<script type="text/javascript">
var inc = 1;
var sel = document.getElementById('sel1');
function test() {
inc++;
var o = new Option('n'+inc, inc);
sel.options[sel.options.length] = o;
o.selected = true;
sel.selectedIndex = sel.options.length - 1;
}
function myfunction() {
document.title += '[CHANGED]';
}
//change to aop.after if you want to call afterwards
jQuery.aop.before( {target: window, method: 'test'},
function() {
myfunctino();
}
);
</script>
</body>
Define your own change function that calls the framework function and then calls a
callback function.
e.g.:
function change(callback)
{
frameworkchange();
callback();
}
The answer is .... no.
The DOM only fires the onchange event as a result of user action not code. It does not provide any additional events to hook in this regard.
You will need to customise the framework or drop your requirement.
ahem...
you can access the event 'onpropertychange' it contains a property within the event arguments to identify which property was changed.
It detects both 'selectedIndex' and 'value' changes - simply case test 'propertyName' I'm currently working with the ASP.NET js framework here is some straight copy-paste code for that:
1) define handler:
this._selectionChangedHandler = null;
2) assign handler
this._selectionChangedHandler = Function.createDelegate(this, this._onSelectionChanged);
3) attach handler to event
$addHandler(element, "propertychange", this._selectionChangedHandler);
4) create function
_onSelectionChanged: function(ev) {
if (ev.rawEvent.propertyName == "selectedIndex")
alert('selection changed');
},
With JQuery, you could do something like
$(document).ready(function(){
$('#select-id').change(function(e){
e.preventDefault();
//get the value of the option selected using 'this'
var option_val = $(this).val();
if(option_val == "v1"){
//run your function here
}
return true;
});
});
This would detect the change programmatically and let you respond to each item changed

Categories