expose each query ONCE to js, plugin gets initialized with query_uuid only
[unfold.git] / plugins / quickfilter / quickfilter.js
1 /**
2  * MySlice QuickFilter plugin
3  * URL: http://trac.myslice.info
4  * Description: editing search filters
5  * Author: The MySlice Team
6  * Copyright (c) 2012 UPMC Sorbonne Universite - INRIA
7  * License: GPLv3
8  */
9
10 ( function($){
11
12     var debug=false;
13     //debug=true;
14
15     $.fn.QuickFilter = function( method ) {
16         /* Method calling logic */
17         if ( methods[method] ) {
18             return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
19         } else if ( typeof method === 'object' || ! method ) {
20             return methods.init.apply( this, arguments );
21         } else {
22             $.error( 'Method ' +  method + ' does not exist on $.QuickFilter' );
23         }    
24     };
25
26
27     var methods = {
28
29         init : function( options ) {
30             return this.each(function(){
31                 
32                 var $this = $(this),
33                 data = $this.data('QuickFilter'), QuickFilter = $('<div />', {text : $this.attr('title')});
34                 
35                 if ( ! data ) {
36                     
37                     data = $(this).data();
38
39                     /* Subscribe to selection updates published by the resource display plugins */
40                     //$.subscribe('selected', {instance: $this}, resource_selected);
41                     $.subscribe('/query/' + options.query_uuid + '/changed', {instance: $this}, query_changed);
42
43
44                     /* End of plugin initialization */
45
46                     $(this).data('QuickFilter', {
47                         plugin_uuid: options.plugin_uuid,
48                         query_uuid: options.query_uuid,
49                         target : $this,
50                         QuickFilter : QuickFilter
51                     });
52
53                     $(this).data('current_query', null);
54
55                     initialize_plugin($(this).data());
56                     
57                     function update_options(e, rows){
58                         var d = data;
59                         var availableTags={};
60                         $.each (rows, function(index, obj) {
61                             $.each(obj,function(key,value){                       
62                                 value = get_value(value);
63                                 if(!availableTags.hasOwnProperty(key)){availableTags[key]=new Array();}
64                                 //availableTags[key].push(value);
65                                 var currentArray=availableTags[key];
66                                 if(value!=null){
67                                     if($.inArray(value,currentArray)==-1){availableTags[key].push(value);}
68                                 }
69                             });                    
70                         });                
71                         $.each(availableTags, function(key, value){
72                             value.sort();
73                             if($("#"+options.plugin_uuid+"-select_"+key).length>0){
74                                 $.each(value, function(k, optValue){
75                                     $("#"+options.plugin_uuid+"-select_"+key).append('<option>'+optValue+'</option>');
76                                 });
77                             }                    
78                             if($("#QuickFilter-string-"+key).length>0){
79                                 $("#QuickFilter-string-"+key).autocomplete({
80                                     source: value,
81                                     minLength: 0, // allows to browse items with no value typed in
82                                     select: function(event, ui) {
83                                         //var key=getKeySplitId(this.id,"-");
84                                         var op='=';
85                                         var val=ui.item.value;
86
87                                         query=d.current_query;
88                                         query.update_filter(key,op,val);
89                                         // Publish the query changed, the other plugins with subscribe will get the changes
90                                         $.publish('/query/' + query.query_uuid + '/changed', query);
91                                         //add_ActiveFilter("#QuickFilter-string-"+key,ui.item.value,d);
92                                     }
93                                 });
94                             }
95                         });   
96                         
97                         
98                     }     
99                     
100                     /* Subscribe to results in order to redraw the table when updates arrive */
101                     $.subscribe('/results/' + options.query_uuid + '/changed', {instance: $this}, update_options);
102                 }
103
104             });
105         },
106         destroy : function( ) {
107
108             return this.each(function(){
109                 var $this = $(this), data = $this.data('QuickFilter');
110                 $(window).unbind('QuickFilter');
111                 data.QuickFilter.remove();
112                 $this.removeData('QuickFilter');
113             })
114
115                 },
116         update : function( content ) { 
117         },
118     };
119
120     /* Private methods */
121
122     function query_changed(e, query) {
123         //panos: this takes a lot of time!
124         data = e.data.instance.data();
125         var plugin_uuid=data.QuickFilter.plugin_uuid;
126         
127         /* Compare current and advertised query to get added and removed fields */
128         var previous_query=data.current_query;
129         /* Save the query as the current query */
130         data.current_query=query;
131         
132         // XXX can we modify data directly ?
133         //$(data.QuickFilter.target).data('current_query', query);
134
135         if(previous_query!=null){
136             // If query has changed in another plugin
137             // set the value on each filter that exists in QuickFilter plugin          
138             if (typeof(previous_query) != 'undefined') {
139                 var tmp=previous_query.diff_filter(query);
140                 // Remove first to clean up select boxes
141                 var removed_filters = tmp.removed;
142                 $.each(removed_filters, function(i,filter){
143                     console.log(filter[0]);
144                     allowedValues=getMetadata_property('resource', filter[0], 'allowed_values');
145                     if (allowedValues!='' && allowedValues!="N/A") {
146                         //if(MANIFOLD_METADATA[filter[0]]['allowed_values']!=''){
147                         $('#QuickFilter_select_field').val("#");
148                         $('#QuickFilter_select_value').children().remove().end();
149                         $('#QuickFilter_select_value_container').hide();
150                     }
151                     if($('#'+plugin_uuid+'-select_'+filter[0]).length>0 && filter[1]=="="){
152                         $('#'+plugin_uuid+'-select_'+filter[0]).val(null);
153                     }
154                     if($("#QuickFilter-string-"+filter[0]).length>0 && filter[1]=="="){
155                         $("#QuickFilter-string-"+filter[0]).val(null); 
156                     }
157                 });
158                 // Then Add filters
159                 var added_filters = tmp.added;
160                 $.each(added_filters, function(i,filter){
161                     if($('#'+plugin_uuid+'-select_'+filter[0]).length>0 && filter[1]=="="){
162                         $('#'+plugin_uuid+'-select_'+filter[0]).val(filter[2]);
163                     }
164                     if($("#QuickFilter-string-"+filter[0]).length>0 && filter[1]=="="){
165                         $("#QuickFilter-string-"+filter[0]).val(filter[2]); 
166                     }
167                 });
168             }
169             $.publish('debug', "Quick Filter received fields: " + query.fields+" - filter = "+query.filter);
170         }
171     }
172     
173     function initialize_plugin(data) {
174
175         $('#QuickFilter_select_value_div').hide();
176         $('#QuickFilter_string_value_div').hide();
177         $('#QuickFilter_int_value_div').hide();
178
179         $('#QuickFilter_only_visible').click( function () {
180
181             var only_visible = this.checked;
182             // Clear all options in the select box, Then add None option
183             $('#QuickFilter_select_field').children().remove().end().append("<option value='#'>None</option>");
184             
185             // Get the current query (ONLY AFTER THE PLUGIN HAS BEEN INITIALIZED)
186             var query = data.current_query;
187             // iterate to remove each active filter
188             if (only_visible) {
189                 if (typeof(query.fields) != 'undefined') {
190                     $.each (query.fields, function(index, value) {
191                         $('#QuickFilter_select_field').append("<option>"+value+"</option>");  
192                     });            
193                 }
194             }else{
195                 headers=getMetadata_fields('resource');
196                 $.each (headers, function (key, value) {
197                     $('#QuickFilter_select_field').append("<option>"+value['column']+"</option>");
198                 });
199             }
200         });
201
202         $('#QuickFilter_select_field').change( function () {
203             var field = $(this).val();
204             console.log(field);
205             $('input[id^="QuickFilter-string-"]').hide();
206             $('#QuickFilter_int_value_div').hide();
207             if(field=="#"){
208                 $('#QuickFilter_select_value_container').hide();
209             }else{
210                 $('#QuickFilter_select_value_container').show();
211                 $.publish('debug','field selected = '+field);
212                 valType=getMetadata_property('resource', field, 'value_type');
213                 if (valType == 'string' || valType=="N/A") {
214                     // If this key has predefined values, build a select with each allowed values as options
215                     allowedValues=getMetadata_property('resource', field, 'allowed_values');
216                     if (allowedValues!='' && allowedValues!="N/A") {
217                         $('#QuickFilter_string_value_div').hide();
218                         $('#QuickFilter_int_value_div').hide();
219                         $('#QuickFilter_select_value_div').show();
220                         $('#QuickFilter_select_value').show();
221                         $('#QuickFilter_select_value').children().remove().end().append("<option value=''>all</option>");
222                         // @TODO: define seperator as ;
223                         allowed_values = allowedValues.split(",");
224                         $.each (allowed_values, function (key, value) {
225                             $('#QuickFilter_select_value').append("<option>"+value+"</option>");
226                         });
227                         // Else build an autocomplete based on the values of result query
228                     }else{
229                         $('#QuickFilter_select_value_div').hide();
230                         $('#QuickFilter_string_value_div').show();
231                         $('.QuickFilter-filter-value').hide();
232                         $('#QuickFilter-string-'+field).show();
233                         $('#QuickFilter_int_value_div').hide();
234                     }
235                 }
236                 else if (valType == 'int') {
237                     $('#QuickFilter_select_value_div').hide();
238                     $('#QuickFilter_string_value_div').hide();
239                     $('#QuickFilter_int_value_div').show();
240                 }
241             }
242         });
243
244         $('.QuickFilter-filter-value').change( function () {
245             var query = data.current_query;
246
247             var filter_value = $(this).val();
248             var filter_field = $('#QuickFilter_select_field').val();
249
250             query.update_filter(filter_field, '=', filter_value);
251             $.publish('/query/' + query.query_uuid + '/changed', query);
252         });
253         
254         $('.QuickFilter_select').change( function() {
255             console.log(this.id);
256             var query = data.current_query;
257             var f_value = $(this).val();
258             
259             var key = this.id.split("_");
260
261             // jordan ???
262             /*            
263                           if (f_value == "Network")
264                           f_value = "";
265             */
266             if(typeof(key[1])!="undefined"){
267                 console.log(key[1]+'='+f_value);
268                 if(f_value==""){
269                     query.remove_filter(key[1],"","");
270                 }else{
271                     query.update_filter(key[1], '=', f_value);
272                 }
273             }
274             $.publish('/query/' + query.query_uuid + '/changed', query);
275         });
276
277     }
278
279 })( jQuery );