After retrieving the onclick source, can't use methods of element - javascript

This is the content of "myPlugin.js":
(function ($) {
$.fn.MyPlugin = function (options) {
// retrieve somespan
somespan.html("");
})(jQuery);
function SelectLink(element) {
console.log(element);
if (element.parent("span").parent("li.clickable")) {
alert("is clickable");
} else {
alert("is not clickable");
}
}
When I click the link element we created inside the div , the console gives me:
TypeError: element.parent is not a function
<a onclick="javascript: SelectLink(this);" href="#">
So it knows the element from which we departed, but I can't do anything further with it? Why does this happen?

Here element is a dom element reference not a jQuery oject so there is no method called parent() in it.
You can get the jQuery wrapper for the element and call the method on the wrapper
function SelectLink(element) {
console.log(element);
var $element = $(element);
if ($element.parent("span").parent("li.clickable")) {
alert("is clickable");
} else {
alert("is not clickable");
}
}
Since you are working on a plugin, instead of using inlined event handlers use jQuery event handlers like
(function ($) {
$.fn.MyPlugin = function (options) {
var $a = $('');
somespan.html($a);
$a.click(SelectLink)
}
function SelectLink(event) {
var $this = $(this);
//if ($this.closest("li.clickable").length) {
if ($this.parent("span").parent("li.clickable").length) {
alert("is clickable");
} else {
alert("is not clickable");
}
}
})(jQuery);

Related

Access originally clicked element in jQuery plugin

I have the following plugin, and while I wish it to be able to be applied to multiple elements, I do not wish to create a new dialog for each element.
But in the dialog.open callback or when the button is clicked, I wish to be able to access the element which was clicked and opened the dialog.
If I wanted to create multiple dialogs, I suppose I could put this.each(function () {...} in the init method and then this would be the individually clicked element, but as stated earlier, I only one one dialog.
EDIT. I revised the code so that it does what I need it to do. It just seems like a bit of a hack using data as I did. Is there a more proper way to do so?
How is this accomplished?
(function($){
var defaults = {};
var methods = {
init : function (options) {
var settings = $.extend({}, defaults, options);
var dialog = $('<div/>').dialog({
open: function( event, ui ) {
console.log(dialog.data('elementThatWasClicked'));
},
buttons: [
{
text: 'click',
click: function() {console.log(dialog.data('elementThatWasClicked'));}
}
]
});
return this.each(function () {
var $this=$(this);
$this.click(function(){dialog.data('elementThatWasClicked',$this).dialog('open')});
});
}
};
$.fn.test = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || ! method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.test');
}
};
}(jQuery));
$(function(){
$('.bla').test();
});

show() is undefined because of custom plugin

I wrote this plugin to catch show event only for div_loading_page element:
(function ($) {
$.each(['show'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.each(function () {
if (this.id == 'div_loading_page') {
$(this).trigger(ev);
return false; // break out of the loop
}
});
//alert(this.id);
el.apply(this, arguments);
};
});
})(jQuery);
It's working fine but because of it i get following error:
$cluetipTitle.show() is undefined , which is from cluetip jquery plugin. Any idea how can i resolve this conflict?
Change:
el.apply(this, arguments);
To
return el.apply(this, arguments);
This ensure that the original function's return value is reserved and will not cause unexpected behavior
change this
$.each(['show']
to
return $.each(['show']
this will allow for chaining, ie doing what you want to do with the .show

load() without jQuery?

I am trying to get rid of using jQuery from my widget, having troubles finding how to replace load().
How would i do this in native JavaScript?
$('#IframeABC').load(function() {
var animator = new Animator('sWrapper');
animator.animate();
css('sWrap', 'display', 'block');
});
It’s… onload.
document.getElementById('IframeABC').onload = function() {
Or, to be more modern (incompatible? ;)) about it, the load event:
document.getElementById('IframeABC').addEventListener('load', function() {
The equivalent would be:
var element = document.getElementById('IframeABC');
var handler = function () {
// Handler in no jQuery obviously
}
if (element.addEventListener) {
element.addEventListener('load', handler, false);
} else if (element.attachEvent) {
element.attachEvent('onload', handler);
} else {
element.onload = handler;
}

Making a method in a plugin accessible globally?

Given the jQuery dropdown plugin below. Is there a way to add a method that would allow for a separate function outside of the dropdown to 'hideMenu'? Thanks
For example, if I applied the plugin to a div with an ID like so:
$('#settings.dropdown').dropDownMenu();
How could I then call to close the dropDownMenu w hideMenu from outside of the plugin? Thanks
jQuery.fn.dropDownMenu = function() {
// Apply the Dropdown
return this.each(function() {
var dropdown = $(this),
menu = dropdown.next('div.dropdown-menu'),
parent = dropdown.parent();
// For keeping track of what's "open"
var activeClass = 'dropdown-active',
showingDropdown = false,
showingMenu,
showingParent,
opening;
// Dropdown Click to Open
dropdown.click(function(e) {
opening = true; // Track opening so that the body click doesn't close. This allows other js views to bind to the click
e.preventDefault();
if (showingDropdown) {
dropdown.removeClass(activeClass);
parent.removeClass(activeClass);
showingMenu.hide();
showingDropdown = false;
} else {
showingDropdown = true;
showingMenu = menu;
showingParent = parent;
menu.show();
dropdown.addClass(activeClass);
parent.addClass(activeClass);
}
});
// When you click anywhere on the page, we detect if we need to blur the Dropdown Menu
$('body').click(function(e) {
if (!opening && showingParent) {
var parentElement = showingParent[0];
if (!$.contains(parentElement, e.target) || !parentElement == e.target) {
hideMenu();
}
}
opening = false;
});
// hides the current menu
var hideMenu = function() {
if(showingDropdown) {
showingDropdown = false;
dropdown.removeClass(activeClass);
parent.removeClass(activeClass);
showingMenu.hide();
}
};
});
};
jQuery advises making multiple methods available through the plugin itself:
jQuery.fn.dropDownMenu = function(method) {
var methods = {
init: function() {
// Put all your init code here
},
hide: function() {
hideMenu();
}
};
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
function hideMenu() {
// ...
}
};
See http://docs.jquery.com/Plugins/Authoring#Plugin_Methods
Update: Use like this:
// Use the plugin normally to run the init method
$('#settings.dropdown').dropDownMenu();
// Call the hide method
$('#settings.dropdown').dropDownMenu('hide');
Sure. Give hideMenu to the global window object, like this:
window["hideMenu"] = function() {
if(showingDropdown) {
showingDropdown = false;
dropdown.removeClass(activeClass);
parent.removeClass(activeClass);
showingMenu.hide();
}
};
You can then call it as usual anywhere you need to.

Javascript get the dom element a function was called from

HTML part:
foo
JS part:
function callme() {
var me = ?; //someway to get the dom element of the a-tag
$(me).toggle();
}
in the JS part can i somehow get the a-tag that this function was called from?
i know i could just pass it as a parameter, but this function is used many many times on a page and i want to avoid putting the parameter everywhere.
thanks!
Since you are using an onclick attribute (BAD!) you have to pass that into the function.
onclick="callme(this); return false;"
and the js:
function callme(el) {
var $me = $(el);
$me.doSomething();
}
Another option is to set the context of the function using .call().
onclick="callme.call(this,event)"
and the js
function callme(event) {
event.preventDefault();
$(this).doSomething();
}
I have a simple JS function for that
function getEventTarget(event) {
var targetElement = null;
try {
if (typeof event.target != "undefined") {
targetElement = event.target;
}
else {
targetElement = event.srcElement;
}
// just make sure this works as inteneded
if (targetElement != null && targetElement.nodeType && targetElement.parentNode) {
while (targetElement.nodeType == 3 && targetElement.parentNode != null) {
targetElement = targetElement.parentNode;
}
}
} catch (ex) { alert("getEventTarget failed: " + ex); }
return targetElement;
};
in your html
foo
in your function
function callme(event) {
var me = getEventTarget(event); //someway to get the dom element of the a-tag
$('#'+ me.id).toggle();
}
getEventTarget() will bring back the whole dom object which you can manipulate as you please, or has been said already by other users you can just use
function callme(event) {
$(this).toggle();
}
send this parameter to your function.
foo
function callme(me) {
$(me).toggle();
}
better dont use onlcick in html markup
$(document).ready(function() {
$("a").click(callme);
})
function callme() {
var me = this;
$(me).toggle();
}

Categories