Initialize javascript Object literal property Dynamically - javascript

I wanted to define the input values from HTML page as javascript Literal object property but i am getting Undefined error on accessing in JS file.
Suppose i have a input value like as in HTML
<input type="hidden" id="someid" value="dbvalues in arrayform" >
Now this value i am trying to define like (A.js) as below:
var abc = {
x : $("#someid").val(),
y: function (){
console.log(this.x);
}
}
Now when in another JS file (B.js) i call it as
console.log(abc.x());
Any Solutions?

A.js
var abc;
$(function() {
abc = {
x: $("#someid").val(),
y: function (){
console.log(this.x);
}
}
});
B.js
$(function() {
abc.y();
});
Note that $("#someid").val() will return a string, so you may need to convert into into an array.

x is not function, it is string.
You should call it as:
console.log(abc.x);

two things - first of all it would not be console.log(abc.x()); x() is how you call a function, you could call abc.y(); though since it's a function.
the other thing is that jQuery must be loaded, and that this code defining var abc = { has to be executed after the DOM is fully loaded
I think you want this:
$(function(){ // this ensures DOM is ready, careful about where you want to call abc from though;
var abc = {
var me = this;
x : function(){ return $("#someid").val()},
y: function (){
console.log(me.x); // try this instead it will help with 'this' confusion
}
}
});
now you can call
console.log(abc.x());

Related

How to get current object reference inside a jquery callback function?

I have a javascript Object called aObject and a fucntion inside it is used as a jQuery Callback function like this:
var aObject = {
aVariable : 'whatever value',
test : function(e) {
// Trying to access property. But doesn't work as expected since I am getting the DOM element i.e form, not the aObject reference
var temp = this.aVariable;
}
}
$('document').ready(function(){
$('#some-html-form').submit(aObject.test);
});
When I call the test method in aObject, this refers to the form element that has been submitted. I want to access current object from the test callback function?
I tried the below code as described in this answer but it did not work for me
$(document).ready(function() {
$('#add_api_form').submit(api_cahce.handle_add_form_submit.bind(this));
});
bind with aObject then you can access the variable.
var aObject = {
aVariable : 'whatever value',
test : function(e) {
var temp = this.aVariable;
}
}
$('document').ready(function(){
$('#some-html-form').submit(aObject.test.bind(aObject));
});

Pass a callback function as a html data attribute

I have created a DOM structure like this
<div data-execute="someFunction.abc" id="someId">
</div>
I am able to retrive the attribute in js but I intend to execute this as a callback function. So I am doing like this
var x = document.getElementById("someId").getAttribute('data-execute');
As expected this is returning someFunction.abc .But on consoling typeof(x) it is showing "string".Please refer to this fiddle
var someFunction = function() {
alert("Hello")
}
var load = (function(module, global) {
var x = document.getElementById("someId").getAttribute('data-execute');
console.log(typeof(x))
}(load || {}, this))
<div data-execute="someFunction.abc" id="someId">
Some Function
</div>
I also checked this link
Passing a Javascript function through inline data- attributes
But no way I am able to execute it as a call back function.Any help will be truly appreciable.
Try this:
<div data-execute="someFunction.abc" id="someId"></div>
var x = document.getElementById("someId").getAttribute('data-execute');
window[x].call();
You can use the call methodon the function defined in the global scope, you can access it in the global window ojbect.
Ref:
The call() method calls a function with a given this value and
arguments provided individually.
I have assumed the code after the point is a paramter to pass to the function.
Code:
var someFunction = function (p) {
alert(p)
}
var load = (function (module, global) {
var x = document.getElementById("someId").getAttribute('data-execute');
window[x.split('.')[0]].call(undefined, x.split('.')[1]);
}(load || {}, this))
Demo: https://jsfiddle.net/IrvinDominin/5bjsmu3x/

jQuery plugin instance variables

I'm beginning with jQuery plugins, apologies for the newbie question. My objective is to have a single plugin instantiated twice, where each instance has its own variables values. However, they seem to share the namespace.
For example, given the following plugin:
(function ( $ ) {
var x = false;
$.fn.test = function() {
alert(x);
if ( !x )
x = true;
return this;
};
}( jQuery ));
that is invoked from the following divs:
$( "div1" ).test();
$( "div2" ).test();
The alert displays first false, then true, when the objective is to have to sets of variables where the alert would display false twice.
is this possible?
There is some confusion in your question. Your plugin is a simple function. You don't "instantiate" a function by calling it. So you don't "instantiate" your plugin either.
You can instantiate things in your function, and persist them somewhere.
Since the outer scope runs only once, in your original solution you only get one instance of variable x.
If you create it inside the function, a new instance gets created every time you call it.
I assume you want to create an instance for every element you call this plugin on. A good solution would be to attach your data to the DOM element you initiate your plugin on, like:
(function ( $ ) {
$.fn.test = function() {
var vars = this.data('testPlugin');
if (!vars) {
vars = {
x: false,
something: 'else'
};
this.data('testPlugin', vars);
}
alert(vars.x);
vars.x = !vars.x;
return this;
};
}( jQuery ));
Try this fiddle.
You should put
var x = false;
inside $.fn.test function, otherwise the x variable is the same for all test() functions, and set to true after first call.
You can read more here about javascript variable scoping.
Actually, this is much easier than the previous answers. The context of this in your plugin is the jQuery object for the DOM element you're receiving based on the selector you provided. To gain uniqueness, simply iterate over each element, like so:
(function($) {
$.fn.test = function() {
return this.each(function() {
var x = false;
alert(x);
if (!x) {
x = true;
}
});
}
}(jQuery));
$("div1").test(); //false
$("div2").test(); // false
Here's a JSFiddle to confirm: http://jsfiddle.net/Z6j7f/

Javascript convert string to be called as function

I have the following scenario where I need to call a function based on the data attributes of the html element.
function func1(arg1){
alert("func1");
}
function func2(arg2){
alert("func2");
}
jQuery(document).on('click', '.func-class', function(){
var funcName = jQuery(this).data('func-name');
var funcArg = jQuery(this).data('func-arg');
//Need to call funcName(funcArg) here
});
HTML:
<div data-func-name="func1" data-func-arg="arg1" class="func-class">Func1</div>
<div data-func-name="func2" data-func-arg="arg2" class="func-class">Func2</div>
JSFiddle of the same:
http://jsfiddle.net/E4HeT/
If those functions are defined in ths global scope, you can do this:
window[funcName](funcArg);
Otherwise, I would suggest putting them in an object like so:
var functions = {
"func1":func1,
"func2":func2
};
functions[funcName](funcArg);
This second one is actually safer, as it helps prevent arbitrary code execution.
you can do like the following this
window[funcName](funcArg)
but you will have to get the reference of the function by setting it in a object for example (like what i did in the window object) because its private in the jQuery.ready function
$('.func-class').click(function(){
var toCallArg = $(this).data('func-arg');
var toCall = function(toCallArg){
//your code
};
toCall(toCallArg);
});

Javascript Class Inheritance

Can anyone tell me why my 'showDiv_boo' is undefined inside the class´s method?
I also can´t access my class´s methods.
Here´s my class 'Blink' class with its properties and methods:
function Blink(div) {
this.div = div
}
Blink.prototype.counter = 0
Blink.prototype.showDiv_boo = true
Blink.prototype.showDiv = function() {
this.div.style.visibility = 'visible'
}
Blink.prototype.hideDiv = function() {
this.div.style.visibility = 'hidden'
}
Blink.prototype.startEngine = function() {
if (this.showDiv_boo) {
this.showDiv()
} else if (!this.showDiv_boo) {
this.hideDiv()
}
this.showDiv_boo = !this.showDiv_boo
this.counter++
}
Blink.prototype.startEffect = function() {
this.idEffect = setInterval(this.startEngine, 1000 / 45)
}
So, if I create:
_blink = new Blink(myDiv);
_blink.startEffect();
You can test... the variable 'showDiv_boo', is undefined inside the method.
Even, if I set the showDiv_boo inside the method to true, it won´t call my class´s methods showDiv or hideDiv.
Anyone?
Thanks :)
The reason why is that startEngine is called from setInterval. The way in which this callback is invoked causes startEngine to have a different value for this than startEffect. You need to save this in order to maintain it in the callback. For example.
Blink.prototype.startEffect = function () {
var self = this;
self.idEffect = setInterval(function () { self.startEngine(); }, 1000 / 45);
};
You need to:
use var self and call the method via self.startEngine()
use an anonymous function to wrap the call in [1] i.e. function(){ self.startEngine(); }
This is because when you just pass this.startEngine or self.startEngine you are just passing the function startEngine without specifying what this is, which in both cases is supplied by the global conext of DOMWindow.
To give an example...
function startEngine() {
...code omitted...
};
Blink.prototype.startEngine = startEngine;
Blink.prototype.start = function() {
setTimeout(startEngine, 0); // obviously wrong, what is this?
setTimeout(Blink.startEngine, 0); // actually the same as line above, although not as obvious
setTimeout(startEngine.bind(this), 0); // works correctly
}
works to add code to the prototype and if used in the anonymous function will work as expected, but if you just use Blink.startEngine as the callback it is exactly the same as using startEngine only the second is more obviously wrong because there's no object it is being called on so you'd expect this to be whatever is supplied by the context.
The other way you could do this without using the anonymous function would be
Blink.startEngine.bind(self)
Which returns a function that will call startEngine with the correct this same as explicitly creating the anonymous function and wrapping the call to self.startEngine()
Heres a link to a fiddle to play around with the differences: http://jsfiddle.net/bonza_labs/MdeTF/
If you do the following, you will find it is defined
var x = new Blink('hello');
x.showDiv_boo
Javascript uses prototypical inheritance. While showDiv_boo may not be explicitly defined within the instance of Blink that you now have, it does exist within the prototype that Blink inherits from. When you try referencing showDiv_boo from within the object, the Javascript engine realizes the object does not own a member by that name and then will check its prototype.
Along with setting a temporal variable to store this, you must call the startEngine() function with that variable:
Blink.prototype.startEffect = function(){
var self = this;
self.idEffect = setInterval(function(){ self.startEngine.call(self); }, 1000/45);
}
Note the .call(self), which basically calls the function with the variable self, so the variable this in startEngine will be the correct one.

Categories