edg
edg

Reputation: 669

How can I execute a function passed as an option in a Jquery plugin?

I'm creating a plugin that add buttons based on the options passed into it. I can already render the buttons but I can't figure out how to execute the function when the button is clicked.

Here's an example of how the plugin is used:

$("#myobj").myPlugin({
    width: 100,
    height: 100,
    buttons: {
        "Say Hello": function () { alert("Hello World!"); },
        "Goodbye": function() { alert("Goodbye!"); },
        "Other": function() { alert("Something here"); }
    }
});

I'm trying something like the below inside the plugin source code but I couldn't make the function call work on button click. Please help...

if (options.buttons !== null) {
    var buttons = "";
    for (var property in options.buttons) {
        //console.log(property + ': ' + options.buttons[property]);
        buttons += "<button onclick='" + options.buttons[property] + "'>" + property + "</button>"
    }
}

Upvotes: 0

Views: 72

Answers (2)

edg
edg

Reputation: 669

Thanks to P. Lalonde! I'm posting my complete simplified code here just in case other people run into the same hurdle.

jQuery Plugin Source Code:

(function($) {
    //Shell for your plugin code
    $.fn.buttonsTest = function(options) {
        options = $.extend({}, $.fn.buttonsTest.defaults, options);

        return this.each(function() {                                 
            //Do something to each item
            var buttons = "";
            if (options.buttons !== null) {
                for (var value in options.buttons) {
                    //console.log(property + ': ' + options.buttons[property]);
                    buttons += "<button data-value='" + value + "'>" + value + "</button>"
                }
            }

            //render the UI
            $(this)
                .css({
                    width: options.width + 'px',
                    height: options.height + 'px'
                })
                .html(options.title + "<br>" + buttons);

            //bind each buttons function into their corresponding click event
            $(this).on("click", "button", function() {
                var matchingButtonValue = $(this).data("value");
                options.buttons[matchingButtonValue].call(this);
            });
        });
    }

    $.fn.buttonsTest.defaults = {
        title: "Buttons Test",
        width: 100,
        height: 100,
        buttons: null
    }
})(jQuery);

Sample HTML Source code using the Plugin.

<html>
<head>
<title>Buttons Test</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js" type="text/javascript"></script>
<script src="js/buttonstest/jquery.buttonstest.js" type="text/javascript"></script>
<script type="text/javascript">

        $(function () {
            $("#mytest").buttonsTest({
                title: "My Test",
                width: 500,
                buttons: {
                    "Say Hello": function() {
                        //this could be any action. Added an alert just for simplicity
                        alert("Hello World!");
                    },
                    "Good Bye": function() {
                        alert("Good bye World!");
                    },
                    "Other": function() {
                        alert("Say what?");
                    }
                }
            });

            $("#mytest2").buttonsTest({
                title: "My Test 2",
                width: 500,
                buttons: {
                    "Say Hello": function() {
                        alert("Hello World 2!");
                    },
                    "Something Else": function() {
                        alert("Say what 2?");
                    }
                }
            });

        });
</script>
</head>
<body>
<div id="mytest"></div>
<div id="mytest2"></div>
</body>
</html>

Thanks again to P. Lalonde.

Upvotes: 0

P. Lalonde
P. Lalonde

Reputation: 694

I would suggest adding a "data" attribute with the property name and always call the same method onClick.

buttons += "<button data-property='" + property + "'>" + property + "</button>";

...

$("#myobj").on("click", "button", function(){
    var matchingButtonPropName = $(this).data("property");
    options.buttons[matchingButtonPropName].call(this);
});

Upvotes: 1

Related Questions