Project

General

Profile

Download (8.7 KB) Statistics
| Branch: | Tag: | Revision:
1
// see also https://github.com/geetarista/jquery-plugin-template/blob/master/jquery.plugin-template.js
2

    
3
// the semi-colon before function invocation is a safety net against concatenated
4
// scripts and/or other plugins which may not be closed properly.
5
;(function($, document, window, undefined) {
6

    
7
  // Optional, but considered best practice by some
8
  "use strict";
9

    
10
  // Name the plugin so it's only in one place
11
  var pluginName = 'utis_client';
12

    
13
  // Default options for the plugin as a simple object
14
  var defaults = {
15
    providers: {'bgbm-phycobank': 'PhycoBank', 'diatombase' : 'DiatomBase', 'worms': 'WoRMS'},
16
    // webserviceUrl : 'https://cybertaxonomy.eu/eu-bon/utis/1.3',
17
    webserviceUrl : 'http://test.e-taxonomy.eu/eubon-utis',
18
    pageSize: 20,
19
    spinnerIcon: null
20
  };
21

    
22
  // Plugin constructor
23
  // This is the boilerplate to set up the plugin to keep our actual logic in one place
24
  function Plugin(element, options) {
25
    this.element = element;
26
    this.formItemQueryText = null;
27
    this.formItemProviderCheckboxes = null;
28
    this.formItemProviderSeachMode = null;
29
    this.resultContainer = null;
30
    this.spinnerContainer = null;
31
    this.pageIndex = 0;
32
    this.autoLoadTolerance = 20; // start autoloading x pixels before the bottom of the result container
33

    
34
    // firebug console stub (avoids errors if firebug is not active)
35
    if (typeof console === "undefined") {
36
      console = {
37
        log: function () {
38
        }
39
      };
40
    }
41

    
42
    // Merge the options given by the user with the defaults
43
    this.options = $.extend({}, defaults, options);
44

    
45
    // Attach data to the elment
46
    this.$el      = $(element);
47
    this.$el.data(name, this);
48

    
49
    this._defaults = defaults;
50

    
51
    var meta      = this.$el.data(name + '-opts');
52
    this.opts     = $.extend(this._defaults, options, meta);
53

    
54
    // Initialization code to get the ball rolling
55
    // If your plugin is simple, this may not be necessary and
56
    // you could place your implementation here
57
    this.init();
58
  }
59

    
60

    
61
  Plugin.prototype = {
62
    // Public functions accessible to users
63
    // Prototype methods are shared across all elements
64
    // You have access to this.options and this.element
65
    // If your plugin is complex, you can split functionality into more
66
    // methods like this one
67

    
68
    init: function () {
69
      // Plugin initializer - prepare your plugin
70

    
71
      var plugin = this;
72
      var form = $("<form/>",
73
        {
74
          style: 'vertical-align: top;'
75
        }
76
      );
77

    
78
      this.formItemQueryText = $("<input/>",
79
        {
80
          type: 'text',
81
          placeholder: 'scientific name query string',
82
          name: 'query',
83
          // value: "Navicula", // search term preset for testing
84
          style: 'width:100%'
85
        }
86
      ).keypress(function(event){
87
        if ( event.which == 13 ) { // 13 = ENTER
88
          event.preventDefault();
89
          form.submit();
90
        }
91
      });
92

    
93
      var checkBoxesDiv = $('<div/>',
94
        {
95
          'class': 'checkboxes',
96
           style: 'display: inline-block; width:30%; vertical-align: top;'
97
        });
98
      var checkboxesArray = [];
99
      $.each(Object.keys(plugin.options.providers), function (index, key) {
100
        var checkbox_id = 'checkbox_' + key;
101
        var checkbox =   $("<input/>",
102
          {
103
            type: 'checkbox',
104
            name: 'provider',
105
            checked: index == 0 ? 'checked' : '',
106
            value: key,
107
            id:  checkbox_id
108
          }
109
        );
110
        var label = $('<label for="' + checkbox_id + '" style="display: inline-block; vertical-align: top;">&nbsp;' +  plugin.options.providers[key] + '</label><br/>');
111
        // label.append(checkbox);
112
        checkBoxesDiv.append(checkbox).append(label);
113

    
114
        checkboxesArray.push(checkbox);
115
      });
116

    
117
      this.formItemProviderCheckboxes = checkboxesArray;
118

    
119
      var submit = $("<input/>",
120
        {
121
          type: 'submit',
122
          value: 'Search',
123
          style: 'width:100%; margin-top: 1em;'
124
        }
125
      );
126

    
127
      this.resultContainer = $('<div/>',
128
        {
129
          'class': 'results',
130
          style: 'overflow-y: auto; height: 20em; border: inset 1px rgb(239, 240, 241); margin-top: 1em;'
131
        }
132
        ).hide().bind('scroll', function() {
133
          if($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight - plugin.autoLoadTolerance) {
134
            plugin.pageIndex++;
135
            plugin.executeQuery(plugin);
136
          }
137
        });
138

    
139

    
140
      form.append($('<div />', {style: 'width: 30%; display: inline-block; vertical-align: top; padding-right: 1em;'}).append(this.formItemQueryText).append(submit));
141
      form.append(checkBoxesDiv);
142
      // form.append(submit);
143

    
144
      form.submit(function(event){
145
        event.stopPropagation();
146
        event.preventDefault();
147
        // reset the page index when the form was submitted
148
        plugin.pageIndex = 0;
149
        plugin.executeQuery(plugin);
150
        return false;
151

    
152
      });
153
      this.$el.append(form);
154
      this.$el.append(this.resultContainer);
155
      this.spinnerContainer = $('<div class="spinner" style="position: relative; bottom: 50px; width: 100%; height: 50px; margin: auto; text-align: center;"></div>');
156
      this.spinnerContainer.hide();
157
      this.resultContainer.append(this.spinnerContainer);
158
      if(this.options.spinnerIcon !== undefined){
159
        var icon = $(this.options.spinnerIcon);
160
        this.spinnerContainer.append(icon);
161
      }
162
    },
163

    
164
  /**
165
   *
166
   * @returns {string}
167
   */
168
  providerSelection: function(){
169
    var checkboxes = this.formItemProviderCheckboxes;
170
    return function(){
171
    var providerSelection = [];
172
      $.each(checkboxes, function (index, checkbox) {
173
        if(checkbox.is(':checked')){
174
          providerSelection.push(checkbox.attr('value'));
175
        }
176
      });
177
      return providerSelection.join(',');
178
    }
179
  },
180

    
181
  /**
182
   *
183
   * @returns {string}
184
   */
185
  queryString: function(){
186
    var textField = this.formItemQueryText;
187
    return function(){
188
     return textField.val();
189
    }
190
  },
191

    
192
  /**
193
   *
194
   * @param plugin
195
   */
196
  executeQuery: function (plugin) {
197

    
198
    plugin.resultContainer.show();
199
    plugin.spinnerContainer.show();
200
    $.getJSON(plugin.options.webserviceUrl + '/search',
201
      {
202
        providers: plugin.providerSelection(), // Closure!
203
        searchMode: 'scientificNameLike',
204
        query: plugin.queryString(), // Closure!
205
        pageSize: plugin.options.pageSize,
206
        pageIndex: plugin.pageIndex
207
      },
208
      function (tnrMsg, textStatus, jqXHR) {
209
        if(plugin.pageIndex === 0){
210
          plugin.resultContainer.empty();
211
          plugin.resultContainer.append(plugin.spinnerContainer);
212
        }
213
        // in UTIS there is always only one query
214
        var response = tnrMsg.query[0].response;
215
        var count = 0;
216
        $.each(response, function (index, record) {
217
          if(record.matchingNameString !== null){
218
            // ignore deleted names (WoRMS, DiatomBase)
219
            plugin.spinnerContainer.before(plugin.makeResultEntry(record));
220
            count++;
221
          }
222
        });
223
        if(count === 0){
224
          plugin.spinnerContainer.before($('<div/>', {'class': 'no-results', style: 'height: 100%; text-align: center; v-align: middle;'}).text("No results."))
225
        }
226
        plugin.spinnerContainer.hide();
227
      });
228
  },
229

    
230
  makeResultEntry: function (record) {
231

    
232
    var resultEntry = $('<div/>', {'class': 'result-entry'});
233
    resultEntry.append($('<div/>', {'class': 'matching-name', style: 'font-weight: bold;'}).text(record.matchingNameString));
234

    
235
    var relation = record.matchingNameType;
236
    var taxonName = record.taxon.taxonName.scientificName;
237
    if(relation !== undefined){
238
      relation = relation.toLowerCase();
239
      if(relation !== 'taxon') {
240
        resultEntry
241
          .append($('<span/>', {'class': 'relation', style: 'opacity: 0.5;'}).text(relation + ' for '))
242
          .append($('<span/>', {'class': 'taxon'}).text(taxonName));
243
      }
244
      resultEntry.append($('<div/>', {'class': 'checklist', style: 'opacity: 0.5; '}).text('Checklist: ') // text-align: right?
245
          .append($('<a/>', { href: record.checklistUrl, target: 'checklist'}).text(record.checklist)
246
          )
247
      );
248
    }
249

    
250
    return resultEntry;
251
  }
252

    
253
  }; // END of  Plugin.prototype
254

    
255
  $.fn[pluginName] = function(options) {
256
    // Iterate through each DOM element and return it
257
    return this.each(function() {
258
      // prevent multiple instantiations
259
      if (!$.data(this, 'plugin_' + pluginName)) {
260
        $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
261
      }
262
    });
263
  };
264

    
265
  // ---------------------
266

    
267
    /*
268
    function getFootnoteClassName(object){
269
      return '.'+$(object).attr('href').substr(1);
270
    }
271

    
272
    function getFootnoteKeyClassName(object){
273
      return '.'+$(object).attr('href').substr(1).replace(/-/gi, '-key-') + ' a';
274
    }
275
    */
276

    
277

    
278
})(jQuery, document, window);
    (1-1/1)