How to call function in jquery plugin? - javascript

(function($) {
$.fn.top_islides = function(){
var ajax_init = function(){
init_islides();
setTimeout(function(){picmove()},300);
};
//.....
};
})(jQuery);
call it in doucument ready in another file
$('#top_slides').top_islides();
$('#top_slides').top_islides().ajax_init();
I thought it should work ,I got an error, what's the problem?

Do it like this:
(function($) {
//Assuming $.fn.top_islides is defined
$.fn.top_islides.ajax_init = function(){
init_islides();
setTimeout(picmove,300);
};
//.....
})(jQuery);
Or
(function($) {
$.fn.top_islides = function(){
var ajax_init = function(){
init_islides();
setTimeout(picmove,300);
};
return {
ajax_init: ajax_init
};
});
//.....
})(jQuery);

Try something like this as in the example below:-
<script type="text/javascript">
$.someplugin = {
CallMe : function() {
alert("You called?");
},
otherstuff : function() { alert("other stuff!"); }
};
$.someplugin.CallMe();
$.someplugin.otherstuff();
</script>

when using var inside a function, it will make the element "private". it's a hacky way to make visibility in Javascript work, while true class structure don't come to Javascript.
You need to either set it to the prototype of your function or to return an object
(function($) {
$.fn.top_islides = function(){
var ajax_init = function(){
init_islides();
setTimeout(function(){picmove()},300);
};
return {
'ajax_init': ajax_init
};
//.....
};
})(jQuery);
or
(function($) {
$.fn.top_islides = function(){
//.....
};
$.fn.top_islides.prototype.ajax_init = function(){
init_islides();
setTimeout(function(){picmove()},300);
}
})(jQuery);
but in your case, you won't be using prototype, since you aren't instantiating a new top_islides object, but accessing through jQuery, so the first option is your best bet.

Imo, best solution is used trigger which is cleaner because you can keep the chainable plugin system.
You can declare event handler in your plugin declaration and trigger from outside:
(function($) {
$.fn.top_islides = function(){
this.on ('init_islides', function(){
setTimeout(function(){picmove()},300);
};
//.....
};
})(jQuery);
$( "button" ).click(function () {
$( "p" ).trigger( "init_islides");
});
DOC can be found here : http://api.jquery.com/on/

Related

Only run function after custom function complete jQuery

I normally do e.g.:
$(".item").fadeIn(function(){
alert('done');
});
Which works? (I believe is correct?) but how do I do this with custom functions?
E.g.
$(".item").customFunction(function(){
customFunctionTwo();
});
Basically it will look like this
$.fn.customFunction = function (callback){
//some code
callback();
}
$('.item').customFunction(function () {
customFunctionTwo();
});
I guess you should be looking at promises https://api.jquery.com/promise/
$.fn.customFunction = function (callback){
var myFn = function(){
/* your code along with settimeout as well if you choose*/
//example
return $( "div" ).fadeIn( 800 ).delay( 1200 ).fadeOut();
}
$.when( myFn() ).done(function() {
callback();
});
}
$('.item').customFunction(function () {
customFunctionTwo();
});

jQuery onclick function: Undefined is not a function

Edit: I guess part of this is an issue of me being inexperienced with Drupal. I added a javascript file to site.info, so that it will be added to every page. This is all the file contains:
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
When the site loads, it gets compiled into this larger script, which looks like this in the debugger:
(function ($) {
Drupal.behaviors.titlebar = {
init: function(context, settings) {
// Using percentage font size to easily increase/decrease page font size
var baseFontSize = 100;
$('.pgc-font-size a').click(function() {
if($(this).hasClass('increase')) {
if(baseFontSize < 150)
baseFontSize += 20;
$('.pg-content-body p').css('font-size', baseFontSize+'%');
} else {
if(baseFontSize > 70)
baseFontSize -= 10;
$('.pg-content-body p').css('font-size', baseFontSize+'%');
}
});
// Print button
$('.pgc-print a').click(function() {
window.print();
})
}
};
}(jQuery));
// There's a problem with our jQuery loading before the ingested site's
// jQuery which is causing jQuery plugins to break (the "once" plugin in this case).
// I'm using this workaround for now
jQuery(function() {
Drupal.behaviors.titlebar.init();
});;
(function ($) {
Drupal.behaviors.giftTypes = {
init: function() {
// Gift details accordion
$('.pg-gift-details .accordion-items').css('display', 'none');
$('.pg-gift-details .accordion-switch').click(function(){
if($(this).hasClass('open')) {
$(this).find('span').removeClass('icon-arrow-up').addClass('icon-arrow-down');
$('.pg-gift-details .accordion-items').slideUp('slow');
$(this).html($(this).html().replace('Hide', 'Show More'));
$(this).removeClass('open');
} else {
$(this).find('span').removeClass('icon-arrow-down').addClass('icon-arrow-up');
$('.pg-gift-details .accordion-items').slideDown('slow');
$(this).html($(this).html().replace('Show More', 'Hide'));
$(this).addClass('open');
}
})
}
}
}(jQuery));
// There's a problem with our jQuery loading before the ingested site's
// jQuery which is causing jQuery plugins to break (the "once" plugin in this case).
// I'm using this workaround for now
jQuery(function() {
Drupal.behaviors.giftTypes.init();
});;
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
alert(searchVal);
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
;
You can see my little script at the bottom there. It says there's something wrong with the first line, but I'm not sure what the problem is. What change would I need to make to my javascript file to make sure it compiles right?
I'm probably overlooking a really simple type, but I can't see what's wrong with my jQuery.
This is the part that's not working:
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.website.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
I have jQuery on my site, I know I do because this it's used earlier in the code with no problem. The error is showing in the debugger on the first line, '$("#ct100_btnSearch001").on("click", function(){ '. Here is a larger section of the script page:
(function($) {
Drupal.behaviors.giftTypes = {
init: function() {
// Gift details accordion
$('.pg-gift-details .accordion-items').css('display', 'none');
$('.pg-gift-details .accordion-switch').click(function() {
if ($(this).hasClass('open')) {
$(this).find('span').removeClass('icon-arrow-up').addClass('icon-arrow-down');
$('.pg-gift-details .accordion-items').slideUp('slow');
$(this).html($(this).html().replace('Hide', 'Show More'));
$(this).removeClass('open');
} else {
$(this).find('span').removeClass('icon-arrow-down').addClass('icon-arrow-up');
$('.pg-gift-details .accordion-items').slideDown('slow');
$(this).html($(this).html().replace('Show More', 'Hide'));
$(this).addClass('open');
}
})
}
}
}(jQuery));
jQuery(function() {
Drupal.behaviors.giftTypes.init();
});;
(function($) {
$("#ctl00_btnSearch001").on("click", function() {
var searchVal = $("#ctl00_txtSearch").val();
alert(searchVal);
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);;
Try to install jQuery update Module.
If you are using Drupal 6, you are not be able to use on function.
One option is to include your custom version of jQuery in your page.tpl.php, another option (not recommended) is to use live, but now is deprecated.
You can bind a function to an event use two way:
1.use bind() method and the event name as the first argument
$( "#foo" ).bind( "click", function() {
alert( "User clicked on 'foo.'" );
});
or
2.just use the event method
$( "#foo" ).click( function() {
alert( "User clicked on 'foo.'" );
});
The problem of your code is that there isn't a on event.
ref http://api.jquery.com/category/events/mouse-events/
If ctl00_btnSearch001 is a correct id for what ever you are trying to click. Try changing it to this:
(function ($){
$(document).on("click", "#ctl00_btnSearch001", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);

On/off click event on alternating tabs

$('#filter').on('click', function(){
$('#sort').off('click');
console.log($(this));
});
$('#sort').on('click', function(){
$('#filter').off('click');
console.log($(this))
});
$('.close').on('click', function () {
console.log($(this));
$('#sort').on('click');
$('#filter').on('click');
});
Why doesnt the div .close give back the on method to the divs above if they have the same selector id?
EDIT: For clarity, I'm wanting to temporarily remove the on event on whichever of the two elements wasn't clicked (#filter or #sort). Then clicking '.close' will return the said element back to having the on method again.
The off() does not work the way you think. It actually removes the event handlers (callback functions), not just hides them, so you cannot restore them with a simple on(), they are not stored any longer by the element after the off(), you have to add them again. It is not easy to track whether an event handler is added, so I suggest another approach.
var sort = true;
var filter = true;
$('#filter').on('click', function(){
if (!filter)
return;
sort = false;
console.log($(this));
});
$('#sort').on('click', function(){
if (!sort)
return;
filter = false;
console.log($(this))
});
$('.close').on('click', function () {
console.log($(this));
sort = true;
filter = true;
});
Another approach to use toggle() and combine it with the on() and off() functions. Hmm I found that jquery toggle() is not loosely coupled to dom elements, so you cannot do this with that. You have to create your own implementation, for example something like this:
function toggle(options) {
var currentValue = !!options.value;
return function (value){
if (value === undefined)
value = !currentValue;
if (value != currentValue)
if (value) {
currentValue = true;
options.on();
}
else {
currentValue = false;
options.off();
}
};
}
With this toggle implementation your code will be the following:
var switches = {
sort: toggle({
on: function (){
$('#sort').on('click', function(){
switches.filter(false);
console.log($(this))
});
},
off: function (){
$('#sort').off('click');
}
}),
filter: toggle({
on: function (){
$('#filter').on('click', function(){
switches.sort(false);
console.log($(this));
});
},
off: function (){
$('#filter').off('click');
}
})
};
$('.close').on('click', function () {
console.log($(this));
switches.sort(true);
switches.filter(true);
});
switches.sort(true);
switches.filter(true);
You can try with:
$('#filter:not(.off)').on('click', function(){
$('#sort').addClass('off');
console.log($(this));
});
$('#sort:not(.off)').on('click', function(){
$('#filter').addClass('off');
console.log($(this))
});
$('.close').on('click', function(){
$('#sort').removeClass('off');
$('#filter').removeClass('off');
console.log($(this));
});
I'm assuming that in your block of codeā€¦
$('.close').on('click', function () {
console.log($(this));
$('#sort').on('click');
$('#filter').on('click');
});
You want to click #sort and #filter. To do such, you'll need to do the following:
$('.close').on('click', function () {
console.log($(this));
$('#sort').click();
$('#filter').click();
});
Even so, it would probably be better to wrap the other event handlers in a function and call them like such:
$('.close').on('click', function () {
console.log($(this));
sortClickFunction();
filterClickFunction();
});
This will do anything: $('#sort').on('click');
You need to call: $('#sort').trigger('click');

Condensing Javascript/jQuery Code

I'd like to start by thanking anyone who can help me condense this piece of Javascript/jQuery code.
jQuery(function() {
jQuery('#pitem-1').click(function(e) {
jQuery("#image-1").lightbox_me({centered: true, onLoad: function() {
jQuery("#image-1").find("input:first").focus();
}});
e.preventDefault();
});
jQuery('#pitem-2').click(function(e) {
jQuery("#image-2").lightbox_me({centered: true, onLoad: function() {
jQuery("#image-2").find("input:first").focus();
}});
e.preventDefault();
});
jQuery('#pitem-3').click(function(e) {
jQuery("#image-3").lightbox_me({centered: true, onLoad: function() {
jQuery("#image-3").find("input:first").focus();
}});
e.preventDefault();
});
jQuery('table tr:nth-child(even)').addClass('stripe');
});
Basically each #pitem-ID opens the same #image-ID in a popup.
Thanks again to anyone who can help.
Jack
Your functions all look pretty much the same, which is a clue that you should probably move that functionality out into something that can be called:
function createHandler(id) {
return function (e) {
$(id).lightbox_me({centered: true, onLoad: function() {
$(id).find("input:first").focus();
}});
e.preventDefault();
}
};
Then you can use:
$('#pitem-2').bind('click', createHandler("#image-2"));
You can:
Combine multiple objects into the selector with a common event handler
Use this to refer to the object that triggered the event
Derive the image ID from the id of the object that generated the event.
That lets you use one piece of code to handle the action for all three objects:
jQuery(function() {
jQuery("#pitem-1, #pitem-2, #pitem-3").click(function() {
var image$ = $("#" + this.id.replace("pitem", "image"));
image$.lighbox_me({centered: true, onLoad: function() {
image$.find("input:first").focus();
}});
e.preventDefault();
});
jQuery('table tr:nth-child(even)').addClass('stripe');
});
$('[id^="pitem-"]').click(function(e) {
var numb = this.id.split('-')[1];
$("#image-"+numb).lightbox_me({centered: true, onLoad: function() {
$(this).find("input:first").focus();
}
});
e.preventDefault();
});
$('table tr:nth-child(even)').addClass('stripe');
Without context it is hard to tell, but is it necessary to have a unique ID for each pitem? Why not use a CSS class instead of a ID like so:
<div class="pitem">
<div id="image1"><img ... /></img>
</div>
...
<div class="pitem">
<div id="image3"><img ... /></img>
</div>
And then use the class selector in jQuery to add the click functionality all of them at once:
$(".pitem").click(function(e) {
var currentItem = e.target;
...
e.preventDefault();
});

jQuery and IE, object doesn't support this property or method

I've used this bit of code to get a drop-down style menu on a website.
It works absolutely fine on all browsers other than IE, and even works fine on IE except on this one page where I get the "Object doesn't support this property or method" error.
Here is where IE tells me the error is, this part is in a "header" file that is loaded first before the rest of the page.
<script type="text/javascript">
$(document).ready(function(){
$("#nav-one li").hover(
function(){ $("ul", this).fadeIn("fast"); },
function() { }
);
if(document.all){
$("#nav-one li").hoverClass("sfHover");//THIS LINE IS WHERE THE ERROR IS
};
});
$.fn.hoverClass = function(c) {
return this.each(function(){
$(this).hover(
function() { $(this).addClass(c); },
function() { $(this).removeClass(c); }
);
});
};
</script>
I don't think the error is in the code because it works fine with no errors on every single page except for this one, this is also the only page that uses additional jQuery code.
The rest of the jQuery code runs fine on the page, only the drop-down doesn't work when hovering over the menu items.
If anyone can help me find the answer it would be greatly appreciated.
Thanks,
When you call hoverClass, it has not yet been defined. You need to declare $.fn.hoverClass at the top of your code.
$.fn.hoverClass = function(c) {
return this.each(function(){
$(this).hover(
function() { $(this).addClass(c); },
function() { $(this).removeClass(c); }
);
});
};
$(document).ready(function(){
$("#nav-one li").hover(
function(){ $("ul", this).fadeIn("fast"); },
function() { }
);
if(document.all){
$("#nav-one li").hoverClass("sfHover");//THIS LINE IS WHERE THE ERROR IS
};
});
You are accessing $.fn.hoverClass before it's being declared. You should declare/load all plugins before any other code, just to be safe.
Also, in $.fn.hoverClass, you don't need .each, you can just return this.hover(). (Also, you don't need a semicolon after if statements).
$.fn.hoverClass = function(c) {
return this.hover(
function() { $(this).addClass(c); },
function() { $(this).removeClass(c); }
);
};
$(document).ready(function(){
$("#nav-one li").hover(
function(){ $("ul", this).fadeIn("fast"); },
function() { }
);
if(document.all){
$("#nav-one li").hoverClass("sfHover");//THIS LINE IS WHERE THE ERROR IS
}
});
I think the plugin is getting overridden by jQuery. May be you have included jQuery multiple times on this page. Try this
$(document).ready(function(){
$.fn.hoverClass = function(c) {
return this.each(function(){
$(this).hover(
function() { $(this).addClass(c); },
function() { $(this).removeClass(c); }
);
});
};
$("#nav-one li").hover(
function(){ $("ul", this).fadeIn("fast"); },
function() { }
);
if(document.all){
$("#nav-one li").hoverClass("sfHover");//THIS LINE IS WHERE THE ERROR IS
};
});

Categories

Resources