I'm going to show you two snippets.
This works fine:
this.searchBox = new Foo.UI.SearchBox(this.input, {
autoCompleteSearchComplete: processSearchResults
});
This doesn't work at all:
this.searchBox = new Foo.UI.SearchBox(this.input, {
autoCompleteSearchComplete: function() {
processSearchResults
}
});
I need to place that processSearchResults call inside an if statement, to check if my search text input ($('.search')) has any text written inside it.
My first idea was to use this function type notation, but it's not working. It's as if the call to processSearchResults is never made at all.
Any suggestions?
That's because you do not actually call that function. This would be correct:
this.searchBox = new Foo.UI.SearchBox(this.input, {
autoCompleteSearchComplete: function() {
if (...) {
processSearchResults();
}
}
});
Related
I can't figure out how to use a Javascript constructor method in a jQuery .click method. I'm trying to get a button's function to change dynamically based on a constructor. Here's the set up:
<button onclick="">
</button>
needs to call a method that changes depending on another button. The following is my broken code:
function GloveMode (name , array) {
this.colorArray = array;
this.displaySettings = function(){
//Title
$("#displayTitle").text(this.name);
//Display Color Set
$("#displayColors").empty();
//Totally Broken
$("#upArrow").click( function(){
addColor();
});
};
this.addColor = function(){
console.log(this.colorArray.length);
};
};
I can't figure out how to get $("#upArrow").click() to call this.colorArray properly, or how to call this.addColor() in the .click() method! Please help.
Your Problem is that "this" means something different in each function body. So save the wanted "this" to a variable e.g. "self" and use that.
function GloveMode (name , array)
{
var self = this;
this.colorArray = array;
this.displaySettings = function()
{
//Title
$("#displayTitle").text(this.name);
//Display Color Set
$("#displayColors").empty();
//Totally Broken
$("#upArrow").click( function()
{
self.addColor();
});
};
this.addColor = function()
{
console.log(self.colorArray.length);
};
};
I've got some code in JavaScript and I'm looking to trigger a ViewModel method using a keyboard shortcut. What is the correct syntax? Here's my code:
document.addEventListener('keydown', function(event) {
if (event.keyCode==27){
ViewModel.escapePressed();
}
}, true);
function ViewModel() {
this.escapePressed=function(){
// Code
};
}
If you are going to use that style of class, then you must first make an instance of it.
var a_view_model = new ViewModel();
a_view_model.escapePressed();
… but if you just want to have a static method, then you probably shouldn't be using a constructor function in the first place
var view_model = {
escapePressed: function () { };
}
and:
view_mode.escapePressed();
From within my webpage I am creating an object and trying to call a dynamically set function from within it. The dynamic function however, isn't being executed.
Here is a subset of the Object:
var LightBoxLogin = {
DialogBox: null,
SuccessFunction: null,
..........
Login: function(){
console.log(LightBoxLogin.SuccessFunction) // Displays "TestSubmit()"
LightBoxLogin.SuccessFunction(); // does nothing, should alert the page
}
}
LightBoxLogin.SuccessFunction is set with:
function SuperLightbox(functOnSuccess)
{
LightBoxLogin.SuccessFunction = functOnSuccess;
if(IsLightboxNeeded())
{
LightBoxLogin.Login();
}
else{
alert("Not needed");
}
}
And called like:
function TestSubmitHandler ()
{
SuperLightbox(TestSubmit);
}
function TestSubmit ()
{
alert('TEST SUBMIT ALL CAPS');
}
Let me know if im missing anything.
I just need to execute the function passed as a parameter initially.
Instead of the line
SuperLightBox(TestSubmit);
Use the function name as a String instead:
SuperLightBox("TestSubmit");
This means in the Login:function() this line:
LightBoxLogin.SuccessFunction();
Will be replaced with:
window[LightBoxLogin.SuccessFunction]();
This yields the results I was looking for, but beware; it only works if the desired function is accessible globally in the page.
JSFiddle: http://jsfiddle.net/M2ALY/3/
My goal is to make a module that I can use and distribute. Therefore I must not pollute the global namespace. The module I'm making is also going to be used multiple times on one web page. That's why I chose to use OOP, but this introduced a problem.
I want my object to bind a function to be run when the user clicks an element in the DOM. In this simplified example I made, I want an alert box to pop up when the user clicks a paragraph. As an example, one of the things I need in the real project I'm working on is: The user clicks a canvas, the function figures out where the user clicked and saves it to this.clientX and this.clientY.
Instead of doing
this.bind = function() {
$("p1").bind('click', function() {
// code here
});
}
I figured it would work if I did:
this.bind = function() {obj.codeMovedToThisMethod()}
The problem is that this isn't a good design. Inside the "class" you shouldn't need to know the name of the object(s) that is going to be made of this "class". This doesn't get better when I'm making multiple objects of the "class"...
So I figured I could do
$("p1").bind('click', function(this) {
// code here
});
}
But it didn't work because sending this into the function didn't work as I thought.
How should I solve this problem?
Here is a simplified sample problem. (Same as JSFiddle.)
var test = function() {
this.alert = function() {
alert("Hi");
}
this.bind = function() {
$("#p1").bind('click', function() {
obj.alert();
});
}
}
window.obj = new test();
obj.bind();
// What if I want to do this:
var test2 = function() {
// Private vars
this.variable = "This secret is hidden.";
this.alert = function() {
alert(this.variable);
}
this.bind = function() {
$("#p2").bind('click', function(this) {
obj2.alert();
this.alert();
});
}
}
window.obj2 = new test2();
obj2.bind();
Thanks!
Read MDN's introduction to the this keyword. As it's a keyword, you can't use it as a parameter name.
Use either
this.bind = function() {
var that = this;
$("#p2").on('click', function(e) {
that.alert();
// "this" is the DOM element (event target)
});
}
or $.proxy, the jQuery cross-browser equivalent to the bind() function:
this.bind = function() {
$("#p2").on('click', $.proxy(function(e) {
this.alert();
}, this));
}
I seem to have an issue when creating copies of a template and tying the .click() method to them properly. Take the following javascript for example:
function TestMethod() {
var test = Array();
test[0] = 0;
test[1] = 1;
test[2] = 2;
// Insert link into the page
$("#test_div").html("<br>");
var list;
for (x = 0; x < test.length; x++) {
var temp = $("#test_div").clone();
temp.find('a').html("Item #" + test[x]);
temp.click(function () { alert(x); });
if (list == undefined)
list = temp;
else
list = list.append(temp.contents());
}
$("#test_div2").append(list);
}
The problem I am seeing with this is that no matter which item the user clicks on, it always runs alert(2), even when you click on the first few items.
How can I get this to work?
Edit: I have made a very simple example that should show the problem much clearer. No matter what item you click on, it always shows an alert box with the number 2 on it.
Correct me if I'm wrong, .valueOf() in JS returns the primitive value of a Boolean object.....
this would not happen ShowObject(5,'T');... ShowObject(objectVal.valueOf(), 'T');
why not use objects[x].Value directly? ShowObject(objects[x].Value, 'T');
WOOOOOSSSHHHH!
after searching deeply... I found a solution...
because it's a closure, it won't really work that way...
here's a solution,
temp.find('a').bind('click', {testVal: x},function (e) {
alert(e.data.testVal);
return false;
});
for best explanation, please read this... in the middle part of the page where it says Passing Event Data a quick demo of above code
I think your issue arises from a misunderstanding of scopes in JavaScript. (My apologies if I'm wrong.)
function () {
for (...) {
var foo = ...;
$('<div>').click(function () { alert(foo); }).appendTo(...);
}
}
In JavaScript, only functions create a new scope (commonly referred to as a closure).
So, every round of the for loop will know the same foo, since its scope is the function, not the for. This also applies to the events being defined. By the end of looping, every click will know the same foo and know it to be the last value it was assigned.
To get around this, either create an inner closure with an immediately-executing, anonymous function:
function () {
for (...) {
(function (foo) {
$('<div>').click(function () { alert(foo); }).appendTo(...);
})(...);
}
}
Or, using a callback-based function, such as jQuery.each:
function () {
$.each(..., function (i, foo) {
$('<div>').click(function () { alert(foo); }).appendTo(...);
});
}
For your issue, I'd go with the latter (note the changes of objects[x] to just object):
var list;
jQuery.each(data.objects, function (x, object) {
// Clone the object list item template
var item = $("#object_item_list_template").clone();
// Setup the click action and inner text for the link tag in the template
var objectVal = object.Value;
item.find('a').click(function () { ShowObject(objectVal.valueOf(), 'T'); }).html(object.Text);
// add the html to the list
if (list == undefined)
list = item;
else
list.append(item.contents());
});