How can I use a javascript function globally in Drupal 7.
I have my javascript file set up like this and add it using drupal_add_js():
(function($) {
function add_if_country_is_not_usa() {
// Check what country it is
// Update text, image, etc.. of a block.
}
});
In my block WYSIWIG I added the following code (The reason I add it in the WYSIWIG is because I want it to update before the page is fully rendered):
<script type="text/javascript">
add_if_country_is_not_usa();
</script>
But I get the following error:
Uncaught ReferenceError: add_if_country_is_not_usa is not defined
(anonymous function)
I read about adding functions to Drupal behaviors but that happens on document ready. I want to run the function as soon as the block is shown.
Any ideas?
Either define in the global scope, or do like below:
(function($) {
function add_if_country_is_not_usa() {
// Check what country it is
// Update text, image, etc.. of a block.
}
// set as a property of the global object `window`
window.add_if_country_is_not_usa = add_if_country_is_not_usa;
});
Not sure if this is the best way but I ended up being able to get it work using a namespaces. I call myGlobalObject.add_if_country_is_not_usa() from my block and it works now.
var myGlobalObject = mySingleGlobalObject || { 'country': {} };
(function ($) {
myGlobalObject.country = '';
myGlobalObject.add_if_country_is_not_usa = function() {
// Check what country it is
// myGlobalObject.country = 'US';
}
})(jQuery);
Related
I have a page where i use jQuery to load some content into a div element
<div id="contents-box-in"></div>
jQuery code in page
$(document).ready(function() {
$("#contents-box-in").load("new-01.php", function() {
$('#contents-box-in').fadeIn(120);
});
var updateBoxData = function(data) {
$('#contents-box-in').fadeOut(100, function() {
$('#contents-box-in').html(data).fadeIn(130);
});
}
});
the content that i load is a form that needs to load a new page sending collected data from form
$('#form-buttons-next').click(function(e) {
var formData = new FormData($(this)[0]);
var formS = $.ajax({
url : 'new-02.php',
type : 'POST',
data : formData,
async : false,
cache : false,
processData : false,
contentType : false
});
formS.done(function(data) {
if (data != null) {
updateBoxData(data);
}
});
formS.fail(function(jqXHR, textStatus) {
alert("error");
});
});
since i do this in different step i would like to use a shared function contained in page that is loading the ajax content but i get updateBoxData is undefined
I guess that ajaxed content can't see parent container function
The easy way would be to load a different .js file containing shared function, i was wondering if is possible to access the updateBoxData from ajaxed contents
...i would like to use a shared function contained in page that is loading the ajax content but i get updateBoxData is undefined
I guess that ajaxed content can't see parent container function
No, that's not why. Your updateBoxData variable is scoped to the function it's declared in (your ready) callback. If you want it accessible globally, you'll need to make it global instead.
The problem is, though, the global namespace is already incredibly crowded. So if you put all of your useful functions there as globals, you're going to run into conflicts sooner or later.
For that reason, for now until browsers support ES2015 modules (which will take a while), I suggest giving yourself just one global symbol, something unlikely to conflict with other things, and assigning an object to it with properties for your various utility functions. E.g.:
var MyNiftyUtils = {
updateBoxData: function() {
// ...
}
};
Then you call that via MyNiftyUtils.updateBoxData. If the verbosity bothers you, no worries, just use a scoping function and assign it to a local:
(function() {
var u = MyNiftyUtils;
// ....
u.updateBoxData(/*...*/);
})();
(There are about 18 variations on that theme, this is just one of them.)
The function updateBoxData is defined inside a callback function you passed to .ready and hence its scope is limited to that function. Let us call this callback function Fx.
The click handler (the function passed to .click in the second part), which we call it Fy is defined outside of Fx and as a result does not have access to the variables defined in Fx (remember updateBoxData is a variable inside Fx).
That is why your code does not work. To get it working simply take updateBoxData out of the callback in .ready function:
$(document).ready(function() {
$("#contents-box-in").load("new-01.php", function() {
$('#contents-box-in').fadeIn(120);
});
});
function updateBoxData(data) {
$('#contents-box-in').fadeOut(100, function() {
$('#contents-box-in').html(data).fadeIn(130);
});
}
...
The rest is the same.
am just don't know what happened it was work correctly .... What's most reasons that led us to this error ????
I was trying to run my website locally then this error comes to me from I don't know so what is this error mean and how can I solve it
the error occurs in this code .... actually , its complete website and I'm a beginner with JS and SO so please help me
// disable class and attribute rules defined by jquery.validate
$.validator.classRules = function() {
return {};
};
$.validator.attributeRules = function() {
return {};
};
Your Code tries to access an non existing JQuery namespace. You are either missing some sort of JQuery plugin, or you need to create on your self.
If you would like to create the validator namespace you can use such sample code as described here
(function ($) {
// do not overwrite the namespace, if it already exists
$.validator= $.validator|| {};
$.validator.classRules = function () { return {};}
$.validator.attributeRules = function () { return {};}
})($);
I want to be able to put the code in one place and call it from several different events.
Currently I have a selector and an event:
$("input[type='checkbox']").on('click', function () {
// code works here //
});
I use the same code elsewhere in the file, however using a different selector.
$(".product_table").on('change', '.edit_quantity', function () {
// code works here //
});
I have tried following the advice given elsewhere on StackOverflow, to simply give my function a name and then call the named function but that is not working for me. The code simply does not run.
$(".product_table").on('change', '.edit_quantity', function () {
calculateTotals() {
// code does not work //
}
});
So, I tried putting the code into it's own function separate from the event and call it inside the event, and that is not working for me as well.
calculateTotals() {
// code does not work //
}
So what am I doing wrong ?
You could pass your function as a variable.
You want to add listeners for events after the DOM has loaded, JQuery helps with $(document).ready(fn); (ref).
To fix your code:
$(document).ready(function() {
$("input[type='checkbox']").on('click', calculateTotalsEvent)
$(".product_table").on('change', '.edit_quantity', calculateTotalsEvent)
});
function calculateTotalsEvent(evt) {
//do something
alert('fired');
}
Update:
Vince asked:
This worked for me - thank you, however one question: you say, "pass your function as a variable" ... I don't see where you are doing this. Can you explain ? tks. – Vince
Response:
In JavaScript you can assign functions to variables.
You probably do this all the time when doing:
function hello() {
//
}
You define window.hello.
You are adding to Global Namespace.
JavaScript window object
This generally leads to ambiguous JavaScript architecture/spaghetti code.
I organise with a Namespace Structure.
A small example of this would be:
app.js
var app = {
controllers: {}
};
You are defining window.app (just a json object) with a key of controllers with a value of an object.
something-ctlr.js
app.controllers.somethingCtlr.eventName = function(evt) {
//evt.preventDefault?
//check origin of evt? switch? throw if no evt? test using instanceof?
alert('hi');
}
You are defining a new key on the previously defined app.controllers.somethingCtlrcalled eventName.
You can invoke the function with ();.
app.controllers.somethingCtlr.eventName();
This will go to the key in the object, and then invoke it.
You can pass the function as a variable like so.
anotherFunction(app.controllers.somethingCtlr.eventName);
You can then invoke it in the function like so
function anotherFunction(someFn) { someFn();}
The javascript files would be structured like so:
+-html
+-stylesheets
+-javascript-+
+-app-+
+-app.js
+-controllers-+
+-something-ctlr.js
Invoke via chrome developer tools with:
app.controllers.somethingCtlr.eventName();
You can pass it as a variable like so:
$(document).ready(function() {
$('button').click(app.controllers.somethingCtlr.eventName);
});
JQuery (ref).
I hope this helps,
Rhys
It looks like you were on the right track but had some incorrect syntax. No need for { } when calling a function. This code should behave properly once you add code inside of the calculateTotals function.
$(".product_table").on('change', '.edit_quantity', function () {
calculateTotals();
});
$("input[type='checkbox']").on('click',function() {
calculateTotals();
});
function calculateTotals() {
//your code...
}
You could just condense it all into a single function. The onchange event works for both the check box and the text input (no need for a click handler). And jQuery allows you to add multiple selectors.
$('input[type=checkbox], .product_table .edit_quantity').on('change', function() {
console.log('do some calculation...');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="product_table">
<input type="checkbox">
<input class="edit_quantity">
</div>
I am new in HTML5 & trying to learn drag & drop feature.I have a JavaScript function for creating div element & attaching dragstart event to it.
var taskDefination = document.createElement("div");
taskDefination.className = "defaultButtonHolder";
taskDefination.setAttribute("draggable","true");
document.getElementById("toDo").getElementsByClassName('columnContent')[0].appendChild(taskDefination);
taskDefination.addEventListener('dragstart', dragStart, false);
}
Now I have a drop zone created as
<span class="columnWidth">
<div class ="columnHeader">Progress</div>
<div class ="columnContent" ondragenter ="dragDrop.dragEnter(event)"></div>
</span>
where the dragEnter function belongs to an external javascript file where it has been designed as a closure.I have checked network tab and this javascript file is perfectly loading.
var dragDrop = function(){
var _dragEnter = function(){
console.log("Dragged dropped");
}
return{
dragEnter:_dragEnter
}
}
Now the issue is whenever i am trying to drop the element in dropzone it is throwing an undefined not a function error. But ondropeneter event , if calling a function written in same HTML page it is perfectly executing.Why does it throwing an undefined not an function error though it is working fine function written in same HTML page?
Your closure isn't properly formed. As it stands, dragDrop is a function object returned from the function expression and as such doesn't have the code you want attached to it. Have a quick read of function expressions here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function
It looks like you're trying to use a closure to implement a module pattern. To do this, you need to rebuild your code like this:
var dragDrop = (function() {
var _dragEnter = function(){
console.log("Dragged dropped");
}
return {
dragEnter:_dragEnter
}
})();
The first set of brackets around the (function {}) make it a closure. The second set of brackets afterwards (function {})() execute it immediately. This means your module is returned to the var dragDrop and then you will be able to successfully call dragDrop.dragEnter.
I found the following definition
$.fn.flex = function ( options ) {
var p = this.data("flex"),
opts = options || {};
if (p) return p;
this.each(function () {
p = new Flex( this, opts );
$(this).data("flex", p);
});
return opts.api ? p : this;
};
which defines function flex() in original code.
Unfortunately, it stops defining this function in my environment, i.e. function call causes an error that flex is not a function.
What is critical here for flex being a function?
UPDATE
Sorry, actually I didn't modify anything. I just put this javascript https://github.com/jasonenglish/jquery-flex/ into my environment (Liferay) and the code to run script
<script type="text/javascript">
$(function() {
$(".flex").flex();
});
</script>
caused an error. So I replaced $ to jQuery everywhere as I did before and it is still not working.
UPDATE 2
Hmmm. Error occurs in widget.js from Twitter. Says
TypeError: jQuery(...).flex is not a function
If I rename flex to flex1 everywhere, it says "flex1" is not a function.
Sorry, actually I didn't modify anything. I just put this javascript ... into my environment (Liferay) and the code to run script
Because that's a jQuery plug-in, you need to make sure you include that script after jQuery on the page. So
<script src="/path/to/jquery.js"></script>
<script src="/path/to/the-plugin.js"></script>
If you put them in the other order, the first script will fail because it will try to take the value of the jQuery symbol, which doesn't exist yet, throwing a ReferenceError (in both loose and strict mode).
First of all in $.fn.flex $ and fn are jQuery variables. they are not native to JavaScript. $.fn provided by jQuery to attach method/property to jquery object