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;
}

      

+3


source to share


1 answer


Sometimes simple things are less obvious.

My problem has to do with the type of css rules, specifically the class name. it should have been:



.foldable-folded > .foldable-content {
    display:none;
}
.foldable-unfolded > .foldable-content {
    display:inherit;
}

      

0


source







All Articles