Why is Drupal not recognizing my javascript function? - javascript

Why is the following not working:
(function($){
Drupal.my_module = {};
Drupal.behaviors.my_module = {
attach: function(context, settings) {
$('#some-div').Drupal.my_module.doStuff();
}
};
Drupal.my_module.doStuff = function(){
this.append('Hello World');
}
})(jQuery);
I get this error: TypeError: $(...).Drupal is undefined
If I use another architecture like passing the selector as an argument for the function it works:
(function($){
Drupal.my_module = {};
Drupal.behaviors.my_module = {
attach: function(context, settings) {
Drupal.my_module.doStuff($('#some-div'));
}
};
Drupal.my_module.doStuff = function(elem){
elem.append('Hello World');
}
})(jQuery);
It also works if I declare the function in the jQuery.fn object:
$.fn.doStuff = function(){...do something...}; // It works
Then call it like:
$('#my-div').doStuff(); // It works
But I want to put it under Drupal.my_module, something more like the first case.
Any clues?
Thanks!

$('#some-div').Drupal.my_module.doStuff();
Drupal is not a valid jQuery method or property, hence the undefined error.

Related

method with parameter in unknown js function issues

I'm trying to protect a part of my js code wrapping my code with an Unknown function.
I have edit my function to change
function banana(url) {}
to method
banana: function(url){ },
when I try to call my function banana in another function i try to use
this.banana(url);
but i have this error:
TypeError: this.banana is not a function
Full code:
(function (){
var url_test = "./add_user.php?opt=get_user&token=<?php echo $token; ?>";
if (typeof $.customfnc == 'undefined')
$.customfnc = {}
$.customfnc.get = {
setup: function (){
var url = "google.ca";
this.banana(url);
},
banana: function (url){
console.log("my url: " + url);
};
};
};
// on ready render data
$(document).ready(function() {
$.customfnc.get.setup();
});
})(jQuery);
thanks for your help!
The issue here is that the scope of 'this' is not exactly what you might think it is.
The way I have handled this particular issue in the past is to add
var self = this;
Outside of the object that is attempting to self reference. This may impact how you have set up youre .get() object though.
$.customfnc.get = function(){
var self = this;
self.setup = function (){
//....
self.banana(URL)
}
self.banana = function(url){
//...
}
}

Accessing public functions from inside a jQuery plugin

It is the first time I write a jQuery plugin without a tutorial. Now (September 28 2014), the jQuery site doesn't work (I don't know why), so I cannot find any resource there.
Below is part of my plugin that reports errors:
$(function($){
$.fn.dialog = function(command, options) {
var opts = $.extend( {}, $.fn.dialog.defaults, options );
//code
$.fn.dialog.handleCancel = function() {
};
$.fn.dialog.handleAccept = function() {
};
return this;
};
$.fn.dialog.defaults = {
// some other props
onCancel: $.fn.dialog.handleCancel(),
onAccept: $.fn.dialog.handleAccept()
};
// code
}(jQuery));
When I call the plugin ($("#dialog1").dialog(/*..*/)), the browser console, shows the following:
Uncaught TypeError: undefined is not a function
The error is on the line with onCancel: $.fn.dialog.handleCancel().
How can I access these methods, and where should them be? (I also want them to have access to $(this) <- for the dialog itself)
Your handleCancel and handleAccept functions are not initialized until you call the $.fn.dialog function. Therefore, they are undefined when you set the dialogs defaults.
Insert this code prior to $.fn.dialog.defaults:
$.fn.dialog();
Try rearranging blocks within the piece , adding a filter , to prevent both handleCancel and handleAccept being called by default; e.g.,
(function($){
$.fn.dialog = function(command, options) {
var $el = this;
// access , pass arguments to methods
$.fn.dialog.handleCancel = function(c) {
$el.html(c + "led")
};
$.fn.dialog.handleAccept = function(a) {
$el.html(a + "ed")
};
// call `handleCancel` or `handleAccept` ,
// based on `command`
$.fn.dialog.defaults = {
// some other props
onCancel: command === "cancel"
? $.fn.dialog.handleCancel(command)
: null,
onAccept: command === "accept"
? $.fn.dialog.handleAccept(command)
: null
};
var opts = $.extend( {}, $.fn.dialog.defaults, options );
//code
return this;
};
// code
}(jQuery));
$("button").on("click", function(e) {
$("#result").dialog(e.target.id)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="accept">accept</button><button id="cancel">cancel</button><br />
Result: <div id="result"></div>

Updating a JavaScript Object Creation Pattern

I have the following JavaScript pattern for creating a simple plugin:
(function(window, document, $) {
function method_1(){
}
function method_2{}
{
}
})(window, document, jQuery);
I want to have the ability to access my plugin and plugin methods in the following way:
myplugin.method_1();
myplugin.method_2();
How do I update my existing plugin pattern to enable this?!
NOTE: It has to maintain a self-executing format i.e. no variable declarations.
You could try something like this fiddle, which returns an object that includes the public functions for the plugin.
var myPlugin = (function(window, document, $) {
function privateFunction() {
}
return {
method_1: function () {
},
method_2: function () {
privateFunction(); // This works
}
};
}(window, document, jQuery));
myPlugin.method_1();
myPlugin.method_2();
myPlugin.privateFunction(); // This will throw an error
The following pattern seems to work perfectly for my requirements:
(function(root, name, make){
var $ = root['jQuery'] || root['Zepto'];
if (typeof module != 'undefined' && module['exports']) module['exports'] = make($);
else root[name] = make($);
}(window, 'myPlugin', function($) {
function method_1(){
}
function method_2{}
{
}
var myPlugin = {
method_1: method_1,
method_2: method_2
};
return myPlugin;
}));

Giving data/params with my function jquery

var regfbnaam = $('#regfbnaam');
$('#regnaam').focusin({param1: regfbnaam},removeClass);
function removeClass(e)
{
param1.removeClass('hidden');
}
Error in console.log: param1 is nog defined. Means he doesn't get the value of my param1. What am i doing wrong here?
(trying to get a variable with a onclick event to my function)
Try this (tested)
function removeClass(e) {
var param1 = e.data.param1;
param1.removeClass('hidden');
}
jQuery(document).ready(function($) {
var regfbnaam = $('#regfbnaam');
$('#regnaam').focusin({param1: regfbnaam},removeClass);
});
Reference:
event.data
.focusin()
Try:
function removeClass(e)
{
$(e.data.param1).removeClass('hidden');
}
Not exactly sure what you trying to do with that syntax. I would suggest a different approach:
var $el = $(el);
$el.on('focusin', function(){
removeClass(e, {param1: regfbnaam});
});
function removeClass(e, params)
{
params.param1.removeClass('hidden');
}
Untested, but I think it should work. Basically the idea is that you are binding a function to the element and then providing it with whatever arguments it needs.

Overriding a function in jQuery plugin

I have an existing jQuery plugin, now I want to extend it. Consider the below mentioned plugin:
$.fn.x = function(option) {
var def = {
a: 1,
b: 2
};
option = $.extend(def, option);
function abc() {
//do something
}
function def() {
//do something
}
};
Now the above one is the plugin I got from somewhere. I need to have custom behavior for abc method, say
function abc() {
//do something else
}
I don't want to change the existing plugin, Can you tell me how could I achieve the same by extending the same or by making my own custom plugin ?
EDIT:
I tried this too with method mentioned below:
(function($) {
$.fn.x = function(option) {
var defaults = {
a: 1,
b: 2
};
option = $.extend(def, option);
function abc() {
//do something
console.log('Base method called');
}
function def() {
//do something
abc();
}
def();
};
})(jQuery);
(function() {
var x = $.fn.x;
$.fn.x.abc = function() {
console.log('Overidden method called');
//_x.abc();
};
})();
$('<div/>').x();
But I am still getting "Base method called" as the console output.
The best route can vary, but something that I've done in the past is to wrap the extension in my own! This works best when you're trying to operate on something that the plugin does without modifying its underlying code.
(function($){
$.fn.extendedPlugin = function(options) {
var defaults = {
//...
};
var options = $.extend(defaults, options);
//Here you can create your extended functions, just like a base plugin.
return this.each(function() {
//Execute your normal plugin
$(this).basePlugin(options);
//Here you can put your additional logic, define additional events, etc
$(this).find('#something').click(function() {
//...
});
});
};
})(jQuery);
I know this isn't terribly specific (it's hard without a specific scenario), but hopefully it'll get you started down the right path!
This is as far as I got. But when I uncomment _x.abc.apply( this, arguments );, it gets stuck in a recursive loop.
Here's the jsfiddle if someone wants to play with and fix it:
http://jsfiddle.net/TLAx8/
// PLUGIN DEFINITION
(function( $ ){
$.fn.x = function(option) {
var def = {
a: 1,
b: 2
};
option = $.extend(def, option);
function abc() {
console.log( 'Plugin method called' );
}
function def() {
//do something
}
};
})( jQuery );
// OVERRIDING THE PLUGIN METHOD
(function(){
var _x = $.fn.x;
$.fn.x.abc = function() {
console.log( 'Overidden method called' );
//_x.abc.apply( this, arguments );
}
})();
// INVOKING THE METHOD
(function() {
$.fn.x.abc();
});

Categories