Function stored to a variable not running when called - javascript

I'm working on a plugin for Trumbowyg where I'm trying to store a function in a variable so it can be called later but also be over-writable without altering the included javascript file.
The problem is, the function is not being called when I try to call it.
Here is my relevant code:
init: function (trumbowyg) {
var plugins = trumbowyg.o.plugins;
...
if(!plugins.giphycrumbs.close_modal) {
plugins.giphycrumbs.close_modal = function() {
console.log('close modal');
$(plugins.giphycrumbs.modal_selector).modal('hide');
}
}
$(document).on('click', '.add_giphy', function() {
trumbowyg.execCmd('insertImage', $(this).attr('src'), false, true);
plugins.giphycrumbs.close_modal;
});
// If the plugin is a button
trumbowyg.addBtnDef('giphycrumbs', {
//this function is handled exactly the same way except it actually works
fn: plugins.giphycrumbs.open_modal
});
}
In my code above, you can see I am checking if plugins.giphycrumbs.close_modal is NOT set, and if thats true, I set it to a function which is supposed to close a modal.
In my click handler for .add_giphy, the insertImage code works, but plugins.giphycrumbs.close_modal is never executed (I don't get the console.log message embedded in the function)
If I do console.log(plugins.giphycrumbs.close_modal) the expected function is put into the console.
Why is the close_modal function not executed in my code?

Answer
Try adding parentheses to close_modal inside your click handler.
Explanation
It seems to me like you are not invoking (calling) this function.
In your click handler, there's this line plugins.giphycrumbs.close_modal;
In javascript, this is a reference to a property on the giphycrumbs object. Though it happens to be a function, it will not be invoked as such unless you use parentheses after it (and optionally give it some arguments).
Hope that helps! 👍

Related

Passing value into function and variable scope in JQuery

Link to code example:
http://jsfiddle.net/99Shr/
This code works for a given click handler, and $(this) takes on the particular class.
I am attempting to take the code that is inside the click function and put it into it's own function. The reason I want to do this is because I would like to replace quantity-- with quantity++ depending on which click handler is called. The issue I am running into is that the variables when called in the function are undefined since $(this) is window.
I am well aware that I may be doing this wrong to achieve what I want and am open to learning a better way to achieve it.
function price(change) {
return change;
}
$('.cart-item-decrease').click(function(){
price('quantity--');
});
or
$('.cart-item-increase').click(function(){
price('quantity++');
});
You can customise the event handler registration so that additional data gets sent to your function:
function myClickHandler(e)
{
// ...
quantity += e.data.increment;
// ...
}
$('.cart-item-increase').on('click', null, {
increment: 1
}, myClickHandler);
$('.cart-item-decrease').on('click', null, {
increment: -1
}, myClickHandler);
Here, the increment property gets sent to myClickHandler as e.data.increment.

Recognising variables while assigning a function to a variable in javascript

In my jQuery scripts, when the user closes a menu with an animation, I have to call a function after the closing animation is finished. I want to assign this function dynamically by calling a function openStrip() with a parameter. My code looks like:
var FUNCTION_JUST_AFTER_MENU_CLOSE = function(){};
function openStrip(stripId){
FUNCTION_JUST_AFTER_MENU_CLOSE = function(){
createStrip(stripId);
});
}
if I call openStrip("aStripId"), I expect FUNCTION_JUST_AFTER_MENU_CLOSE to be:
// #1
function(){
createStrip("aStripId");
}
whereas my current code gives:
//#2
function(){
createStrip(stripId);
}
i.e, the parameter passed to the function openStrip() is lost while assigning the function() to the variable FUNCTION_JUST_AFTER_MENU_CLOSE.
How can I avoid this.
EDIT: I discovered that my code is actually working. The problem was elsewhere. I got confused because when I looked at Chrome's debugger, it was showing me the function definition as is (#2 in above). But when it actually went down executing that function later in the code, it did evaluate the values of the passed argument, and endedup executing #1.
Thanks for the answer though. I am marking it correct because that is perhaps a better way of assigning the function.
The best way is to return a function, from openStrip like this
function openStrip(stripId) {
return function() {
createStrip(stripId);
};
}
For example,
function openStrip(stripId) {
return function() {
console.log(stripId);
};
}
openStrip("aStripId")();
# aStripId
openStrip("bStripId")();
# bStripId
You can even assign the function objects returned to different variables and use them later on
var aStrip = openStrip("aStripId");
aStrip();
# aStripId
aStrip();
# aStripId

My $.extend does not seem to work when inside a function in javascript

I have the following code:
File 1:
$(document).ready(function () {
addDataTableExts();
}
File 2:
function addDataTableExts() {
$.extend($.fn.dataTableExt.oStdClasses, {
sWrapper: 'no-margin last-child'
}
}
This seems to work okay. I now tried to replace this with the following:
File 2:
(function () {
$.extend($.fn.dataTableExt.oStdClasses, {
sWrapper: 'no-margin last-child'
}
}
This doesn't work.
Is there some reason why it only seems to work if I do this the first way? I thought
that by changing the first line of File 2 then it would cause the code to get
executed without me calling it.
You changed the code from running in the ready event to running immediately. It seems that you are loading your datatable plugin after loading file 2, so the plugin doesn't exist yet when you try to use it.
If you put it back in the ready event, it should work:
File 2:
$(document).ready(function () {
$.extend($.fn.dataTableExt.oStdClasses, {
sWrapper: 'no-margin last-child'
}
});
Note: Events in jQuery are not exclusive, so you can have several ready event handlers in the same page without problems.
"I thought that by changing the first line of File 2 then it would cause the code to get executed without me calling it."
If you actually changed only the first line as shown then you've created a syntax error - you've added an opening ( without a closing ). But simply adding the closing ) won't cause the now anonymous function expression to be executed. If you want the code to get executed without being called from File 1 you need to add extra parentheses () on the end to actually invoke the function.
Also you had a missing closing ) after the } at the end of $.extend(..., though that was also a problem in the first version of your code (and also a problem with the document ready handler in File 1).
(function () {
$.extend($.fn.dataTableExt.oStdClasses, {
sWrapper: 'no-margin last-child'
}); // <-- add missing ); here
})(); // <-- add missing )(); here
But you don't need the containing function at all unless it also wraps other code that you don't show, because that $.extend() statement on its on doesn't have any deleterious effect on the global scope.
Finally, if you do need to run that $.extend() after the page is ready but don't want to have a dependency between your two files you can add a document ready handler directly in File 2. Multiple document ready handlers will all be executed.

Why is function() needed sometimes in JavaScript?

HTML
<button id='hello'>Click Me!</button>
JavaScript (wrong)
$('#hello').click(alert('Hello, World!'));
JavaScript (correct)
$('#hello').click(function() {
alert('Hello, World!');
}
I'm wondering why the first JS code triggers on the event load instead of click. Can anyone tell me why function() { [code] } is needed for the script to work properly?
In this example, I used jQuery events, but this is not specific to it, for example, I need to use it with setTimeout, too.
The click function expects another function as a parameter.
In the first case you would be passing the result of calling alert('hello world');, which is null.
The second is just a shorthand for:
$('#hello').click(callback);
function callback(){
alert('hello world');
}
Because .click() is a handler. The first argument is a function to assign. But if you actually pass the function with arguments then it will call the function (in this case alert) and then pass it's return value.
Writing $('#hello).click( function() { } )` is basically a short hand for writing:
var myfunction = function() {
// code
};
$('#hello').click( myfunction );
As you can see in the long hand way, it's passed as a reference to the function instead of the function's return value.
Your first example says "evaluate
alert('Hello, World!')
right now, and pass the result as an argument to click. "
The second says "Define a function which will do the alert when I call it, and pass that whole function as an argument to click.
The function() { ... } syntax is how you declare an anonymous function in Javascript. jQuery uses lots of these to specify that some action will be performed later, like when an event occurs. You can think of it as delaying the execution of your function until necessary. Without this syntax, whatever code you place there is evaluated immediately, which is not what you want for an event handler.
You might think, "why isn't JavaScript smart enough to know the difference?" Consider this:
function returnCallback(linkId, data) {
return function(e) {
alert('Clicked on ' + linkId + '. Here is some data: ' + data);
// Maybe do some stuff with e, the event parameter
}
}
$('#some-link').click(returnCallback('some-link', 'some-data'));
$('#other-link').click(returnCallback('other-link', 'different-data'));
This is a contrived example, but it illustrates the power of anonymous functions and closures. This works since returnCallback returns a function.
In the first instance, "JavaScript wrong", you're actually calling alert('Hello, World!') at the point that the script is loaded. Now, the reason you pass the .click function a function is because it can call it at any point. Essentially, you're packing code together to be run (or not run at all) at any point when you put it in a function.
$('#hello').click(alert('Hello, World!')); is attempting to run alert('...') and pass its return value to the .click() function which will not work as expected.
This is because JavaScript evaluates everything and during this process your alert is invoked. You can use anonymous function or you can also use your own custom function as implemented below:
<script language="javascript" type="text/javascript">
$("#mybutton").click(clickFired);
function clickFired() {
alert('click fired');
}
</script>
The parameter required for the .click() function is a Function. Therefore $("#hello").click(function { [code] }); is required. Because there's nothing to return by alert().
The click function here assigns a value to the event handler.
With the first ("wrong") code you're assigning a value of alert('Hello, World!') which is itself a function call, so it's going to be immediately evaluated and hence appear at load.
With the second ("correct") code you're now assigning a new anonymous function which is not executed itself, just instantiated at load. Hence this will work as expected later.
somefunction(alert('hello! world'));
this would mean you want to pass to somefunction the return value of alert("hello! world").
jquery click expects a callback that it should fire upon click on the element. so you put it in a function which does not execute unless someone (here jquery) calls it explicitly.

Drupal Form can't access javascript function (errors "not a function")

using drupal with lightbox2 to open a form. this form is from a custom module.
the module has a setting: 'onsubmit' => 'return form_submission(this);' and that appears to be working correctly.
I've included the functions.js in the theme.info file and it's showing up, i can open that file and see the function.
for some reason, i keep getting "form_submission not a function" when i do submit the form.
if(Drupal.jsEnabled)
{
$(document).ready(function() {
// Call back function for AJAX call
var form_submission = function(responseText) {
alert (responseText);
}
// preventing entire page from reloading
return false;
});
}
Your form_submission function is local to the anonymous function it's inside (ie the document ready function).
You need to declare the function in a global scope, outside of the document ready. You at least need to declare the variable form_submission. You will then be able to attach the function on to it wherever you wish.
form_submission has to be a defined function.
function form_submission(data) {
// action code
}
or also try
var form_submission = new function(data) {
// action code
}
Not that this is the perfect answer, but I removed the function from within the document.ready jquery wrapper and it picked up on it.

Categories