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()};
Related
I have input in my page and it get or set value from other function in js
now i want know any ways has when my input get or set value it run other
function and set other input value
here is my function set value to input1
function showPoint(loc) {
var docloc = myDiagram.transformDocToView(loc);
var elt = document.getElementById("P18_LOC");
elt.value = "view coordinates: " + docloc.x.toFixed(2) + " " + docloc.y.toFixed(2);
}
now i need any event or listener when input get or set value run other function
i tired onchange() and oninput() and some more js event but i cant fix it
now : any way has to do that?
When an element gets its value changed dynamically through code, user events like change and input don't fire off. What you need to do is manually call for those events to fire with the jQuery .trigger() method.
function showPoint(loc) {
var docloc = myDiagram.transformDocToView(loc);
var elt = document.getElementById("P18_LOC");
elt.value = "view coordinates: " + docloc.x.toFixed(2) + " " + docloc.y.toFixed(2);
// Trigger the change event of the P18_LOC element
$(elt).trigger("change");
}
Now, you can set up a change event handler for P18_LOC and it will fire whenever showPoint() is called.
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;
}
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
}
}
I have a method which is called onClick of some element. In that function I have an event handler( JQuery $().click() ), that detects the click of a button and performs some action.
I have noticed that the event handler works fine as long as it is the last block of statement in the function and is skipped altogether if there lie certain code block after it. Why is that happening?
EDIT Adding code
function launchPopUp(ID) {
if ($('#popUp').is(':hidden')) {
var serial = ID.id; // ID of the element or area clicked.
var headData = 'SVG PopUp';
var entData = 'Enter the data you want to store:';
var ok = "No";
var input = "";
var header = addHeader(headData);
var enterable = addEnterable(entData);
var buttons = addButtons();
$('#popUp').append(header);
$('#popUp').append(enterable);
$('#popUp').append(buttons);
$('#popUp').show();
$('#btnSubmit').click(function() {
input = document.getElementById('txtData').value;
if (input != "") {
ok = "yes";
$(ID).css('fill', 'green'); // Change colour to green only if some valid data is entered.
closePopUp();
}
});
var collData = { "ID": serial, "header": headData, "OK": ok, "input": input };
collection.push(collData);
}
}
Control is jumping straightaway to the code block after the .click()
You are misunderstanding the event handlers.
Javascript has asynchronous nature, so (in normal cases) there is no "waiting" for an event.
You register an eventhandler like your click() and then the function is executed when (eventually) a click on that element is registered. In the meantime the execution of the rest of your code goes on.
If you want to make your code dependent on the click, you have to write this code into the function of the click handler or pass a callback to the function.
Registering Event-Handlers is a one-time process and has to be done outside your function - at the moment you are registering a new click-handler every time you call launchPopUp. E.g. if you are calling launchPopUp five times, your code
input = document.getElementById('txtData').value;
if (input != "") {
ok = "yes";
$(ID).css('fill', 'green');
closePopUp();
}
also gets executed five times as soon as you click on #btnSubmit.
Basically you have to structure your code like the following:
register eventhandler for #btnSubmit - define what is happening when the button is clicked in this function (evaluation of your inputs)
write the launchPopUp function which gets eventually executed. No eventhandler in here and no evaluation code on btnSubmit this is all done in your eventhandler.
I think this is what you want:
function launchPopUp(ID) {
if ($('#popUp').is(':hidden')) {
var serial = ID.id; // ID of the element or area clicked.
var headData = 'SVG PopUp';
var entData = 'Enter the data you want to store:';
var ok = "No";
var input = "";
var header = addHeader(headData);
var enterable = addEnterable(entData);
var buttons = addButtons();
$('#popUp').append(header);
$('#popUp').append(enterable);
$('#popUp').append(buttons);
$('#popUp').show();
var collData = { "ID": serial, "header": headData, "OK": ok, "input": input };
collection.push(collData);
$('#btnSubmit').click(function() {
input = document.getElementById('txtData').value;
if (input != "") {
collData.OK = "yes";
$(ID).css('fill', 'green'); // Change colour to green only if some valid data is entered.
closePopUp();
}
});
}
}
Note that the collData is a variable containing a reference to an object. That object is added to the collection, and modified within the click handler when the btnSubmit button is clicked. This way, if the save button is never clicked, the object is still added to the collection. But if it is clicked, the object is changed, and closePopUp() is called, presumably allowing you to do what you need to do with the objects which exist in the collection variable.
$('#btnSubmit').click(function() {
input = document.getElementById('txtData').value;
if (input != "") {
ok = "yes";
$(ID).css('fill', 'green'); // Change colour to green only if some valid data is entered.
closePopUp();
}
});
Put the above outside your loadPopup function and put it in a
$(document).ready(function()
{
});
That might just solve it.
EDIT:
$('#btnSubmit').click(function()
{
input = document.getElementById('txtData').value;
if (input != "")
{
ok = "yes";
$(ID).css('fill', 'green'); // Change colour to green only if some valid data is entered.
closePopUp();
}
var collData = { "ID": serial, "header": headData, "OK": ok, "input": input };
collection.push(collData);
});
var collData should be IN your click function, then it will be executed when you click on the submit button.
The above code will not work good if I understand it correctly. It looks like every time you launch the popup you bind a new click event to it. So if you launch the same popup twice you will have two on click event handlers bound to the object.
Accessing variables outside the closure is practical. However, you can only access the variables that has been defined before you define your closure.
Imagine that you move the definition of "ok" after you define your click event handler. In that case OK would not be defined and there will be another ok in the event handler.
(I hope I understood your question correct, please comment otherwise)
Try this:
var launchPopUp = function launchPopUp(ID) {
'use strict';
var popup = $('#popUp'), //cache #popup instead of doing multiple lookups
headData = 'SVG PopUp',
entData = 'Enter the data you want to store:',
submit = null, //declare a var to cache #btnSubmit instead of doing multiple lookups
submitHandler = function (e) { //handler can be defined anywhere in this routine
//collData should be defined in the handler
var collData = {
"ID": ID.id, // ID of the element or area clicked.
"header": headData,
"OK": "No",
"input": document.getElementById('txtData').value
};
//modify collData based on inputs at time #btnSubmit is clicked.
if (collData.input !== "") {
collData.OK = "yes";
$(ID).css('fill', 'green'); // Change colour to green only if some valid data is entered.
closePopUp();
}
collection.push(collData);
};
if (popup.is(':hidden')) {
popup.append(addHeader(headData));
popup.append(addEnterable(entData));
//if addButtons() defines/creates/adds #btnSubmit then you will need
//to attach the handler after #btnSubmit exists in the DOM
popup.append(addButtons());
//once #btnSubmit is in the DOM, you can add the handler at any time
//although I recommend doing it prior to showing #popup
submit = $('#btnSubmit'); //cache #btnSubmit
if (!submit.data('handlerAttached')) {
//only need to attach the handler one time.
//also note that attaching the handler does not fire the handler
//only clicking the button, or calling the handler (i.e., submit.click()
//or submitHandler(), etc.) will fire the handler.
submit.click(submitHandler);
//set flag to indicate that the handler has been attached.
submit.data('handlerAttached', true);
}
popup.show();
}
};
Also, as long as these are all defined elsewhere:
addEnterable()
addButtons()
addHeader()
closePopUp()
collection[]
your routine shouldn't have any errors preventing execution of the handler.
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);