Assigning onclick event to global variables - javascript - javascript

I have many divs with class "mypoll". Here is my js code:
var mypoll=[];
$(document).ready(function (){
mypoll=document.getElementsByClassName("mypoll");
});
for(var t=0; t<mypoll.length; t++) {
mypoll[t].getElementsByClassName("deletePoll")[0].onclick=(function() {
var currentI = t;
return function() {
deletedMyPoll(currentI);
};
})();
}
function deletedMyPoll(i){
var a=document.getElementsByClassName("mypoll")[0].innerHTML;
alert(a);
}
The error I get is
cannot set property onclick of undefined.
I have the exact same piece of code on my project (it is big and complicated and I can't post it all here) but it doesn't work.
It works on the jsfiddle though.
Is there any problem with the global variables in javascript? Can I use them that way?
jsfiddle.net/Vwtmu
Thank you

If you're going to use jQuery, you might as well use it:
$(".mypoll").on('click', '.deletePoll', function () {
});

The for loop runs before the dom is ready.
$(document).ready(function (){
mypoll=document.getElementsByClassName("mypoll");
for(var t=0; t<mypoll.length; t++) {
mypoll[t].getElementsByClassName("deletePoll")[0].onclick=(function() {
var currentI = t;
return function() {
deletedMyPoll(currentI);
};
})();
}
});

Related

Pass HTML element to JavaScript function

I am passed 3 html elements as parameters to JS function. JS function is in separate file. I have problem to bind 'click' event with _confBtn object (which is parameter). My complete JS file:
window.HAS = window.HAS || {};
HAS.MyApp = HAS.MyApp || {};
(function (_this, $, undefined) {
var _sessionTimeOut = false;
var _startCountDown = false;
var _counterTime;
var _countDownTime;
var _dialogWrap;
var _confBtn;
var _counter;
_this.init = function (showDialogTime, logofCountDownTime, dialogWrap, counter, confirmationButton) {
_counterTime = 5;
_countDownTime = 0;
_dialogWrap = $('#' + dialogWrap);
_confBtn = $('#' + confirmationButton);
_counter = $('#' + counter);
alert(_confBtn.text());
createSessionTimeOut();
$(document).bind("mousemove keypress mousedown mouseup", resetTimeOut);
}
_confBtn.on('click', function () {
window.clearInterval(_startCountDown);
_dialogWrap.css('visibility', 'hidden');
createSessionTimeOut();
$(document).bind("mousemove keypress mousedown mouseup", resetTimeOut);
});
function createSessionTimeOut() {
_sessionTimeOut = window.setTimeout(function () {
_dialogWrap.removeAttr("style");
_counter.text(_counterTime);
$(document).unbind("mousemove keypress mousedown mouseup");
startCountDown();
}, 2000);
}
function startCountDown() {
_startCountDown = window.setInterval(function () {
if (_counterTime >= 0) {
_counter.text(_counterTime--);
}
_countDownTime++;
if (_countDownTime >= 4) {
logOutUser();
return;
}
}, 1000);
}
function resetTimeOut() {
window.clearTimeout(_sessionTimeOut);
_sessionTimeOut = false;
createSessionTimeOut();
}
function logOutUser() {
$.ajax({
url: '/MyApp/Account/LogOut',
type: 'GET',
success: function () {
document.location.href = '/MyApp/Account/Login';
}
})
}
}(window.HAS.MyApp.SessionTimeOut = window.HAS.MyApp.SessionTimeOut || {}, jQuery));
I call in separate page like in following:
SessionTimeOut.init('5', '5', 'dialog-wrap', 'confirm-button', 'counter');
I have issue with _confBtn when I try to call click event. Browser show that is undefined.
Please help.
It would probably better to do something more dynamic like this:
function SomeFunction (element1,element2) {
var e1 = $("#"+element1),
e2 = $("#"+element2);
// Do something with variables e1 and e2
}
and you would call like this:
//html:
<div id="one"><div>
<div id="two"><div>
//javasctript:
SomeFunction('one','two');
No, you are mixing a function declaration with a function call somehow. You can't provide function arguments when defining a function. This however will work fine:
function someFunction($element1, $element2) {
//Do something with the elements
}
someFunction($("#element1"), $("#element2"));
Note that $element1 and $element2 are just variable names, and the leading $ doesn't have anything to do with jQuery. It is just a common convention to identify variables referencing jQuery selections.
You can of course do it, just by using the normal jQuery way of including multiple selectors. Your code is slightly incorrect because you are actually only defining the function without calling it, and you are not supposed to pass arguments/variables into the function when defining it.
Unless you have the intention to distinguish between two groups of elements, I would refrain from declaring elements individually as you have used in your question, because sometimes you will never know the length of the selected items.
function someFunction($ele) {
// jQuery objects will be accessible as $ele
}
// Call the function
someFunction($('#selector1, #selector2'));
However, if the former is the case, you can always do so:
function someFunction($ele1, $ele2) {
// jQuery objects will be accessible as $ele1 and $ele2 respectively
// Example: $ele1.hide();
// $ele2.show();
}
// Call the function
someFunction($('#selector1'), $('#selector2'));
For example, you can refer to this proof-of-concept JSfiddle: http://jsfiddle.net/teddyrised/ozrfLwwt/
function someFunction($ele) {
// jQuery objects will be accessible as $ele
$ele.css({
'background-color': '#c8d9ff'
});
}
// Call the function
someFunction($('#selector1, #selector2'));
If you want to pass some elements to function you can use jQuery constructor to standardize arguments
function SomeFunction (element1,element2) {
element1 = $(element1);
element2 = $(element2);
// and you have 2 jQuery objects...
}
// and now you can pass selector as well as jQuery object.
SomeFunction($('div.a'),'#b');
You can pass paramters as much as you want this way. I use jQuery in this code and created a simple function.
var item=$("#item-id");
var item1=$("#item1-id");
makeReadOnly(item,item1);
function makeReadOnly(){
for(var i=0;i<arguments.length;i++){
$(arguments[i]).attr("readonly", true);
}
}

checkValidity() not working within function

I've got a simple function that does basically nothing but alert me of the validity:
function alertV(elem) {
alert("here");
alert(elem.checkValidity());
alert("really");
}
The code for hooking this up:
var elements = document.forms["form"].getElementsByTagName("input");
for (i = 0; i < elements.length; i++) {
elements[i].onkeyup = function () { alertV(elements[i]) };
}
Here shows up fine, but checkValidity() isn't doing anything and is even causing the really call to be ignored. Am I passing in the arguments wrong? I essentially just want this, which works:
<input type="text" onkeyup="alertV(this);">
Try using a closure:
elements[i].onkeyup = (function (a)
{
return function ()
{
alertV(elements[a])
}
})(i);

How do I get "I" to increment inside a .click function

$('#x').click(function() {
var i=1;
$('#y').prepend('<div id='+i+'>x'+i+'</div>');
i++;
});
I want the i to increment, now for some reason it is not. I will agree this is a silly question.
Place var i before the click scope:
var i=1;
$('#x').click(function() {
$('#y').prepend('<div id='+i+'>x'+i+'</div>');
i++;
});
Try not to litter the global scope. This solution will encapsulate i, but still retain its value
$('#x').click((function() {
var i = 1;
return function () {
$('#y').prepend('<div id='+i+'>x'+i+'</div>');
i++;
}
})());
Example: http://jsfiddle.net/Hxw3q/

Calling nested function using javascript

I have this code which calls a function test() on body onload
<body onLoad="test();">
The Test function has 2 more functions drawLayers() ,StopAll().
function test() {
function drawLayers() {
timers = [];
timers.push(setTimeout(drawMoon,800));
timers.push(setTimeout(drawCircle1,2300));
timers.push(setTimeout(drawCircle2,2700));
timers.push(setTimeout(drawCircle3,3100));
timers.push(setTimeout(drawCircle4,3500));
timers.push(setTimeout(drawCircle5,3900));
timers.push(setTimeout(drawtext2,4300));
timers.push(setTimeout(drawtext,4700));
timers.push(setTimeout(drawtext3,5100));
timers.push(setTimeout(drawtext4,5500));
timers.push(setTimeout(drawtext5,5900));
timers.push(setTimeout(drawtext6,6300));
timers.push(setTimeout(drawtext7,6700));
timers.push(setTimeout(drawtext8,7100));
timers.push(setTimeout(drawtext9,7500));
timers.push(setTimeout(drawtext10,7900));
}
function StopAll() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
}
What i want to do is Call the StopAL() function on click of a button, the html code looks like below
<a href="javascript:void(0);" onClick="StopAll();">
Its throwing error, "StopAll is not defined"
How do i call the StopALL() function?
The scope of those nested functions is restricted to the test function only. You cannot invoke them from the outside. If you need to do that you could externalize it from the test function.
This is a 'closure' problem. The function StopAll is within the scope of the test function, and therefore is undefined in the global scope in which you are trying to call it.
Closures are a tricky subject to grasp initially. There's a good explanation here:
How do JavaScript closures work?
(by the way StopAll should really be called stopAll because capitalised functions are generally reserved for use with the new keyword.)
test = function (){
this.drawLayers = function() {
this.timers = [];
this.timers.push(setTimeout(drawMoon,800));
}
this.StopAll = function() {
alert('fsdfsdf');
var t = timers.length
for (var i = 0; i < t; i++)
window.clearTimeout(this.timers[i]);
}
}
var testObj = new test();
testObj.StopAll()
function test() {
function drawLayers() {
timers = [];
timers.push(setTimeout(drawMoon,800));
timers.push(setTimeout(drawCircle1,2300));
timers.push(setTimeout(drawCircle2,2700));
}
var StopAll=function() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
return StopAll;
}
var obj= new test();
//to call StopAll function
obj();
(function test($) {
function drawLayers() {
}
//expose this to outside world ,public function
$.StopAll = function() {
alert('fsdfsdf');
}
})(window);
StopAll();
You'd better not use html attributes to bind event handler, you can do the same with the following code:
window.onload = function(){
document.getElementById("myLink").onclick = function(){
StopAll();
}
}
// Your functions
This way you'll ensure your dom is loaded and ready to call event handlers.
You can move the function StopAll() outside the test function and call it as specified. If suppose you need to access that function even in the test(), you can do like this
function test() {
.....
drawLayers();
StopAll() ;
}
function StopAll() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
Declaration of function can be given outside and called any where you want

How to call function outside of jQuery(document).ready with setTimeout()?

My code looks something like:
$(document).ready(function(){
var cont = 0;
function func1(cont)
{
//Some code here
search.setSearchCompleteCallback(this, searchComplete, null);
//Some other code
}
func1(cont);
function searchComplete()
{
//Some code
cont += 1;
if (cont < length ) {
func1(cont);
} else {
// Other code
}
}
});
So what I want to do is delay the execution of func1(cont); inside of the searchComplete() function. The reason for this is that all the code does is to work with the Google search API and PageRank checks and I need to slow down the script so that I won't get banned. (Especially for the requests it makes regarding the PR check).
If I simply use setTimeout() on func1(cont); it says there is no func1() defined, if I try to get the function outside $(document).ready() it sees the function but the Google code won't for for it needs the page completely loaded.
How can I fix setTimeout or how can I pause the script for a number of seconds ?
Thanks!
Write
func1(cont);
as
window.setTimeout(function() {
func1(cont);
}, 1000);
Instead of declaring the function like this:
function func1(cont) {}
declare it like this:
var func1 = function(cont) {}
You'll need to rearrange your code a little:
$(document).ready(function(){
var cont = 0;
var func1;
var searchComplete = function()
{
//Some code
cont += 1;
if (cont < length ) {
func1(cont);
} else {
// Other code
}
}
func1 = function(cont)
{
//Some code here
search.setSearchCompleteCallback(this, searchComplete, null);
//Some other code
}
func1(cont);
});
I'd try something like this. I prefer to declare the vars and functions inside the jquery namespace, but you could equally move the cont variable and the functions outside of the document ready function and have them available globally.
$(document).ready(function(){
$.cont = 0;
$.func1 = function() {
//Some code here
search.setSearchCompleteCallback(this, $.searchComplete, null);
//Some other code
}
$.searchComplete = function() {
//Some code
$.cont += 1;
if (cont < length ) {
setTimeout($.func1,1000);
} else {
// Other code
}
}
setTimeout($.func1,1000); // delay the initial start by 1 second
});
Hopefully I've got your description correct:
document.ready() event fires
Inside document.ready() you want a function to be called after X milliseconds
This function wires up the Google object search.setSearchCompleteCallback() to another function (which it looks like it needs a parent object from the this)
If this is the case, why do you need any of the functions declared inside the document.ready() scope? Can you't simply make all 3 global? e.g.
var search = null; // initialise the google object
var cont = 0;
function timedSearch()
{
search.setSearchCompleteCallback(this, searchComplete, null);
}
function searchComplete()
{
if (++cont < length) // postfix it below if this is wrong
setTimeout(timedSearch,1000);
}
$(document).ready(function()
{
setTimeout(timedSearch,1000);
}
Hit me with the downvotes if I've misunderstood.

Categories

Resources