Project

General

Profile

« Previous | Next » 

Revision 0af3ce28

Added by Andreas Kohlbecker almost 8 years ago

#5887 #5852 classification breadcrumbs navigation implemented

View differences:

modules/cdm_dataportal/js/jquery.cdm.taxonomic_children.js
96 96
       method below).
97 97
       */
98 98
      this.isDataLoaded = false;
99
      this.subTaxonName = undefined;
100 99
      this.buildCache();
101 100
      this.bindEvents();
102 101
    },
......
138 137
        // '0' is used in the cdm_dataportal settings as value for 'no rank limit'
139 138
        this.rankLimitUuid = undefined;
140 139
      }
140
      if(this.$element.hasClass('classification-chooser')){
141
        this.classificationChooser = true;
142
      }
143
      this.destinationUri = this.$element.attr('data-destination-uri');
141 144

  
145
      this.classificationMode =  this.$element.attr('data-cdm-classification-mode');
142 146

  
143
      var nextLiElement = this.$element.parent('li').next();
144
      if(nextLiElement != undefined){
145
        this.subTaxonName = nextLiElement.children('a').text();
147
      if (this.$element.attr('data-cdm-align-with') == 'prev') {
148
        var prev = this.$element.prev();
149
        this.alignOffset = {
150
          'padding': prev.width(),
151
          'left' : prev.width()
152
        }
153
      } else {
154
        this.alignOffset = {
155
          'padding': this.$element.width(),
156
          'left' : '0'
157
        }
146 158
      }
147 159

  
148 160
      // Create new elements
......
175 187

  
176 188
       this works at earliest with v1.7, with 1.4.4 we need to use bind:
177 189
       */
178
      /*plugin.$element.bind('mouseenter', function() { // 'mouseenter' or 'click' are appropriate candidates
190
      plugin.$element.bind('mouseenter', function() { // 'mouseenter' or 'click' are appropriate candidates
179 191
        plugin.showChildren.call(plugin);
180
      });
181
      */
192
       });
182 193

  
183 194
      plugin.$element.bind('click', function (event){
184
        plugin.showChildren.call(plugin);
195
        if(event.target == this){
196
          // prevents eg from executing clicks if the
197
          // trigger element is an <a href=""> element
198
          event.preventDefault();
199
        }
185 200
        event.stopPropagation();
201
        plugin.showChildren.call(plugin);
186 202
      });
187 203

  
188 204
      plugin.container.mouseleave(function (){
......
193 209
        plugin.hideChildren.call(plugin);
194 210
      });
195 211

  
212
      /*
196 213
      plugin.$element.children('i.fa').hover(
197 214
        function(){
198 215
          this.addClass(this.options.hoverClass);
......
201 218
          this.removeClass(this.options.hoverClass);
202 219
        }
203 220
      );
204

  
221
      */
205 222
    },
206 223

  
207 224
    // Unbind events that trigger methods
......
211 228
       to "this.$element".
212 229

  
213 230
       this works at earliest with v1.7, with 1.4.4 we need to unbind without
214
       namespace specifity
231
       namespace specificity
215 232
       */
216 233
      this.$element.unbind('click');
234
      // TODO complete this ...
217 235
    },
218 236

  
219 237
    log: function (msg) {
......
223 241
    showChildren: function(){
224 242

  
225 243
      var plugin = this;
244

  
226 245
      var trigger_position =  this.$element.position();
227 246

  
228 247
      this.log('trigger_position: ' + trigger_position.top + ', ' + trigger_position.left);
......
237 256
      this.log('baseHeight: ' + this.baseHeight);
238 257
      this.log('lineHeight: ' + this.lineHeight);
239 258

  
240
      this.offset_container_top = this.lineHeight - trigger_position.top;
259
      this.offset_container_top = this.lineHeight - trigger_position.top  + 1;
241 260

  
242 261
      this.container
243 262
        .css('top', - this.offset_container_top + 'px')
244
        .css('left', trigger_position.left + 'px')
245
        .css('padding-left', this.$element.width() + 'px')
246
        .css('padding-right', this.$element.width() + 'px')
263
        .css('left', (trigger_position.left - this.alignOffset.left) + 'px')
264
        .css('padding-left', this.alignOffset.padding + 'px')
265
        .css('padding-right', this.alignOffset.padding + 'px')
247 266
        .css('z-index', 10)
248 267
        .show();
249 268

  
......
258 277
    },
259 278

  
260 279
    hideChildren: function(){
261
      // return;
280
      //return; // uncomment for debugging
262 281
      this.container
263 282
        .detach();
264 283
    },
......
268 287
      this.loading.hide();
269 288
      this.isDataLoaded = true;
270 289
      var listContainer = $(html);
290
      if(listContainer[0].tagName != 'UL'){
291
        // unwrap from potential enclosing div, this is
292
        // necessary in case of compose_classification_selector
293
        listContainer = listContainer.children('ul');
294
      }
271 295
      this.children.append(listContainer);
272 296
      this.itemsCount = listContainer.children().length;
273 297

  
......
285 309
        max = Math.floor( ($(window).height() - this.element.getBoundingClientRect().top) / this.lineHeight) - 2;
286 310
        this.log('max: ' + max);
287 311
      }
288
      return (this.itemsCount > this.options.viewPortRows.min ? max : this.options.viewPortRows.min);
312
      var rows = Math.max(this.itemsCount, this.options.viewPortRows.min);
313
      rows = Math.min(rows, max);
314
      this.log('rows: ' + max);
315
      return rows;
289 316
    },
290 317

  
291
    adjustHeight: function(itemsCount){
318
    adjustHeight: function(){
292 319

  
293
      var viewPortRows = this.calculateViewPortRows(itemsCount); //(itemsCount > this.options.viewPortRows.min ? this.options.viewPortRows.max : this.options.viewPortRows.min);
294
      this.log('itemsCount: ' + itemsCount + ' => viewPortRows: ' + viewPortRows);
320
      var viewPortRows = this.calculateViewPortRows(this.itemsCount); //(itemsCount > this.options.viewPortRows.min ? this.options.viewPortRows.max : this.options.viewPortRows.min);
321
      this.log('itemsCount: ' + this.itemsCount + ' => viewPortRows: ' + viewPortRows);
295 322

  
296 323
      this.container.css('height', viewPortRows * this.lineHeight + 'px');
297 324
      this.children
......
301 328

  
302 329
    scrollToSelected: function () {
303 330

  
304
      if(this.subTaxonName){
305
        var scrollTarget = this.children
306
          .find("a:contains('" + this.subTaxonName + "')")
307
          .css('font-weight', 'bold');
331
      var scrollTarget = this.children.find(".focused");
332
      if(scrollTarget){
308 333
        var scroll_target_offset_top = scrollTarget.position().top;
309 334
        this.log("scroll_target_offset_top: " + scroll_target_offset_top + ", offset_container_top: " + this.offset_container_top);
310
        this.container.scrollTop(scroll_target_offset_top - this.lineHeight);
335
        this.container.scrollTop(scroll_target_offset_top - this.lineHeight + 1); // +1 yields a better result
311 336
      }
312 337
    },
313 338

  
314 339
    requestURI: function(pageIndex, pageSize){
315 340

  
316
      // pageIndex, pageSize are not yet used, prepared for future though
317 341
      var contentRequest;
342
      var renderFunction;
343
      var proxyRequestQuery= '';
318 344

  
345
      // pageIndex, pageSize are not yet used, prepared for future though
319 346
      if(!pageIndex){
320 347
        pageIndex = 0;
321 348
      }
......
323 350
        pageSize = 100;
324 351
      }
325 352

  
326
      if(this.taxonUuid){
327
        contentRequest =
328
          this.options.cdmWebappBaseUri
329
          + this.options.cdmWebappTaxonChildrenRequest
330
            .replace('{classificationUuid}', this.options.classificationUuid)
331
            .replace('{taxonUuid}', this.taxonUuid);
332

  
333
      } else if(this.rankLimitUuid){
334
        contentRequest =
335
          this.options.cdmWebappBaseUri
336
          + this.options.cdmWebappClassificationChildnodesAtRequest
337
            .replace('{classificationUuid}', this.options.classificationUuid)
338
            .replace('{rankUuid}', this.rankLimitUuid);
353
      if(this.classificationChooser){
354
        renderFunction = this.options.renderFunction.classifications + '?destination=' + this.destinationUri;
355
        contentRequest = 'NULL'; // using the plain compose function which does not require any data to be passes as parameter
356

  
339 357
      } else {
340
        contentRequest =
341
          this.options.cdmWebappBaseUri
342
          + this.options.cdmWebappClassificationRootRequest
343
            .replace('{classificationUuid}', this.options.classificationUuid);
358
        renderFunction = this.options.renderFunction.taxonNodes;
359
        proxyRequestQuery = '?currentTaxon=' + this.taxonUuid;
360
        if(this.taxonUuid) {
361
          if(this.classificationMode == 'siblings') {
362
            contentRequest =
363
              this.options.cdmWebappBaseUri
364
              + this.options.cdmWebappRequests.taxonSiblings
365
                .replace('{classificationUuid}', this.options.classificationUuid)
366
                .replace('{taxonUuid}', this.taxonUuid);
367
          } else {
368
            // default mode is 'children'
369
            contentRequest =
370
              this.options.cdmWebappBaseUri
371
              + this.options.cdmWebappRequests.taxonChildren
372
                .replace('{classificationUuid}', this.options.classificationUuid)
373
                .replace('{taxonUuid}', this.taxonUuid);
374
          }
375
        } else if(this.rankLimitUuid){
376
          contentRequest =
377
            this.options.cdmWebappBaseUri
378
            + this.options.cdmWebappRequests.childNodesAt
379
              .replace('{classificationUuid}', this.options.classificationUuid)
380
              .replace('{rankUuid}', this.rankLimitUuid);
381
        } else {
382
          contentRequest =
383
            this.options.cdmWebappBaseUri
384
            + this.options.cdmWebappRequests.classificationRoot
385
              .replace('{classificationUuid}', this.options.classificationUuid);
386
        }
344 387
      }
345 388

  
389

  
390

  
346 391
      this.log("contentRequest: " + contentRequest);
347 392

  
348 393
      var proxyRequest = this.options.proxyRequest
349 394
        .replace('{contentRequest}', encodeURIComponent(encodeURIComponent(contentRequest)))
350
        .replace('{renderFunction}', this.options.renderFunction);
395
        .replace('{renderFunction}', renderFunction);
351 396

  
352
      var request = this.options.proxyBaseUri + '/' + proxyRequest;
397
      var request = this.options.proxyBaseUri + '/' + proxyRequest + proxyRequestQuery;
353 398
      this.log("finalRequest: " + request);
354 399

  
355 400
      return request;
......
385 430
    return this;
386 431
  };
387 432

  
388
  /*
389
   Attach the default plugin options directly to the plugin object. This
390
   allows users to override default plugin options globally, instead of
391
   passing the same option(s) every time the plugin is initialized.
392 433

  
393
   For example, the user could set the "property" value once for all
394
   instances of the plugin with
395
   "$.fn.pluginName.defaults.property = 'myValue';". Then, every time
396
   plugin is initialized, "property" will be set to "myValue".
397

  
398
   More: http://learn.jquery.com/plugins/advanced-plugin-concepts/
399
   */
400 434
  $.fn[pluginName].defaults = {
401 435
    hoverClass: undefined,
402 436
    activeClass: undefined,
437
    /**
438
     * uuid of the current classification - required
439
     */
403 440
    classificationUuid: undefined,
441
    /**
442
     * uuid of the current taxon - required
443
     */
444
    taxonUuid: undefined,
404 445
    cdmWebappBaseUri: undefined,
405 446
    proxyBaseUri: undefined,
406
    cdmWebappTaxonChildrenRequest: "portal/classification/{classificationUuid}/childNodesOf/{taxonUuid}",
407
    cdmWebappClassificationChildnodesAtRequest: "portal/classification/{classificationUuid}/childNodesAt/{rankUuid}.json",
408
    cdmWebappClassificationRootRequest: "portal/classification/{classificationUuid}/childNodes.json",
447
    cdmWebappRequests: {
448
      taxonChildren: "portal/classification/{classificationUuid}/childNodesOf/{taxonUuid}",
449
      taxonSiblings: "portal/classification/{classificationUuid}/siblingsOf/{taxonUuid}",
450
      childNodesAt: "portal/classification/{classificationUuid}/childNodesAt/{rankUuid}.json",
451
      classificationRoot: "portal/classification/{classificationUuid}/childNodes.json"
452
    },
409 453
    proxyRequest: "cdm_api/proxy/{contentRequest}/{renderFunction}",
410
    renderFunction: "cdm_taxontree",
454
    renderFunction: {
455
      taxonNodes: "cdm_taxontree",
456
      classifications: "classification_selector"
457
    },
411 458
    // viewPortRows: if max is 'undefined' the height will be adapted to the window viewport
412 459
    viewPortRows: {min: 3, max: undefined}
413 460
  };

Also available in: Unified diff