JavaScript generated HTML with onClick doesn't trigger function - javascript

The script below adds items to an array when you click the link, and generates a list of items as html output. You can see an example here: http://jsfiddle.net/dqFpr/
I am trying to create a function to delete items from the list. Not a difficult task with splice(), but somehow clicking the delete link doesn't trigger the test_function() function.
Can someone tell me what I am doing wrong, or show me another way of triggering the function? Your help is really appreciated ;-)
<script language="javascript">
$(document).ready(function() {
function test_function( number ) {
/* This function is not triggered, nothing works inside here!! */
}
});
var lines = [];
function update_list( lines ) {
var thecode = '';
for(var i = 0; i < lines.length; i++) {
thecode = thecode + lines[i] + ' <a onclick="javascript:test_function('+i+')" href="#">(delete)</a><br />';
}
$('div#display').html(thecode);
}
$('a#new').click(function() {
lines.push('another line');
update_list(lines);
});
</script>
<div id="display"></div>
Add a new line

Because in the text assigned to display's innerHTML, *test_function* is just plain text that is evaluated by the HTML parser. At that point, its scope is global, not within the IIFE passed to $(document).ready(). You can fix that by making the function global:
$(document).ready(function(){
window.test_function = function (number) {
// do stuff
}
....
});
or
var test_function;
$(document).ready(function(){
test_function = function (number) {
// do stuff
}
....
});
Or whatever method you like to get access to the function. But while it is declared inside an anonymous function's scope, you can only get access to it from a function that has a closure to the variables in that scope.

Related

Using a variable inside a input check in JS

The input named alternativa-*** will have the *** changed in the PHP that comes before. I'm not using a form on PHP only a onClick statement calling the respondeQuestao function. But this code seems to not work. Someone have any suggestion.
$(document).ready(function() {
function respondeQuestao(qid,resposta) {
var alternativa = document.getElementsByName('input[name = "aternativa-"' + qid ']:checked').value;
document.getElementById("demo").innerHTML = 5 + 6;
if(alternativa==resposta) {
$("#botao-questao"+qid).hide();
};
if(alternativa!=resposta) {
};
};
})
Defining a function within the jQuery Ready statement limits the accessibility - define it outside of the jQuery Ready statement but call it when you need it.
function respondeQuestao(qid, resposta) {
var alternativa = $("INPUT[name^='alternativa-']:checked").val();
$("#demo").html(5+6);
if (alternativa == resposta) {
$("#botao-questro" + qid).hide()
} else {
//
}
}
Call the function inside jQuery:
$(function() {
respondeQuestao("id", 11);
});
I hope this helps.

JS onClick not working

Just don't know why this piece of code is not working: (onClick not working, click() is working (using console))
function click(ID)
{
if(cost[ID] <= currency[costID[ID]])
{
currency[costID[ID]] -= cost[ID];
currency[ID] += buyamout[ID];
document.getElementById(x[costID[ID]]).innerHTML = "<center>"+(Math.round(notyfication(currency[costID[ID]])*100)/100)+not+"</center>";
document.getElementById(x[gainID[ID]]).innerHTML = "<center>"+(Math.round(notyfication(currency[gainID[ID]])*100)/100)+not+"</center>";
}
}
...'<button onClick="click('+i+');">'+button+x[i]+'</button>'
this gives output <button onClick="click(0);">Make DNA</button>
and after clicking button nothing happens.
There could be a namespace conflict with your click. Use another name like button_click below
var i = 0;
var button = "Make ";
var x = [['DNA']]
document.writeln('<button onclick="button_click('+i+');" >'+(button+x[i])+'</button>');
function button_click(ID) { // notice the function name change
alert(ID);
}
Code below not working:
var i = 0;
var button = "Make ";
var x = [['DNA']]
document.writeln('<button onclick="click('+i+');" >'+(button+x[i])+'</button>');
function click(ID) { // the function name click may have been used already
alert(ID);
}
indeed onclick="click('+i+');" executes the javaScript code between the double brackets: click('+i+');: it calls the javaScript click() function, but this does not work if you declare function click() and someone else did that elsewhere in javaScript code.
if onClick is not working you can also use addEventListener will do the same job.
for e.g.
element.addEventListener('click', function() { /* do stuff here*/ }, false);
To answer your question you must do the following.
Change:
onClick="click(0)"
To:
onclick="click(0)"
That will most probably fix your problem.

onclick delete node and decrement counter

I have this code that I use to append some inputs + a button to delete the added input. I've set a counter to limit the number of added inputs to 5. What I'm trying to reach here is : when I click on the delete button it removes the appended element and decrements the counter
$(function($) {
var i = 1;
$("#btn_add").on("click",addAnotherPool);
function deletePool(){
this.parentNode.remove(this);
i--;
}
function addAnotherPool() {
if (i < 5) {
var html = '<div><input name="srv[]" id="srv_'+i+'" type="text"><button id="btn_del" name="pool_btn_add" onclick="deletePool()">Delete</button></div>';
$("#first_member").append(html);
}
i++;
return false;
}
});
When I run this code I get this error on the console :
Uncaught ReferenceError: deletePool is not defined
Can you please explain to me why this error ? How can I make this work ?
the problem is that deletePool is defined in a function, meaning that it is only a temporary function. you will have to make deletePool take in a argument for the object to delete, than have the html onclick like this:
onclick="deletePool(this)"
here is the deletePool function revised:
function deletePool(elm){
elm.parentNode.remove(elm);
}
There are more than one errors:
var i = 1; // declare global this variable
function deletePool(obj) { // declare global this function and use the this obj passed
obj.parentNode.remove(obj);
i--;
}
$(function () {
$("#btn_add").on("click",addAnotherPool);
function addAnotherPool() {
if (i < 5) {
var html = '<div><input name="srv[]" id="srv_'+i+'" type="text"><button id="btn_del" name="pool_btn_add" onclick="javascript:deletePool(this)">Delete</button></div>';
$("#first_member").append(html);
i++;
}
return false;
}
});
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<div id="first_member">
</div>
<p><br/></p>
<button id="btn_add" onclick="">btn_add</button>

Calling a Javascript only with the button class

I am new to Javascript and also new to this Website.
I have about 40 Buttons which are all in the class "foo".
I also have a Javascript function named "run".
How can I set the Javascript to run whenever one of the buttons in class "foo" is pressed without actually setting the button to run it?
Is this even Possible?
Yes. Here is an example using jQuery.
$('.foo').click(function() {
run();
});
OR, using plain old JavaScript (see the jsfiddle):
//generates a "NodeList" of all buttons
var foo = document.getElementsByTagName('button'),
//then, we turn it into an actual array
foo = Array.prototype.slice.call(foo);
foo.forEach(function(button) {
//check to see if that button has the class "foo"
if(button.classList.contains('foo')) {
button.onclick = function() {
return run();
};
}
});
function run() {
console.log('run');
}
You could use
getElementsByClassName
but the downside of that, is that the only version of IE in which it is supported is 9+ (including all other major browsers), which is fine, if that's what you decide to go with.
Live Demo
You can copy + paste this right into your code and should work perfectly.
var buttons = document.getElementsByClassName('foo');
for (var i = 0; i < buttons.length; i++) {
addEvent(buttons[i], 'click', run);
}
function addEvent(element, myEvent, fnc) {
return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false));
};
Without jQuery:
var foos = document.getElementsByClassName('foo');
for (var i=0; i<foos.length; i++) {
foos[i].onclick = function() { run() };
}
JSFiddle: http://jsfiddle.net/8AKeP/
There are 3 simple ways to accomplish this.
First, you can just use plain vanilla Javascript. No external libraries are required.
// Get all buttons
var buttons = document.getElementsByClassName('foo');
// Loop through the buttons
for(var i = 0; i < buttons.length; i++){
// Tell each button that when it is clicked, call the "run" function.
buttons[i].onclick = run;
}
Second, You can specify the onclick methods in your HTML. This is a bad approach as it forces you to define global methods (functions that are accessible from anywhere), and also ties your code with your markup, making it hard to change one without changing the other.
<!-- Old HTML -->
<button class="foo">Text</button>
<!-- New HTML -->
<button class="foo" onclick="run()">Text</button>
Lastly, You can include the very helpful jQuery library to handle it for you. jQuery provides an easy way to handle binding events, selecting elements, etc.:
// One line (deconstruction below)
// $(".foo") => Find me all elements with a class name of "foo"
// .on("click", => When those elements are clicked
// run); => Call the "run" method.
$(".foo").on("click", run);
The last approach, using jQuery has become the sort of de facto standard way of doing this.
Try this:
var run = function(){
//your function goes here
}
$(document).on('click', '.foo', run);
I would use jQuery, for example:
$('.foo').click(function(){
run();
});
it is simpler to program. However, without using jQuery:
var buttons = document.getElementsByClassName('foo');
function run(){
alert('hi');
}
for(var i = 0; i < elements.length; i++){
buttons[i].onclick = function() { run() };
}

Jquery - binding click event to a variable

All,
I am really stuck/ confused at this point.
I have an array with 6 items in it. Each item in the array is dynamically filled with elements using jquery '.html' method. However, I cannot seem to be able to attach/ bind an event to this dynamically created variable.
As soon as the browser gets to the problem line (see the area labeled 'PROBLEM AREA'), I get a 'undefined' error, which is really confusing as all the previous code on the very same variable works just fine.
var eCreditSystem = document.getElementById("creditSystem");
var i = 0;
var eCreditT = new Array(6); // 6 members created which will be recycled
function createCreditTransaction () // func called when a transaction occurs, at the mo, attached to onclick()
{
if (i < 6)
{
eCreditT[i] = undefined; // to delete the existing data in the index of array
addElements (i);
} else
if (i > 5 || eCreditT[i] != undefined)
{
...
}
}
function addElements (arrayIndex) // func called from within the 'createCreditTransaction()' func
{
eCreditT[i] = $(document.createElement('div')).addClass("cCreditTransaction").appendTo(eCreditSystem);
$(eCreditT[i]).attr ('id', ('trans' + i));
$(eCreditT[i]).html ('<div class="cCreditContainer"><span class="cCreditsNo">-50</span> <img class="cCurrency" src="" alt="" /></div><span class="cCloseMsg">Click box to close.</span><div class="dots"></div><div class="dots"></div><div class="dots"></div>');
creditTransactionSlideOut (eCreditT[i], 666); // calling slideOut animation
console.log(eCreditT[i]); // this confirms that the variable is not undefined
/* ***** THE PROBLEM AREA ***** */
$(eCreditT[i]).on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn (eCreditT[i], 150); // slide back in animation
});
return i++;
}
Try this:
$(eCreditT[i]).bind('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
Edit: use ++i instead of i++ like this:
return ++i;
/*
or
i += 1;
return i;
*/
retrurn ++i performs the increment first then return i after the increment.
While return i++ return i then icrement it.
Try to add click event out of addElements() function and try once.
Nonsense create an element using JavaScript and then use jQuery function to transform it into a jQuery object. You can let jQuery create the element directly for you.
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
Also, since eCretitT[i] is already a jQuery element, no need to call the jQuery function again.
eCreditT[i].on('click', function () {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
If you already tried on, bind, live and click methods, then maybe the called function is your problem. Try to put a console.log() or an alert() inside the function to make sure the click event is actually happening. If it happens then the function creditTransactionSlideBackIn() is your problem.
EDIT
The problem is when the event takes place, i is not the original variable anymore.
function addElements (arrayIndex)
{
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
eCreditT[i].attr ('id', ('trans' + i));
eCreditT[i].data ('id', i); // Store the id value to a data attribute
Then when you call the function you can refer to the data attribute instead of the i variable:
/* ***** THE PROBLEM AREA ***** */
eCreditT[i].on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn ($(this).data('id'), 150); // slide back in animation
});
return i++;
}
try to bind parent div and then use if($e.target).is('some')){}, it will act as .live, like this:
$(eCreditSystem).bind('click', function (e){
if($(e.target).is('.cCreditTransaction')) {
creditTransactionSlideBackIn ($(e.target), 150);
}
});
of course you'll need in a minute larger if for checking if clicked dom el is a child of .cCreditTransaction, like this:
if($(e.target).parents().is('.cCreditTransaction')){}
Try this:
$(eCreditT[i]).live('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});

Categories