Reading a function from another function - javascript

The problem that when I click on .test it does not execute the do_alert(); function and gives me a error:
do_alert(); is not defined.
What's the problem? the main function helpers is already read when the page is loaded why can' get this function from logout_users function?
var setup_system = (function($) {
"use strict";
return {
init: function() {
this.logout_users();
this.helpers();
},
logout_users: function() {
$(document).on('click', '.test', function(e) {
e.preventDefault();
do_alert();
});
},
helpers: function() {
function do_alert() {
alert();
}
}
};
})(jQuery);
jQuery(document).ready(function() {
setup_system.init();
});
NOTE: I try to re-read the helpers function by adding this.helpers() inside logout_users function but nothing change.

It's because you've defined do_alert() within the scope of the helpers function.
To fix this you will need to move that function to within scope of the object you return. You could either put it at root level of the object (which would work fine, but could get messy if you have a lot of 'helper' functions) or you could nest it within your helpers property if you define that as another object. Personally, I'd use the latter to have some semblance of organisation. Try this:
var setup_system = (function($) {
"use strict";
return {
init: function() {
this.logout_users();
},
logout_users: function() {
var _obj = this;
$(document).on('click', '.test', function(e) {
e.preventDefault();
_obj.helpers.do_alert();
});
},
helpers: {
do_alert: function() {
alert('foo');
}
}
};
})(jQuery);
jQuery(function() {
setup_system.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">Click me</div>
Note that I cached the reference to the object as _obj outside of the click handler, as within that block this will refer to the clicked .test element.

Do_alert function exist only in helpers method, so you can't access to it.
You need to declare your function directly in the logout_user method or outside, try this :
var setup_system = (function ($) {
"use strict";
return {
init: function () {
this.logout_users();
this.helpers();
},
logout_users: function() {
function do_alert(){
alert();
}
$(document).on('click', '.test', function(e){
e.preventDefault();
do_alert();
});
},
helpers: function () {
function do_alert(){
alert();
}
}
};
})(jQuery);
jQuery(document).ready(function () {
setup_system.init();
});

When helpers is invoked by the initfunction, all that is happening is that do_alert is being declared. But function declarations are hoisted to the top of their lexical scope. The lexical scope of do_alert is the scope defined by the helpers function. Therefore, do_alert is not accessible outside of helpers function.
A couple things you could do. The first one that comes to mind is: you could have the helpers method define a method called do_alert on the object being returned rather than merely declaring a function, like so:
helpers: function() {
this.doAlert = function() {
alert();
}
}
When your doAlert() is invoked by the event handler passed to jQuery, it will not work with the above solution. Instead you will need to make sure you call that doAlert on the returned object in that event handler. This is how you can do that:
logout_users: function() {
var self = this;
$(document).on('click', '.test', function(e) {
e.preventDefault();
self.doAlert();
});

Related

How bind a event and use apply/call to change the scope

+function ($) {
'use strict';
var popup = {
init: function(element) {
this._active = 'products__popup--active';
this._product = $('.products__popup');
this._element = $('[data-popup-to]');
this._TIME = 500;
popup.attachEvt();
},
attachEvt: function() {
var that = this;
that._element.bind('click', popup.handlerEvt.call(that));
},
handlerEvt: function() {
console.log(this);
console.log('test');
}
};
$(window).on('load', function() {
popup.init();
});
}(jQuery);
I have this script, and is not working yet, I cant show you a working example because it is not ready, I'm organizing the code first.
And there is a problem with the attachEvt function, inside it I want to call another function of my object, this function will bind a click in the that._element, but I want pass to the handlerEvt the scope of this (the clicked element) and the that (the object), but this is not working:
that._element.bind('click', popup.handlerEvt.call(that));
I'm just passing the that scope and when the script loads, the element will be clicked without click, I want avoid this.. this is possible?
UPDATE:
Resuming:
I want be able to use the scope of the object (that) and the scope of the clicked element (this) inside the handlerEvt function, but without make the event click when the script loads.. :B
Try utilizing .bind() , with this set to that._element , that passed as parameter to handlerEvent . Note order of parameters at handlerEvent: obj: that first , evt event object second
+function ($) {
'use strict';
var popup = {
init: function(element) {
this._active = 'products__popup--active';
this._product = $('.products__popup');
this._element = $('[data-popup-to]');
this._TIME = 500;
popup.attachEvt();
},
attachEvt: function() {
var that = this;
that._element.bind('click', popup.handlerEvt.bind(that._element, that));
},
handlerEvt: function(obj, evt) {
console.log(evt, obj, this);
console.log('test');
}
};
$(window).on('load', function() {
popup.init();
});
}(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div data-popup-to="true">click</div>

(document).ready is a global scope?

Guys i have this function inside my script.js:
$(document).ready(function() {
function alert() {
alert('AAAAAAAA');
}
});
And i am trying to call here in my index.html:
$('.something').on('click', function() {
e.preventDefault();
alert();
});
But is showing my this error - alert is not defined.
But when i take off the document ready in the external script, the click handler will work. Why is that?
The document ready is creating a separate scope?
Using $(document).ready() creates a new function scope (note the function() after the .ready), so when you call
$(document).ready(function() {
function alert() {
alert('AAAAAAAA');
}
});
alert is only defined within the document.ready block. There are two ways to solve this issue:
Define the function outside of the document.ready block:
function customAlert() {
alert('AAAAAAAA');
}
Attach the function to the window object:
$(document).ready(function() {
window.customAlert = function() {
alert('AAAAAAAA');
};
});
Include the click event into the document.ready
Check it here http://jsfiddle.net/fbrcm45q/1/
$(document).ready(function() {
function showAlert() {
alert('AAAAAAAA');
}
$('.something').on('click', function(e) {
e.preventDefault();
showAlert();
});
});
First of all e.preventDefault is a function so you have to add braces at the end:
e.preventDefault()
Second alert is a function in javascrpt, so you need to rename your function to something else, for example:
$(document).ready(function() {
function special_alert() {
alert('AAAAAAAA');
}
});
and:
$('.something').on('click', function() {
e.preventDefault();
special_alert();
});

Simplify code with named self invoking function

I have this script:
function fixHeight () {
$(".sidebar-mainbox-container").height($(window).height());
})
fixHeight();
$(window).on("resize", function() {
fixHeight();
})
I'm looking for a way to simplify it using a self invoking function and then call it in the resize event.
I've tried this one:
var fixHeight = (function () {
$(".sidebar-mainbox-container").height($(window).height());
})();
$(window).on("resize", function() {
fixHeight();
})
But in this way the value of the self-invoked function is assigned to fixHeight, and this can't work.
If I remove the self-invoking part...
var fixHeight = (function () {
$(".sidebar-mainbox-container").height($(window).height());
});
$(window).on("resize", function() {
fixHeight();
})
Then the function works only when I call it on resize, and this is not good.
How can I simplify this code to avoid 3 elements for such a simple task?
What's wrong with
$(window).on("resize", function() {
$(".sidebar-mainbox-container").height( $(this).height() );
});
?
To avoid an extra function call just trigger the event immediately after registering it.
$(window).on("resize", /* ... */).trigger("resize");

JS Jquery Namespace Calling Functions

Ok terrible title but I couldn't think of another description.
I have the following code:
jQuery( document ).ready( function( $ )
{
$.myNamespace = {
init: function()
{
$('.button').click(function() {
this.anotherFunction();
});
},
anotherFunction: function()
{
alert('insidefunction');
}
}
$.myNamespace.init();
});
As you can see I am trying to call anotherFunction from inside init and have there the two ways I tried but didn't work. So how am I able to call that function or is my concept wrong?
jQuery( document ).ready( function( $ )
{
$.myNamespace = {
init: function()
{
var a=this;
$('.button').click(function() {
a.anotherFunction();
});
},
anotherFunction: function()
{
alert('insidefunction');
}
}
$.myNamespace.init();
});
http://jsfiddle.net/ZpAtm/2/
Absolutely calling it within the click handler changes things, as this inside any jQuery event handler is set to the element that caused the event.
Instead, try using the following pattern:
jQuery(document).ready(function($) {
$.myNamespace = (function() {
function init() {
$('.button').click(function() {
anotherFunction();
});
}
function anotherFunction() {
alert('insidefunction');
}
// return an object with all the functions you want
// available publically as properties. Don't include
// any "private" functions.
return {
init: init,
anotherFunction: anotherFunction
};
})();
$.myNamespace.init();
});​

JS & EXT JS: function inside a function scope misunderstanding

im having some trouble with the following code:
Ext.define('...controller...', {
extend: 'Ext.app.Controller',
init: function() {
...
},
crearLoginWindow:function(){
var loginWindow = Ext.create('Proto1.view.adminbd.LoginWindowBDView', {
itemId: 'loginwindow',
autoShow: true,
modal: true
});
Ext.ComponentQuery.query('#loginwindow > button[text="Cancelar"]')[0].on('click', function(){loginWindow.close()});
//Cant call 'enviarLogin' function if its inside 'crearLoginWindow'
Ext.ComponentQuery.query('#loginwindow > button[text="Conectar"]')[0].on('click', this.enviarLogin, this);
var enviarLogin = function(){
console.log('login')
}
}
});
I want to be able to call 'enviarLogin' inside 'crearLoginWindow' function but it throws a reference error. If the function is placed outside 'crearLoginWindow' it will work.
Being these two lines the source of trouble:
Ext.ComponentQuery.query('#loginwindow > button[text="Conectar"]')[0].on('click', this.enviarLogin, this);
var enviarLogin = function(){
console.log('login')
}
I've tried different scope variants such as;
Ext.ComponentQuery.query('#loginwindow > button[text="Conectar"]')[0].on('click', this.crearLoginWindow.enviarLogin);
this.enviarLogin = function(){
console.log('login')
}
Which makes sense with what i think i understand about scope and the need to specify the place where the function resides to execute it.
Id appreciate a solution because this problem makes my code very messy!
Simply defining a function within another function doesn't attach it to any object or instance, so this.enviarLogin won't work. There are two basic options here:
Just define the inner function as you're doing (moving it up above your handler assignment), and reference it directly by name:
var enviarLogin = function(){
console.log('login')
};
Ext.ComponentQuery.query('#loginwindow > button[text="Conectar"]')[0]
.on('click', enviarLogin);
Define enviarLogin as a method, the same way you are defining crearLoginWindow:
Ext.define('...controller...', {
extend: 'Ext.app.Controller',
init: function() { ... },
crearLoginWindow: function(){
// ...
Ext.ComponentQuery.query('#loginwindow > button[text="Conectar"]')[0]
.on('click', this.enviarLogin, this);
},
enviarLogin: function(){
console.log('login')
}
});
The first version may be better if you don't need to reference enviarLogin outside of the crearLoginWindow method. The second is better if you do need to reference enviarLogin elsewhere, and it makes using this in enviarLogin clearer.

Categories