2

I am trying to write an extension to jQuery, whereby you can pass methods by strings, and apply these methods to the element specified. However, I cannot understand how calling a method this way can determine the options that were originally set when the method was called.

Consider this (using jQuery UI as example):

$('#foo').datepicker({ someoption: true });

$('#foo').datepicker('setDate','10/10/2013');

How does the second call know what someoption is set too?

If, for instance, the someoption was dateFormat then the datepicker would automatically change the format of the supplied date to match the format specified in formatDate... How does the second call know what the value of formatDate is?

The only way I can see how this is achieved is like so (obviously missing a few details):

var datepickers = new Array();

$.fn.datepicker = datepicker;
function datepicker(options){
    // Get the selector somehow
    var selector = somefunction($(this));
    // Save the options to the datepickers array
    // for the given selector
    datepickers[selector] = options;
}

Is this the correct way to go about achieving this? If so, how does one get the selector and is it reliable (potential solution to this part here)?

Community
  • 1
  • 1
Ben Carey
  • 16,540
  • 19
  • 87
  • 169
  • 1
    Have you had a look at the source of the plugin? – Felix Kling Jun 05 '13 at 09:57
  • @FelixKling Theres a thought!! hahaha, can't believe I didnt think of that! I only used the `datepicker` as an example but I guess the solution would lie in there! Either way, if anybody does have any opinions or potential solutions, I would still be keen to see :-) – Ben Carey Jun 05 '13 at 10:03

1 Answers1

2

The only way I can see how this is achieved is like so

Yeah, storing them in a static variable in the plugin's scope is one way. However: You need a reliable way to determine a unique selector for all DOM elements (your somefunction), and you will run into memory leaks since you do not know when you can un-store the information.

Instead, most plugins do use the standard jQuery .data() method, which will take care of both issues. From the datepicker source:

// in the init function:
$.data(target, "datepicker", inst);

// in other methods:
var inst = $.data(target, "datepicker");

Other ways (just for completeness): Store the data directly on properties of the DOM object (which can cause memory leaks on certain known browsers), or returning a widget instance object from the method (instead of the chainable jQuery wrapper - which requires a different invocation strategy than the one you requested).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • That is exactly the sort of thing I was looking for, thank you! Could you possibly post an example of this? – Ben Carey Jun 05 '13 at 10:11
  • Would it be something like this: `$(this).data('datepicker',options);`? – Ben Carey Jun 05 '13 at 10:18
  • @BenCarey Take a look at [jQuery UI's Widget](https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js), the base class for all UI components in the library. The [`$.widget.bridge`](https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js#L165) method takes care of creating a method on `$.fn` which either creates a widget instance or calls a method of the current instance. – Mattias Buelens Jun 05 '13 at 10:26
  • @BenCarey Yes, that's also how jQuery UI does it. For reading it uses [`$.data(this, name)`](https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js#L202) and for writing it uses [`$.data(this, name, new object(...))`](https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js#L206) (where `object` is the widget's constructor). – Mattias Buelens Jun 05 '13 at 10:29
  • @BenCarey: Yes, exactly. Though most plugins do use the "internal" [`jQuery.data`](http://api.jquery.com/jQuery.data/) function directly. – Bergi Jun 05 '13 at 10:31