$("#foo").on("click", function() {
amountItems.speek('heey')
})
var amountItems = (function(el) {
// var el = el;
return {
speek: function() {
alert(el)
}
}
}())
This is my first attempt to using a module pattern. basically when foo get's clicked i want the speek method inside the amountItems function to be called and I want to pass the string 'heey' to the method so it should alert 'heey' when foo is clicked. originally i wanted to pass something like $("#foo").text() but either way I get 'undefined'.
can you show me how to work with a jQuery object when it's passed into this type of function?
You just have the parameter for el in the wrong place. This works:
$("#foo").on("click", function() {
amountItems.speek('heey')
})
var amountItems = (function() {
return {
speek: function(el) {
alert(el);
}
}
}())
--edit--
Just in case you were wondering how the whole scope / private variables thing works:
$("#foo").on("click", function() {
amountItems.load('heey');
amountItems.speek();
})
var amountItems = (function() {
var el = ""
return {
load: function(str) {
el = str;
},
speek: function() {
alert(el);
}
}
}())
When you do this:
var amountItems = (function(el) {
// var el = el;
return {
speek: function() {
alert(el)
}
}
}())
You execute a wrapper function and assign amountItems with the inner object.
You don't pass a param(el) when you invoke this and therefore el is undefined.
amountItems is an object with a method called speek that doesn't except params.
The right way to do this is:
var amountItems = {
speek: function(txt) {
alert(txt);
}
};
$("#foo").on("click", function() {
amountItems.speek('heey')
})
Related
I am trying to return an object method on the event jQuery.change() of a text field,
here is the code:
var Utente = function(indice){
this.Indice = indice;
this.Dati = new Array();
this.initialize = function() {
this.Dati['stato_civile'] = this.getField('stato_civile').val();
this.onChange('stato_civile',this.checkObbligatorieta);
}
this.getField = function(name) {
return $('#'+indice+name);
}
this.onChange = function(field, func) {
this.getField(field).live('change',function() {
return func.apply();
});
}
this.checkObbligatorieta = function() {
this.Dati['stato_civile'] = this.getField('stato_civile').val();
[...]
}
this.initialize();
}
Using this I get the field "#stato_civile" returns the function this.checkObbligatorieta correctly but it gives me an error:
** this.getField('stato_civile').val() is not a function
I think it's something strictly related with the scope, but I can't figure it out.
That's because you're not invoking func() in the same context as the caller, so this is not bound to the same object.
You can fix the problem by passing this to apply():
this.onChange = function(field, func) {
this.getField(field).live("change", function() {
return func.apply(this);
});
};
I have written some javascript that I would to encapsulate in a closure so I can use it elsewhere. I would like do do this similar to the way jQuery has done it. I would like to be able to pass in an id to my closure and invoke some functions on it, while setting some options. Similar to this:
<script type="text/javascript">
_snr("#canvas").draw({
imageSrc : someImage.png
});
</script>
I have read a lot of different posts on how to use a closure to do this but am still struggling with the concept. Here is where I left off:
_snr = {};
(function (_snr) {
function merge(root){
for ( var i = 1; i < arguments.length; i++ )
for ( var key in arguments[i] )
root[key] = arguments[i][key];
return root;
}
_snr.draw = function (options) {
var defaults = {
canvasId : 'canvas',
imageSrc : 'images/someimage.png'
}
var options = merge(defaults, options)
return this.each(function() {
//More functions here
});
};
_snr.erase = function () {};
})(_snr);
When ever I try to call the draw function like the first code section above, I get the following error, '_snr is not a function'. Where am I going wrong here?
EDIT
Here is what I ended up doing:
function _snr(id) {
// About object is returned if there is no 'id' parameter
var about = {
Version: 0.2,
Author: "ferics2",
Created: "Summer 2011",
Updated: "3 September 2012"
};
if (id) {
if (window === this) {
return new _snr(id);
}
this.e = document.getElementById(id);
return this;
} else {
// No 'id' parameter was given, return the 'about' object
return about;
}
};
_snr.prototype = (function(){
var merge = function(root) {
for ( var i = 1; i < arguments.length; i++) {
for ( var key in arguments[i] ) {
root[key] = arguments[i][key];
}
}
return root;
};
return {
draw: function(options) {
var defaults = {
canvasId : 'canvas',
imageSrc : 'images/someimage.png'
};
options = merge(defaults, options);
return this;
},
erase: function() {
return this;
}
};
})();
I can now call:
<script type="text/javascript">
_snr("#canvas").draw({
imageSrc : someImage.png
});
</script>
Because you declared _snr as an object and not a function. Functions can have properties and methods, so there's various ways to achieve what you want, for example one of them would be say...
_snr = function(tag) {
this.tag = tag;
}
_snr.foo = function() {
//Code goes here
}
You can also pass the outer context into a closure to hide your variables from accidentally polluting the global namespace, so like...
(function(global) {
var _snr = function(tag) {
this.tag = tag;
}
_snr.foo = function() {
//Code goes here
}
//export the function to the window context:
global._snr = _snr;
})(window);
window._snr('#tag').foo('wat');
Happy coding.
Because your _snr is an object, not a function. You have to call it like this:
_snr.draw({
canvasId: '#canvas',
imageSrc: 'someImage.png'
});
When you do _snr('#canvas') that is a function call which is why you're getting that error. _snr is an object with some methods attached to it such as draw() and erase(). The reason jQuery is able to pass arguments into the $ is because they return the $ as a function object which is why we're able to pass it various selectors as arguments.
You are going wrong at the first line _snr = {}
It needs to be
_snr = function(){
selector = arguments[0]||false;
//snr init on dom object code
return _snrChild;
}
Im on a mobile phone but when im on a pc I will maybe fix the whole code c:
Here you have a snr object and that has erase and draw methods. What you intend to do is to write a _snr function which will get an id and return a wrapper object. That returned object should have erase and draw methods. so you can do
var returnedObject = _snr("my_id");
returnedObject.draw("image.png");
The code looks like this
function Scripts() {this.FindById = function (id) {
this.FindById.constructor.prototype.value = function () {
return document.getElementById(id).value;
}}}
var Control = new Scripts();
Now when i say Control.FindById("T1").value(). I am not able to get the textInput("T1")'s value.
It seems that your code is a bit more complicated then it should be ;-)
Personally I would write it this way (not tested):
function Scripts() {
this.findById = function(id) {
var el = document.getElementById(id);
return {
value: function() {
return el.value;
}
}
}
}
The findById() now closes over a node and returns an interface that can return its value.
Also, your idea sounds a lot like Singleton, so you wouldn't even need the extra Scripts constructor:
var Control = {
findById: function(id) {
var el = document.getElementById(id);
return {
value: function() {
return el.value;
}
}
}
}
Working example: http://jsfiddle.net/YYkD7/
Try this:
function Scripts() {this.FindById = function (id) {
this.FindById.constructor.prototype.value = function () {
return document.getElementById(id).value
}}}
You didn't close the last "}" :-)
Ok, just solved one problem where this refered to the wrong scope. Now I have another problem.
So I want to call a method that is inside a method. But I do not know how, check this source:
function someObj() {
var self = this;
this.someMethod1 = function() {
var elementBtn = document.getElementById('myBtn');
elementBtn.onclick = function() {
self.someMethod2.methodMethod();
//I want this.someMethod2.methodMethod() to be called
//...but I get an big error instead. Is it even possible?
//this.someMethod2() works fine.
};
};
this.someMethod2 = function() {
this.methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};
alert('NO, NOT THIS!');
};
}
Error msg:
Uncaught TypeError: Object function () { ...
With your code, someMethod2 would need to execute first for the function expression to be assigned. Even then, it would be assigned to the parent instance.
Bearing in mind that all functions are objects in JavaScript, this is what you want instead:
this.someMethod2 = function() {
alert('NO, NOT THIS!');
};
this.someMethod2.methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};
You are trying to use an object accessor on a function. If you want it to work in this way, you need to return an object literal from your call to the "outer" function.
this.someMethod2 = function() {
return {
methodMethod: function() {
alert('THIS IS THE ONE I WANTED!');
}
}
};
You can then chain the call. self.someMethod2().methodMethod();
While this is not directly possible, you can pass a "command" to the outer function to tell it to execute the inner function. But, are you sure this is what you really need? Perhaps you should use objects instead of functions here. But here's the "command" way:
this.someMethod2 = function(cmd) {
var methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};
if (cmd === "methodMethod") {
methodMethod();
return;
}
alert('NO, NOT THIS!');
};
function someObj() {
var self = this;
this.someMethod1 = function () {
var elementBtn = document.getElementById('myBtn');
elementBtn.onclick = function () {
self.someMethod2().methodMethod();
};
};
this.someMethod2 = function () {
this.methodMethod = function () {
alert('THIS IS THE ONE I WANTED!');
};
//return this for chain method.
return this;
};
}
trying
function someObj() {
var self = this;
this.someMethod1 = function() {
var elementBtn = document.getElementById('myBtn');
elementBtn.onclick = function() {
self.someMethod2().methodMethod();
};
this.someMethod2 = function() {
this.methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};
alert('NO, NOT THIS!');
return this;
};
}
Also if you use prototype then
function someObj() {
var self = this;
this.someMethod1 = function() {
var elementBtn = document.getElementById('myBtn');
elementBtn.onclick = function() {
self.someMethod2.methodMethod();//['methodMethod']();
};
};
this.someMethod2 = function() {
};
this.someMethod2.methodMethod = function() {
alert('THIS IS THE ONE I WANTED!');
};
};
But the method methodMethod is static
I have a json object retrieved from server in my $(document).ready(...); that has an string that I would like to resolve to a function also defined within $(document).ready(...); so, for example:
$(document).ready(function{
$.getJSON(/*blah*/,function(data){/*more blah*/});
function doAdd(left,right) {
return left+right;
}
function doSub(left,right) {
return left-right;
}
});
with json string:
{"doAdd":{"left":10,"right":20}}
One way I thought about was creating an associative array of the function before loading the json:
var assocArray=...;
assocArray['doAdd'] = doAdd;
assocArray['doSub'] = doSub;
Using eval or window[](); are no good as the function may not be called for some time, basically I want to link/resolve but not execute yet.
Change your JSON to
{method: "doAdd", parameters : {"left":10,"right":20}}
Then do
var method = eval(json.method);
// This doesn't call it. Just gets the pointer
Or (haven't tried this)
var method = this[json.method]
How about something like this?
$(function(){
// Function to be called at later date
var ressolvedFunc = null;
// Ajax call
$.getJSON(/*blah*/,function(data){
// Generate one function from another
ressolvedFunc = (function(data) {
var innerFunc;
var left = data.left;
var right = data.right;
// Detect action
for (action in data) {
if (action == "doAdd")
innerFunc = function() {
return left + right;
};
else
innerFunc = function() {
return left - right;
};
}
return innerFunc;
})(data);
});
});
The anonymous function returns fresh function, with the new values stored within the enclosure. This should allow you to call the function at later date with the data previously retrieved from the GET request.
Rich
try this:
var doX = (function() {
var
data = [],
getDo = function(action) {
for(var d in data) {
if (data[d][action]) {
return data[d];
}
}
return null;
};
return {
set: function(sdata) {
data.push(sdata);
},
doAdd: function() {
var add = getDo("doAdd");
if (!add)
return 0;
return add.doAdd.left + add.doAdd.right;
},
doSub: function() {
var sub = getDo("doSub");
if (!sub)
return 0;
return sub.doAdd.left + sub.doAdd.right;
}
};
})();
$(document).ready(function{
$.getJSON(/*blah*/,function(data){ doX.set(data); });
});