Project

General

Profile

Download (9.86 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: {
16
      'bgbm-phycobank': 'PhycoBank',
17
      'diatombase' : 'DiatomBase',
18
      'worms': 'WoRMS'
19
      //'pesi': 'PESI'
20
    },
21
    webserviceUrl : 'https://cybertaxonomy.eu/eu-bon/utis/1.3',
22
    // webserviceUrl : 'http://test.e-taxonomy.eu/eubon-utis',
23
    //  webserviceUrl : 'http://localhost:8081/',
24
    pageSize: 20,
25
    spinnerIcon: null
26
  };
27

    
28
  // Plugin constructor
29
  // This is the boilerplate to set up the plugin to keep our actual logic in one place
30
  function Plugin(element, options) {
31
    this.element = element;
32
    this.formItemQueryText = null;
33
    this.formItemProviderCheckboxes = null;
34
    this.formItemProviderSeachMode = null;
35
    this.resultContainer = null;
36
    this.spinnerContainer = null;
37
    this.pageIndex = 0;
38
    this.autoLoadTolerance = 20; // start autoloading x pixels before the bottom of the result container
39
    this.externalLinkIconMarkup = '[open]';
40

    
41
    // firebug console stub (avoids errors if firebug is not active)
42
    if (typeof console === "undefined") {
43
      console = {
44
        log: function () {
45
        }
46
      };
47
    }
48

    
49
    // Merge the options given by the user with the defaults
50
    this.options = $.extend({}, defaults, options);
51

    
52
    // Attach data to the elment
53
    this.$el      = $(element);
54
    this.$el.data(name, this);
55

    
56
    this._defaults = defaults;
57

    
58
    var meta      = this.$el.data(name + '-opts');
59
    this.opts     = $.extend(this._defaults, options, meta);
60

    
61
    // Initialization code to get the ball rolling
62
    // If your plugin is simple, this may not be necessary and
63
    // you could place your implementation here
64
    this.init();
65
  }
66

    
67

    
68
  Plugin.prototype = {
69
    // Public functions accessible to users
70
    // Prototype methods are shared across all elements
71
    // You have access to this.options and this.element
72
    // If your plugin is complex, you can split functionality into more
73
    // methods like this one
74

    
75
    init: function () {
76
      // Plugin initializer - prepare your plugin
77

    
78
      var plugin = this;
79
      var form = $("<form/>",
80
        {
81
          style: 'vertical-align: top;'
82
        }
83
      );
84

    
85
      this.formItemQueryText = $("<input/>",
86
        {
87
          type: 'text',
88
          placeholder: 'scientific name query string',
89
          name: 'query',
90
          // value: "Navicula", // search term preset for testing
91
          style: 'width:100%'
92
        }
93
      ).keypress(function(event){
94
        if ( event.which == 13 ) { // 13 = ENTER
95
          event.preventDefault();
96
          form.submit();
97
        }
98
      });
99

    
100
      var checkBoxesDiv = $('<div/>',
101
        {
102
          'class': 'checkboxes',
103
           style: 'display: inline-block; width:30%; vertical-align: top;'
104
        });
105
      var checkboxesArray = [];
106
      $.each(Object.keys(plugin.options.providers), function (index, key) {
107
        var checkbox_id = 'checkbox_' + key;
108
        var disabled = key == '--unused--'; // the disable state has been used for worms
109
        var checkbox =   $("<input/>",
110
          {
111
            type: 'checkbox',
112
            name: 'provider',
113
            checked: index == 0 ? 'checked' : '',
114
            value: key,
115
            id:  checkbox_id,
116
            disabled: disabled
117
          }
118
        );
119
        var label = $('<label for="' + checkbox_id + '" style="display: inline-block; vertical-align: top; ' + (disabled ? 'color:#bbbbbb;': '') + '">&nbsp;' +  plugin.options.providers[key] + '</label><br/>');
120
        // label.append(checkbox);
121
        checkBoxesDiv.append(checkbox).append(label);
122
        if(disabled){
123
          checkBoxesDiv.append($('<div style="font-size:small; color:#bbbbbb;">' + plugin.options.providers[key] + ' disabled due to unresolved potential copyright issues.</div>'))
124
        }
125
        if(  key == 'worms'){
126
          checkBoxesDiv.append($('<div style="font-size:small; color:#bbbbbb;">WoRMS includes data from different databases. Please consider data sources, data citations, and licensing as given by WoRMS.</div>'));
127
        }
128

    
129
        checkboxesArray.push(checkbox);
130
      });
131

    
132
      this.formItemProviderCheckboxes = checkboxesArray;
133

    
134
      var submit = $("<input/>",
135
        {
136
          type: 'submit',
137
          value: 'Search',
138
          style: 'width:100%; margin-top: 1em;'
139
        }
140
      );
141

    
142
      this.resultContainer = $('<div/>',
143
        {
144
          'class': 'results',
145
          style: 'overflow-y: auto; height: 20em; border: inset 1px rgb(239, 240, 241); margin-top: 1em;'
146
        }
147
        ).hide().bind('scroll', function() {
148
          if($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight - plugin.autoLoadTolerance) {
149
            plugin.pageIndex++;
150
            plugin.executeQuery(plugin);
151
          }
152
        });
153

    
154

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

    
159
      form.submit(function(event){
160
        event.stopPropagation();
161
        event.preventDefault();
162
        // reset the page index when the form was submitted
163
        plugin.pageIndex = 0;
164
        plugin.executeQuery(plugin);
165
        return false;
166

    
167
      });
168
      this.$el.append(form);
169
      this.$el.append(this.resultContainer);
170
      this.spinnerContainer = $('<div class="spinner" style="position: relative; bottom: 50px; width: 100%; height: 50px; margin: auto; text-align: center;"></div>');
171
      this.spinnerContainer.hide();
172
      this.resultContainer.append(this.spinnerContainer);
173
      if(this.options.spinnerIcon !== undefined){
174
        var icon = $(this.options.spinnerIcon);
175
        this.spinnerContainer.append(icon);
176
      }
177
      if(this.options.externalLinkIcon !== undefined){
178
        this.externalLinkIconMarkup = this.options.externalLinkIcon;
179
      }
180
    },
181

    
182
  /**
183
   *
184
   * @returns {string}
185
   */
186
  providerSelection: function(){
187
    var checkboxes = this.formItemProviderCheckboxes;
188
    return function(){
189
    var providerSelection = [];
190
      $.each(checkboxes, function (index, checkbox) {
191
        if(checkbox.is(':checked')){
192
          providerSelection.push(checkbox.attr('value'));
193
        }
194
      });
195
      return providerSelection.join(',');
196
    }
197
  },
198

    
199
  /**
200
   *
201
   * @returns {string}
202
   */
203
  queryString: function(){
204
    var textField = this.formItemQueryText;
205
    return function(){
206
     return textField.val();
207
    }
208
  },
209

    
210
  /**
211
   *
212
   * @param plugin
213
   */
214
  executeQuery: function (plugin) {
215

    
216
    plugin.resultContainer.show();
217
    plugin.spinnerContainer.show();
218
    $.getJSON(plugin.options.webserviceUrl + '/search',
219
      {
220
        providers: plugin.providerSelection(), // Closure!
221
        searchMode: 'scientificNameLike',
222
        query: plugin.queryString(), // Closure!
223
        pageSize: plugin.options.pageSize,
224
        pageIndex: plugin.pageIndex
225
      },
226
      function (tnrMsg, textStatus, jqXHR) {
227
        if(plugin.pageIndex === 0){
228
          plugin.resultContainer.empty();
229
          plugin.resultContainer.append(plugin.spinnerContainer);
230
        }
231
        // in UTIS there is always only one query
232
        var response = tnrMsg.query[0].response;
233
        var count = 0;
234
        $.each(response, function (index, record) {
235
          if(record.matchingNameString !== null){
236
            // ignore deleted names (WoRMS, DiatomBase)
237
            plugin.spinnerContainer.before(plugin.makeResultEntry(record));
238
            count++;
239
          }
240
        });
241
        if(count === 0 && plugin.pageIndex === 0){
242
          plugin.spinnerContainer.before($('<div/>', {'class': 'no-results', style: 'height: 100%; text-align: center; v-align: middle;'}).text("No results."))
243
        }
244
        plugin.spinnerContainer.hide();
245
      });
246
  },
247

    
248
  makeResultEntry: function (record) {
249

    
250
    var resultEntry = $('<div/>', {'class': 'result-entry'});
251
    var taxonContainer = $('<div/>');
252
    taxonContainer.append($('<span/>', {'class': 'matching-name', style: 'font-weight: bold; padding-right: 0.3em;'}).text(record.matchingNameString));
253
    if(record.taxon.url){
254
      taxonContainer.append($('<a/>', {href: record.taxon.url, target: 'provider'}).append($(this.externalLinkIconMarkup)));
255
    }
256
    resultEntry.append(taxonContainer);
257

    
258
    var relation = record.matchingNameType;
259
    var taxonName = record.taxon.taxonName.scientificName;
260
    if(relation !== undefined){
261
      relation = relation.toLowerCase();
262
      if(relation !== 'taxon') {
263
        resultEntry
264
          .append($('<span/>', {'class': 'relation', style: 'opacity: 0.5;'}).text(relation + ' for '))
265
          .append($('<span/>', {'class': 'taxon'}).text(taxonName));
266
      }
267
      resultEntry.append($('<div/>', {'class': 'checklist', style: 'opacity: 0.5; '}).text('Checklist: ') // text-align: right?
268
          .append($('<a/>', { href: record.checklistUrl, target: 'provider'}).text(record.checklist)
269
          )
270
      );
271
    }
272

    
273
    return resultEntry;
274
  }
275

    
276
  }; // END of  Plugin.prototype
277

    
278
  $.fn[pluginName] = function(options) {
279
    // Iterate through each DOM element and return it
280
    return this.each(function() {
281
      // prevent multiple instantiations
282
      if (!$.data(this, 'plugin_' + pluginName)) {
283
        $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
284
      }
285
    });
286
  };
287

    
288
  // ---------------------
289

    
290
    /*
291
    function getFootnoteClassName(object){
292
      return '.'+$(object).attr('href').substr(1);
293
    }
294

    
295
    function getFootnoteKeyClassName(object){
296
      return '.'+$(object).attr('href').substr(1).replace(/-/gi, '-key-') + ' a';
297
    }
298
    */
299

    
300

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