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 "}" :-)
Related
$("#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')
})
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 want to test this function:
/js/lib/front.js
var Front = function(){
this.onSignUp = function(){
if (!Form.assertInput("email")) {
$("input[name=email]").focus();
this.showHiddenMessage("Email not set.");
return false;
}
}
}
I have in:
/js/lib/form.js
function Form() {
this.assertInput = function (name, defaultValue) {
var text = $("input[name=" + name + "]").val();
if (defaultValue != null) {
if (defaultValue && text == defaultValue)
return false;
}
if(this.trim(text)) return true;
return false;
}
}
This simple test passing:
test("Front", function() {
var front = new Front()
ok(front);
});
But if I write something like this:
test("On Sign Up ", function() {
var front = new Front()
equal(front.onSignUp(),false,"passing test");
});
I have error:
Died on test #1: Form.assertInput is not a function
I don't understand, what I need test in function like this and how include function inside another function?
I've saved a working fiddle here. As a side note, you might want to check out a tutorial on using qUnit, here.One thing that you need to pay attention to is when you're declaring your functions. It's saying Form.assertInput is not a function because you can't access it like that. You need to use the this keyword, which refers to current context. The code should be something like this:
var Form = function () {
//good to have assertInput first if you're using it in a later function
this.assertInput = function (name, defaultValue) {
var text = $("input[name=" + name + "]").val();
if (defaultValue != null) {
//safer to explicitly close your if statements with {}
if (defaultValue && text == defaultValue) {
return false;
}
}
if ($.trim(text)) { return true; }
return false;
};
this.showHiddenMessage = function (message) {
alert(message);
};
this.onSignUp = function() {
//this will point to the current context, in this case it will be Form class
if (!this.assertInput("email")) {
$("input[name=email]").focus();
this.showHiddenMessage("Email not set.");
return false;
}
};
};
Also in the example code that you gave you're missing the Front class. So I created a dummy one in my fiddle like this:
var Front = function() {};
Here are the tests that were run:
$(document).ready(function() {
test("Front", function() {
var front = new Front();
ok(front);
});
test("On Sign Up ", function() {
var form = new Form();
equal(form.onSignUp(), false, "passing test");
});
});
In the following code, I want to be able to call bindClickEvents() like so:
App.Utils.Modal.bindClickEvents();
However, I don't understand the syntax necessary to do this.
Current code:
var App = new Object;
App.Modal = {
bindClickEvents: function() {
return $('a.alert-modal').click(function(e) {
return console.log('Alert Callback');
});
}
};
$(document).ready(function() {
return App.Modal.bindClickEvents();
});
You can do it in one go:
var App = {
Modal : {
bindClickEvents : function () {/* ... */}
}
}
or if you want to break that up to separate steps:
var App = {};
App.Modal = {};
Modal.bindClickEvents = function () {/* ... */};
BTW, in reference to your original question title, this is not object chaining. This is object composition. Object chaining is being able to call methods in an object multiple times in a single statement.
Is this what you're trying to do?
var App = {};
App.Utils = {};
App.Utils.Modal = {
bindClickEvents: function() {
return $('a.alert-modal').click(function(e) {
return console.log('Alert Callback');
});
}
};
$(document).ready(function() {
return App.Utils.Modal.bindClickEvents();
});
Prefer the object literal syntax to the Object constructor; some authors go so far as to call the latter an anti-pattern
Here's the simplest way to set up App.Utils.Modal.bindClickEvents();
var App = {
Utils: {
Modal: {
bindClickEvents: function() {
return $('a.alert-modal').click(function(e) {
return console.log('Alert Callback');
});
}
}
}
};
Or you can piece it together one step at a time:
var App = {};
App.Utils = {};
App.Utils.Modal = {};
App.Utils.Modal.bindClickEvents = function() {
return $('a.alert-modal').click(function(e) {
return console.log('Alert Callback');
});
};
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); });
});