source: SMC/trunk/SMC/src/web/scripts/js/query_input/qi.js @ 5302

Last change on this file since 5302 was 5302, checked in by xnrn@gmx.net, 10 years ago

added cql-widget (replicated from foreign repo)

File size: 12.7 KB
Line 
1
2// jQuery closure
3(function($) {
4
5/**
6 * @class QueryInput
7 * generate a customizable query_input UI, a input form with fields/widgets based on settings
8 * options: multiple params/fields,
9 * indexes, different widgets
10 *
11 * dependencies: jQuery, jquery-ui: slider, autocomplete
12 
13 * @author vronk, Andy Basch
14 * @version 2013-01-17
15 */
16/* we could make it a class (instead of jQuery plugin)
17       function QueryInput(elem,s) */     
18$.fn.QueryInput = function (options)
19{
20   /** the dom-element to generate the query input in */
21   var elem=this;
22   
23    /** main variable holding all the settings for qi, especially also all params and their allowed values, and their current value
24      * it is constructed here by merging the default and the user options passed as parameter to .QueryInput()
25      */
26   var settings = $.extend(true, {}, defaults, options);
27    blendInParams(settings.params, getUrlParams(location.search)) 
28   
29   // makes the settings publicly available as .data("qi")
30   elem.data("qi",settings); 
31   init(settings);   
32
33  function init(s) {
34    //empty the target element - TODO:optional
35    elem.html('');
36    generateWidgets(s.params, elem);
37  }
38   
39  /** run through the params and generate the widget for every param */
40  function generateWidgets (params, trg_container) {
41       
42        $(trg_container).append("<form />");
43        var form = $(trg_container).find("form");
44       
45      for ( var key in params ) {
46         var param = params[key];
47        // if input already exists - fill it with the default value
48        if ($('#' + settings.input_prefix + key).length) {
49            $('#' + settings.input_prefix + key).value = param.value;   
50         } else if (trg_container)  {
51            var label= param.label ? param.label : key;
52            var new_input_label = param.label=='' ? '' : "<label>" + label+ "</label>";
53            var new_input=null, new_widget=null;
54           
55            switch (param.widget) {
56                case "text":
57                  new_input = genText(key, param);   
58                  break;
59                case "submit":
60                  new_input = genSubmit (key, param);   
61                  break;
62                case "selectone":
63                  new_input = genCombo(key, param);   
64                  break;
65                case "autocomplete":
66                  new_input = genAutocomplete (key, param);   
67                  break;
68               case "cql":
69                  var cql_elems = genCQLInput(key, param);
70                  new_input = cql_elems[0];
71                  new_widget = cql_elems[1]; 
72                  break;
73                case "link":
74                  new_input = genLink (key, param);   
75                  break;
76                case "slider":
77                  var slider_elems = genSlider(key, param);
78                  new_input = slider_elems[0];
79                  new_widget = slider_elems[1]; 
80                  break;
81                default:
82                  console.log("no such widget: " + param.widget); 
83              }   
84       
85          if (new_input) {
86            $(new_input).data("key", key)
87                        .addClass("type-" + param.widget)
88                             .attr("id", settings.input_prefix + key)
89                             .data("param-object", param);
90                     
91            if (param.widget!="link") {
92                 // set initial valuelink
93                 $(new_input).val(param.value);
94                     
95                /* update settings and widgets upon value-change */
96                new_input.change(function () {
97                           setParamValue(this);
98                     });
99               }           
100               
101             $(form).append(new_input_label, new_input, new_widget);
102            // inputs.push(key, new_input_label, new_input, new_widget]);
103           }
104         }
105       } // end for
106       
107       
108    }
109/*
110    function formatForm(inputs) {
111      for ( var key in inputs ) {
112   
113      }
114        <table>
115        </table>
116    }
117*/
118    function genText(key, param_settings) {
119         
120        var input = $("<input />");
121         $(input).attr("name",key);
122         
123        return input;
124    }
125   
126    function genLink(key, param_settings) {
127         
128        var a = $("<a>" + key + "</a>");
129        a.attr("href", generateLink());
130       
131            $(a).mousedown(function(e) {
132                $(this).attr("target", "_blank");
133                $(this).attr("href", generateLink());
134         });
135        return a;
136    }
137   
138    function genSubmit(key, param_settings) {
139         
140        var input = $("<input type='submit'/>");
141         $(input).attr("name",key);
142         $(input).attr("value",param_settings.label);
143        return input;
144    }
145       
146    /** generating our own comboboxes, because very annoying trying to use some of existing jquery plugins (easyui.combo, combobox, jquery-ui.autocomplete) */ 
147    function genCombo (key, param_settings) {
148   
149        var select = $("<select id='widget-" + key + "' />");
150            //select.attr("id", settings.input_prefix + key)
151           
152       if (param_settings.static_source) {
153              //var scanURL = settings.fcs_source +  param_settings.index
154              var source_url = param_settings.static_source.replace(/&amp;/g,'&');
155              // if static source - try to retrieve the data
156              $.getJSON(source_url, function(data) {
157                    param_settings.values = data.terms
158                    param_settings.values.forEach(function(v) { $(select).append("<option value='" + v.value +"' >" + v.label + "</option>") });
159                    //console.log($(input).autocomplete().source);
160              });
161       
162             //param_settings.source = fcsScan;
163        } else if (param_settings.values) {
164            //    $(input).autocomplete(param_settings);
165            if (typeof  param_settings.values[0] ==='object') {// accept format with value and label
166                  param_settings.values.forEach(function(v) { $(select).append("<option value='" + v.value +"' >" + v.label + "</option>") });
167               } else { 
168                   param_settings.values.forEach(function(v) { $(select).append("<option value='" + v +"' >" + v + "</option>") });
169             }
170        } else { /* if no values,  rather make a textbox out of it? */ 
171          //select =
172        }
173       
174        select.attr("id", settings.input_prefix + key)
175        return select;
176    }
177
178    /** generate autocomplete */ 
179    function genAutocomplete (key, param_settings) {
180       
181        var input = $("<input />");
182         $(input).attr("name",key)
183   //     console.log(key, param_settings.static_source);
184        if (param_settings.static_source) {
185              //var scanURL = settings.fcs_source +  param_settings.index
186              var source_url = param_settings.static_source.replace(/&amp;/g,'&');
187              // if static source - try to retrieve the data
188              $.getJSON(source_url, function(data) {
189                    param_settings.source = data.terms
190                    $(input).autocomplete(param_settings);
191                    //console.log($(input).autocomplete().source);
192              });
193       
194             //param_settings.source = fcsScan;
195        } else {
196        $(input).autocomplete(param_settings);
197        }
198         
199        return input;
200    }
201
202   
203    function fcsScan(request, response) {
204        response( $.ui.autocomplete.filter(
205                          scan.terms, request.term ) );
206                                        // extractLast( request.term )
207    }
208         
209    /** generate a slider based on settings
210        @returns an array of two elements: actual input-element with value and a div-container for the slider widget
211    */
212    function genSlider (key, param_settings) {
213
214        var new_input = $("<input />");
215            new_input.attr("id", settings.input_prefix + key)
216                 .val(param_settings.value)
217                 .attr("size", 3);
218     
219        var new_widget = $("<div class='widget-" + param_settings.widget + "'></div>");
220            new_widget.attr("id", "widget-" + key)
221                      .css(settings.slider_style)
222                      .slider( param_settings)
223               
224                        // set both-ways references between the input-field and its slider - necessary for updating
225                        .data("related-input-field",new_input)
226                        .data("related-widget",new_widget);
227                     
228            new_widget.bind( "slidechange", function(event, ui) {
229                $(this).data("related-input-field").val(ui.value);
230                // update the settings-object, but with the (updated) value of the related input-field
231                setParamValue($(this).data("related-input-field"));
232            });
233           
234            /* update the widget upon input value-change (updating the settings-value is handled in the general part */
235            new_input.bind("change", function () {
236                   var related_widget = $(this).data("related-widget");
237                   if ( $(related_widget).hasClass("widget-slider")) {$(related_widget).slider("option", "value", $(this).val()); }
238             });
239             
240           return [new_input,new_widget]; 
241    } 
242   
243   
244    /** gets the current value for a parameter
245        accepting settings as reliable source of current value
246        i.e. changes in input have to change the .value in settings.
247        This is assured by calling setParamValue upon input-change.
248        public by calling: $(elem).data("qi").getParamValue(param_key);
249        @public
250    */
251    settings.getParamValue = function(key) {
252         if (this.params[key])  {
253            return this.params[key].value
254         } else {
255            return ""
256         }
257    }
258
259    /** allow to update the current value in settings from outside */
260    settings.setParamValue = function(key, value) {
261       
262        if (settings.params[key]) {
263            settings.params[key].value = value
264        }
265        // callback:
266        settings.onValueChanged.call( settings,value );
267        return value   
268    }
269   
270    /** update the current value in settings */
271    function setParamValue(input_object) {
272        var param_object = $(input_object).data("param-object");
273        param_object.value= $(input_object).val();
274        var key = $(input_object).data("key");
275        var value = settings.params[key].value;
276       
277        // callback:
278        settings.onValueChanged.call( input_object,value );
279        return value   
280    }
281   
282   
283    /** get params from the uri */
284    function getUrlParams(url)
285    {
286      var urlParams = {};
287      if (url != undefined)
288      {
289        var match;
290        var pl     = /\+/g;  // Regex for replacing addition symbol with a space
291        var search = /([^&=]+)=?([^&]*)/g;
292        var decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); };
293   
294        var query  = "";
295        var qmPos = url.indexOf('?');
296        if (qmPos != -1)
297          query = url.substr(qmPos + 1);
298        else
299          query = url;
300   
301        while (match = search.exec(query))
302           urlParams[decode(match[1])] = decode(match[2]);
303      }
304   
305      return urlParams;
306    }
307
308    function blendInParams(settings_params, params) {
309       
310       for ( var key in settings_params ) {
311            if (params[key]) {settings_params[key].value=params[key]; }     
312       }
313    }
314
315 /** generate a query-link out of the current values of the params */
316    function generateLink()
317    {
318      var url="?";
319     
320       for ( var key in settings.params) {
321           if (settings.params[key].value) {
322                 url += key + "=" + settings.params[key].value + "&"; 
323             }     
324       }
325       
326      return url;
327    }
328
329
330// }   
331 
332}     // end $.fn.QueryInput
333
334   
335    // could expose the defaults: $.fn.QueryInput.defaults =
336    //{q:{label:"Query", widget:"text"}, submit:{value:"Search", widget:"submit"}}
337    var defaults = {params: {},
338                    input_prefix:"input-",
339                    slider_style:{width:"80px", display:"inline-block", "font-size": "70%",  margin: "6px 12px 0 2px"},
340                    onValueChanged : function() {},
341                    fcs_source: "http://193.170.82.207:8680/exist/apps/sade/amc/fcs?operation=scan&x-format=json&scanClause="
342                    };
343   
344    /* TODO: add defaults for widgets, like:
345     widgets: {slider: {style:{width:"80px", display:"inline-block", "font-size": "70%",  margin: "6px 12px 0 2px"}}},
346    */
347
348})(jQuery, this);
349
Note: See TracBrowser for help on using the repository browser.