manifold: imprved plugin class with helpers for naming HTML tags in plugins
[myslice.git] / manifold / js / plugin.js
1 // INHERITANCE
2 // http://alexsexton.com/blog/2010/02/using-inheritance-patterns-to-organize-large-jquery-applications/
3 // We will use John Resig's proposal
4
5 // http://pastie.org/517177
6
7 // NOTE: missing a destroy function
8
9 $.plugin = function(name, object) {
10     $.fn[name] = function(options) {
11         var args = Array.prototype.slice.call(arguments, 1);
12         return this.each(function() {
13             var instance = $.data(this, name);
14             if (instance) {
15                 instance[options].apply(instance, args);
16             } else {
17                 instance = $.data(this, name, new object(options, this));
18             }
19         });
20     };
21 };
22
23 var Plugin = Class.extend({
24
25     init: function(options, element)
26     {
27         // Mix in the passed in options with the default options
28         this.options = $.extend({}, this.default_options, options);
29
30         // Save the element reference, both as a jQuery
31         // reference and a normal reference
32         this.element  = element;
33         this.$element = $(element);
34
35         // return this so we can chain/use the bridge with less code.
36         return this;
37     },
38
39     has_query_handler: function() {
40         return (typeof this.on_filter_added === 'function');
41     },
42
43     _query_handler: function(e, event_type, data)
44     {
45         // We suppose this.query_handler_prefix has been defined if this
46         // callback is triggered    
47         var fn;
48         switch(event_type) {
49             case FILTER_ADDED:
50                 fn = 'filter_added';
51                 break;
52             case FILTER_REMOVED:
53                 fn = 'filter_removed';
54                 break;
55             case CLEAR_FILTERS:
56                 fn = 'filter_clear';
57                 break;
58             case FIELD_ADDED:
59                 fn = 'field_added';
60                 break;
61             case FIELD_REMOVED:
62                 fn = 'field_removed';
63                 break;
64             case CLEAR_FIELDS:
65                 fn = 'field_clear';
66                 break;
67             default:
68                 return;
69         } // switch
70         
71         fn = 'on_' + this.query_handler_prefix + fn;
72         if (typeof this[fn] === 'function') {
73             // call with data as parameter
74             // XXX implement anti loop
75             this[fn](data);
76         }
77     },
78
79     listen_query: function(query_uuid, prefix) {
80         this.query_handler_prefix = (typeof prefix === 'undefined') ? '' : (prefix + '_');
81         this.$element.on(manifold.get_query_channel(query_uuid), $.proxy(this._query_handler, this));
82     },
83
84     default_options: {},
85
86     id: function()
87     {
88         var ret = this.options.plugin_uuid;
89         for (var i = 0; i < arguments.length; i++) {
90             ret = ret + manifold.separator + arguments[i];
91         }
92         return ret;
93     },
94
95     el: function()
96     {
97         if (arguments.length == 0) {
98             return $('#' + this.id());
99         } else {
100             // We make sure to search _inside_ the dom tag of the plugin
101             return $('#' + this.id.apply(this, arguments), this.el());
102         }
103     },
104
105     els: function(cls)
106     {
107         return $('.' + cls, this.el());
108     },
109
110     id_from_filter: function(filter, use_value)
111     {
112         use_value = typeof use_value !== 'undefined' ? use_value : true;
113
114         var key    = filter[0];
115         var op     = filter[1];
116         var value  = filter[2];
117         var op_str = this.getOperatorLabel(op);
118         var s      = manifold.separator;
119
120         if (use_value) {
121             return 'filter' + s + key + s + op_str + s + value;
122         } else {
123             return 'filter' + s + key + s + op_str;
124         }
125     },
126
127     str_from_filter: function(filter)
128     {
129         return filter[0] + ' ' + filter[1] + ' ' + filter[2];
130     },
131
132 });