Can't get element from jQuery plugin using method
I am trying to create a small jQuery plugin that makes an element foldable or expandable.
Basically, the plugin requires the dom element to have a title and content:
<div class="foldable">
<div class="foldable-title">Title</div>
<div class="foldable-content">Content</div>
</div>
When a user clicks on a header, they must show or hide the content. This should work even when nested folding elements are in the DOM
My plugin works as expected when I click on a header that behaves as expected.
However, I want to be able to add "methods" to my plugin, but it doesn't work.
I have no error in the console and just nothing happens.
Here's one of my methods:
foldall: function () {
$(this).each(function () {
$(this).find(".foldable-unfolded").addClass("foldable-folded").removeClass("foldable-unfolded");
});
return this;
}
I think my problem is coming from the object this
. I'm not sure if its value is expected. He provided the following diagram:
$.fn.foldable = function (methodOrOptions) {
if (methods[methodOrOptions]) {
return methods[methodOrOptions].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof methodOrOptions === 'object' || !methodOrOptions) {
// Default to "init"
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + methodOrOptions + ' does not exist on jQuery.foldable');
}
};
Any question how to fix my problem?
FYI, jsFiddle is available with my current work .
Here's the complete code:
(function ($) {
var methods = {
init: function (options) {
var opts = $.extend({}, $.fn.foldable.defaults, options);
this.each(function () {
var $this = $(this);
var $title = $this.find(opts.title).first();
var $content = $this.find(opts.content).first();
$this.data("foldable", opts);
$title.css("cursor", "pointer");
if (!$this.hasClass(opts.foldedClass) && !$this.hasClass(opts.unfoldedClass)) {
$this.addClass(opts.unfoldedClass);
//$content.hide();
}
$title.click(function () {
$content.slideToggle(function () {
$this.toggleClass(opts.unfoldedClass).toggleClass(opts.foldedClass);
if (opts.complete) opts.complete();
});
});
});
return this;
},
foldall: function () {
$(this).each(function () {
$(this).find(".foldable-unfolded").andSelf().addClass("foldable-folded").removeClass("foldable-unfolded");
});
return this;
},
unfoldall: function () {
$(this).each(function () {
$(this).find(".foldable-folded").andSelf().addClass("foldable-unfolded").removeClass("foldable-folded");
});
return this;
}
};
$.fn.foldable = function (methodOrOptions) {
if (methods[methodOrOptions]) {
return methods[methodOrOptions].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof methodOrOptions === 'object' || !methodOrOptions) {
// Default to "init"
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + methodOrOptions + ' does not exist on jQuery.foldable');
}
};
$.fn.foldable.defaults = {
title: ".foldable-title",
content: ".foldable-content",
foldedClass: "foldable-folded",
unfoldedClass: "foldable-unfolded",
complete: null
};
var foldable = $(".foldable").foldable();
$(".foldall").click(function () {
foldable.foldable("foldall");
});
$(".unfoldall").click(function () {
foldable.foldable("unfoldall");
});
})(jQuery);
And a few CSS rules:
.folded > .content {
display:none;
}
.unfolded > .content {
display:inherit;
}
source to share