views:

24

answers:

2

I'm writing a jQuery plugin that stores some data in some cases.

I'd like to write it in a very flexible way, where I'll can change an input parameter to obtain some value that were stored by the plugin.

Explanation:

When I call $("#any").myPlugin(), my plugin initializes creating a div and some a inside. Clicking on an a will store it .index() using the .data() method. If I call $("#any").myPlugin("getSelection") then I would like to get the value stored with .data().

What I'd tried:

(function ($) {
    $.fn.myPlugin = function (action) {
        if (action == null) action = "initialize";

        return this.each(function ($this) {
            $this = $(this);

            if (action == "initialize") {
                $this.html('<div></div>');
                var div = $("div", $this);

                div.append('<a>A</a>').append('<a>B</a>').append('<a>C</a>');

                div.children("a").each(function (i) {
                    $(this).click(function (event) {
                        // Here I store the index.
                        $this.data($(this).index());
                        event.preventDefault();
                        return false;
                    });
                });

                return $this;
            } else if (action == "getSelection") {
                // With this action, I tried to get the stored value.
                return $this.data("selectedValue");
            }
        });
    };
})(jQuery);

Simple call to create the elements:

$("#someElement").myPlugin();

And here I'd tried to get the index, without sucess:

alert($("#someElement").myPlugin("getSelection"));

So, is possible to do what I'm trying?

A: 

I believe this line is where your problem starts

if (action == null) action = "initialize";

as if you call the plugin without specifying a parameter, action will be undefined (not null).

you could consider changing this to

if (!(action)) action = "initialize";

Edit: Having looked further, I think the issue is that when you set the data you never give it a key according to the Documentation of .data() method

Store the data using:

$this.data("selectedValue",$(this).index());

and retrieve it like this:

$('#plugin-container').data("selectedValue")

see working fiddle here --> http://jsfiddle.net/7MAUv/

Jamiec
Thanks by pointing about the undefined, but it could affect just the initialization. The return when the correct action is set isn't solved.
ErickPetru
But with the initialisation not working, you'll never get the new elements, never attach the click events and never set the data. Therefore, you'll never get the selection later on when calling with the getSelection parameter.
Jamiec
+1  A: 

You need to change up the order a bit, like this:

(function ($) {
    $.fn.myPlugin = function (action) {
        action = action || "initialize";

        if (action == "getSelection") {
          return this.data('index');
        }

        return this.each(function ($this) {
            $this = $(this);

            if (action == "initialize") {
                $this.html('<div></div>');
                var div = $("div", $this);

                div.append('<a>A</a>').append('<a>B</a>').append('<a>C</a>');

                div.children("a").each(function (i) {
                    $(this).click(function (event) {
                        // Here I store the index.
                        $this.data('index', $(this).index());
                        event.preventDefault();
                        return false;
                    });
                });

                return $this;
            }
        });
    };
})(jQuery);

The you can get the clicked index out like this:

alert($("#someElement").myPlugin("getSelection"));

You can give it a try here, the fundamental problem is you're trying to return a single value out of a .each() loop, which doesn't work. This instead grabs the data off the first object that matches the selector (#someElement in the example). Also .data() stores other things, so you need to give your value a key, like I'm using 'index' in the version above.

Nick Craver