Projet

Général

Profil

Révision 98a362c2

Ajouté par Assos Assos il y a plus de 6 ans

Weekly update of contrib modules

Voir les différences:

drupal7/sites/all/modules/shs/js/shs.js
3 3
 * Custom behaviors for Simple hierarchical select.
4 4
 */
5 5

  
6
(function ($) {
6
(function ($, Drupal) {
7 7

  
8 8
  /**
9 9
   * Creates the widget for Simple hierarchical select.
......
13 13
    // Default function to attach the behavior.
14 14
    attach: function (context, settings) {
15 15
      var self = this;
16
      $('input.shs-enabled')
17
        .not('.shs-processed')
16
      var settingsDefault = {
17
        display: {
18
          animationSpeed: 400,
19
        }
20
      };
21
      $('select.shs-enabled:not([disabled])')
18 22
        .once('shs')
19 23
        .addClass('element-invisible')
24
        .hide()
20 25
        .each(function() {
21
          var $field = $(this);
26
          $field = $(this);
22 27
          var fieldName = $(this).attr('name');
28
          // Multiform messes up the names of the fields
29
          // to the format multiform[something][fieldname][...].
30
          if (fieldName.indexOf('multiform') == 0) {
31
            var split = fieldName.split('][');
32
            split.splice(0, 1);
33
            fieldName = split.splice(0, 1) + '[' + split.join('][');
34
          }
23 35

  
24 36
          if (fieldName in settings.shs) {
25 37
            var fieldSettings = {};
......
29 41
            $.each(settings.shs[fieldName], function(hash, setting) {
30 42
              fieldSettings = setting;
31 43
            });
44
            fieldSettings = $.extend({}, fieldSettings, settingsDefault, {
45
              fieldName: fieldName
46
            });
32 47
            var level = 0;
33 48
            var parent_id = 0;
34 49
            // Update class of wrapper element.
......
42 57
                // Add error-class if there was an error with the original field.
43 58
                $select.addClass('error');
44 59
              }
60
              // Add label to dropdown.
61
              $label = shsLabelCreate($field.attr('id'), fieldSettings, level);
62
              if ($label !== false) {
63
                $label.appendTo($field.parent());
64
              }
45 65
              $select.appendTo($field.parent());
46 66
              // Retrieve data for this level.
47 67
              getTermChildren($select, fieldSettings, parent_id, parent.tid, $field.attr('id'));
......
54 74
              }
55 75
            });
56 76
            var addNextLevel = false;
57
            if ((level > 1 || parent_id) && (fieldSettings.settings.create_new_terms && fieldSettings.settings.create_new_levels)) {
77
            if ((level > 1 || parent_id) && ((fieldSettings.settings.create_new_terms && fieldSettings.settings.create_new_levels) || fieldSettings.settings.test_create_new_levels)) {
58 78
              // Add next level in hierarchy if new levels may be created.
59 79
              addNextLevel = true;
60 80
            }
61
            if (fieldSettings.default_value && (fieldSettings.default_value.tid == parent_id)) {
81
            if (fieldSettings.default_value && (fieldSettings.default_value === parent_id) && (fieldSettings.default_value !== '')) {
62 82
              addNextLevel = true;
63 83
            }
64 84
            if (addNextLevel) {
85
              // Add label to dropdown.
86
              $label = shsLabelCreate($field.attr('id'), fieldSettings, level);
87
              if ($label !== false) {
88
                $label.appendTo($field.parent());
89
              }
65 90
              // Try to add one additional level.
66
              $select = shsElementCreate($field.attr('id'), fieldSettings, level);
91
              $select = shsElementCreate($field.attr('id'), fieldSettings, ++level);
67 92
              $select.appendTo($field.parent());
68 93
              // Retrieve data for this level.
69 94
              getTermChildren($select, fieldSettings, parent_id, 0, $field.attr('id'));
......
88 113
    *   ID of original field which is rewritten as "taxonomy_shs".
89 114
    */
90 115
  getTermChildren = function($element, settings, parent_value, default_value, base_id) {
91

  
92 116
    // Check if parent_value is number and convert it.
93 117
    if (!$.isArray(parent_value) && typeof parent_value != "object") {
94 118
      parent_value = [parent_value];
95 119
    }
96 120

  
97
    // Check if default_value is object and convert it.
98
    if (!$.isArray(default_value) && typeof default_value == "object") {
99
      var arr = new Array;
100
      $.each(default_value, function(delta, value){
101
        arr.push(value);
102
      });
103
      default_value = arr;
104
    }
105

  
106 121
    $.ajax({
107
      url: Drupal.settings.basePath + 'js/shs/json',
122
      url: Drupal.settings.basePath + '?q=' + Drupal.settings.pathPrefix + 'js/shs/json',
108 123
      type: 'POST',
109 124
      dataType: 'json',
110 125
      cache: true,
......
113 128
        arguments: {
114 129
          vid: settings.vid,
115 130
          parent: parent_value,
116
          settings: settings.settings
131
          settings: settings.settings,
132
          field: settings.fieldName
117 133
        }
118 134
      },
119 135
      success: function(data) {
......
125 141
            var options = $element.attr('options');
126 142
          }
127 143

  
128
          if (data.data.length == 0 && !(settings.settings.create_new_terms && (settings.settings.create_new_levels || (parent_value + default_value == 0)))) {
144
          if (((data.data.length == 0) || ((data.data.length == 1 && !data.data[0].tid))) && !(settings.settings.create_new_terms && (settings.settings.create_new_levels || (parent_value[0] == settings.any_value && default_value == 0)))) {
129 145
            // Remove element.
146
            $element.prev('label').remove();
130 147
            $element.remove();
131 148
            return;
132 149
          }
133 150

  
134 151
          // Remove all existing options.
135 152
          $('option', $element).remove();
136
          // Add empty option (if field is not required and not multiple
137
          // or this is not the first level and not multiple).
138
          if (!settings.settings.required || (settings.settings.required && parent_value != 0 && !settings.multiple)) {
139
            options[options.length] = new Option(Drupal.t('- None -'), 0);
140
          }
141

  
142
          if (settings.settings.create_new_terms) {
143
            // Add option to add new item.
144
            options[options.length] = new Option(Drupal.t('<Add new item>', {}, {context: 'shs'}), '_add_new_');
153
          // Add empty option (if field is not required or this is not the
154
          // first level.
155
          if (!settings.settings.required || (settings.settings.required && (default_value === 0 || parent_value !== 0))) {
156
            options[options.length] = new Option(settings.any_label, settings.any_value);
145 157
          }
146 158

  
147 159
          // Add retrieved list of options.
148 160
          $.each(data.data, function(key, term) {
149
            options[options.length] = new Option(term.label, term.tid);
161
            if (term.vid && settings.settings.create_new_terms) {
162
              // Add option to add new item.
163
              options[options.length] = new Option(Drupal.t('<Add new item>', {}, {context: 'shs'}), '_add_new_');
164
            }
165
            else if (term.tid) {
166
              option = new Option(term.label, term.tid);
167
              options[options.length] = option;
168
              if (term.has_children) {
169
                option.setAttribute("class", "has-children");
170
              }
171
            }
150 172
          });
151 173
          // Set default value.
152 174
          $element.val(default_value);
175
          if (0 === default_value) {
176
            $element.val(settings.any_value);
177
          }
153 178

  
154 179
          // Try to convert the element to a "Chosen" element.
155 180
          if (!elementConvertToChosen($element, settings)) {
156 181
            // Display original dropdown element.
157
            $element.fadeIn();
182
            $element.fadeIn(settings.display.animationSpeed);
158 183
            $element.css('display','inline-block');
159 184
          }
185
          else {
186
            $element.trigger('chosen:updated');
187
          }
160 188

  
161 189
          // If there is no data, the field is required and the user is allowed
162 190
          // to add new terms, trigger click on "Add new".
163
          if (data.data.length == 0 && settings.settings.required && settings.settings.create_new_terms && (settings.settings.create_new_levels || (parent_value + default_value == 0))) {
191
          if (data.data.length == 0 && settings.settings.required && settings.settings.create_new_terms && (settings.settings.create_new_levels || (parent_value[0] == settings.any_value && default_value == 0))) {
164 192
            updateElements($element, base_id, settings, 1);
165 193
          }
166 194
        }
......
183 211
   *   ID of original field which is rewritten as "taxonomy_shs".
184 212
   * @param level
185 213
   *   Current level in hierarchy.
214
   * @param settings
215
   *   Field settings.
186 216
   */
187
  termAddNew = function($triggering_element, $container, term, base_id, level) {
217
  termAddNew = function($triggering_element, $container, term, base_id, level, settings) {
188 218
    $.ajax({
189
      url: Drupal.settings.basePath + 'js/shs/json',
219
      url: Drupal.settings.basePath + '?q=' + Drupal.settings.pathPrefix + 'js/shs/json',
190 220
      type: 'POST',
191 221
      dataType: 'json',
192 222
      cache: true,
......
195 225
        arguments: {
196 226
          vid: term.vid,
197 227
          parent: term.parent,
198
          name: term.name
228
          name: term.name,
229
          field: settings.fieldName
199 230
        }
200 231
      },
201 232
      success: function(data) {
......
212 243
          // Set new default value.
213 244
          $triggering_element.val(data.data.tid);
214 245
          // Set value of original field.
215
          updateFieldValue($triggering_element, base_id, level);
246
          updateFieldValue($triggering_element, base_id, level, settings);
247
          // Add new child element if adding new levels is allowed.
248
          if (settings.settings.create_new_levels) {
249
            $element_new = shsElementCreate(base_id, settings, level + 1);
250
            $element_new.appendTo($triggering_element.parent());
251
            if ($element_new.prop) {
252
              var options_new = $element_new.prop('options');
253
            }
254
            else {
255
              var options_new = $element_new.attr('options');
256
            }
257
            // Add "none" option.
258
            options_new[options_new.length] = new Option(settings.any_label, settings.any_value);
259
            if (settings.settings.create_new_terms) {
260
              // Add option to add new item.
261
              options_new[options_new.length] = new Option(Drupal.t('<Add new item>', {}, {context: 'shs'}), '_add_new_');
262
            }
263
            // Try to convert the element to a "Chosen" element.
264
            if (!elementConvertToChosen($element_new, settings)) {
265
              // Display original dropdown element.
266
              $element_new.fadeIn(settings.display.animationSpeed);
267
              $element_new.css('display','inline-block');
268
            }
269
          }
216 270
        }
217 271
      },
218 272
      error: function(xhr, status, error) {
......
221 275
      },
222 276
      complete: function(xhr, status) {
223 277
        // Remove container.
278
        $container.prev('label').remove();
224 279
        $container.remove();
225 280
        // Display triggering element.
226
        $triggering_element.fadeIn();
281
        $triggering_element.fadeIn(settings.display.animationSpeed);
227 282
        $triggering_element.css('display','inline-block');
283
        $triggering_element.trigger('change');
228 284
      }
229 285
    });
230 286
  }
......
247 303
      if (Drupal.settings.chosen) {
248 304
        // Remove element created by chosen.
249 305
        var elem_id = $(this).attr('id');
250
        $('#' + elem_id.replace(/-/g, '_') + '_chzn').remove();
306
        $element_chosen = $('#' + elem_id.replace(/-/g, '_') + '_chosen');
307
        if ($element_chosen) {
308
          $element_chosen.prev('label').remove();
309
          $element_chosen.remove();
310
        }
251 311
      }
252 312
      // Remove element.
313
      $(this).prev('label').remove();
253 314
      $(this).remove();
254 315
    });
255
    //$triggering_element.nextAll('.chzn-container').remove();
256 316
    $triggering_element.nextAll('.shs-term-add-new-wrapper').remove();
257 317
    // Create next level (if the value is != 0).
258 318
    if ($triggering_element.val() == '_add_new_') {
259 319
      // Hide element.
260 320
      $triggering_element.hide();
321
      if (Drupal.settings.chosen) {
322
        // Remove element created by chosen.
323
        var elem_id = $triggering_element.attr('id');
324
        $('#' + elem_id.replace(/-/g, '_') + '_chosen').remove();
325
      }
261 326
      // Create new container with textfield and buttons ("cancel", "save").
262 327
      $container = $('<div>')
263 328
        .addClass('shs-term-add-new-wrapper')
......
283 348
        .bind('click', function(event) {
284 349
          event.preventDefault();
285 350
          // Remove container.
351
          $container.prev('label').remove();
286 352
          $container.remove();
287 353
          // Reset value of triggering element.
288
          $triggering_element.val(0);
289
          // Display triggering element.
290
          $triggering_element.fadeIn();
291
          $triggering_element.css('display','inline-block');
354
          $triggering_element.val(settings.settings.any_value);
355

  
356
          if (!elementConvertToChosen($triggering_element, settings)) {
357
            // Display triggering element.
358
            $triggering_element.fadeIn(settings.display.animationSpeed);
359
            $triggering_element.css('display','inline-block');
360
          }
292 361
        });
293 362
      $cancel.appendTo($buttons);
294 363
      if (level == 1 && settings.settings.required && $('option', $triggering_element).length == 1) {
......
307 376
          // Create a term object.
308 377
          var term = {
309 378
            vid: settings.vid,
310
            parent: $triggering_element.prev('select').val() || 0,
379
            parent: (level === 1) ? 0 : ($triggering_element.prevAll('.shs-select').val() || 0),
311 380
            name: termName
312 381
          };
313 382
          if (termName.length > 0) {
314
            termAddNew($triggering_element, $container, term, base_id, level);
383
            termAddNew($triggering_element, $container, term, base_id, level, settings);
315 384
          }
316 385
          else {
317 386
            // Remove container.
387
            $container.prev('label').remove();
318 388
            $container.remove();
319 389
            // Reset value of triggering element.
320 390
            $triggering_element.val(0);
321 391
            // Display triggering element.
322
            $triggering_element.fadeIn();
323
            $triggering_element.css('display','inline-block');;
392
            $triggering_element.fadeIn(settings.display.animationSpeed);
393
            $triggering_element.css('display', 'inline-block');;
324 394
          }
325 395
        });
326 396
      $save.appendTo($buttons);
327 397
    }
328
    else if ($triggering_element.val() != 0) {
398
    else if ($triggering_element.val() != 0 && $triggering_element.val() != settings.any_value) {
329 399
      level++;
400
      $label = shsLabelCreate(base_id, settings, level);
401
      if ($label !== false) {
402
        $label.appendTo($triggering_element.parent());
403
      }
330 404
      $element_new = shsElementCreate(base_id, settings, level);
331 405
      $element_new.appendTo($triggering_element.parent());
332 406
      // Retrieve list of items for the new element.
......
334 408
    }
335 409

  
336 410
    // Set value of original field.
337
    updateFieldValue($triggering_element, base_id, level, settings.multiple);
411
    updateFieldValue($triggering_element, base_id, level, settings);
338 412
  }
339 413

  
340 414
  /**
......
352 426
   */
353 427
  shsElementCreate = function(base_id, settings, level) {
354 428
    // Create element and initially hide it.
429
    $element = $('<select>')
430
      .attr('id', base_id + '-select-' + level)
431
      .addClass('shs-select')
432
      // Add core class to apply default styles to the element.
433
      .addClass('form-select')
434
      .addClass('shs-select-level-' + level)
435
      .bind('change', function() {
436
        updateElements($(this), base_id, settings, level);
437
      })
438
      .hide();
355 439
    if (settings.multiple) {
356
      $element = $('<select>')
357
        .attr('id', base_id + '-select-' + level)
358
        .attr('multiple', 'multiple')
359
        .addClass('shs-select')
360
        // Add core class to apply default styles to the element.
361
        .addClass('form-select')
362
        .addClass('shs-select-level-' + level)
363
        .bind('change', function() {
364
          updateElements($(this), base_id, settings, level);
365
        })
366
        .hide();
440
      $element.attr('multiple', 'multiple')
367 441
    }
368
    else {
369
      $element = $('<select>')
370
        .attr('id', base_id + '-select-' + level)
371
        .addClass('shs-select')
372
        // Add core class to apply default styles to the element.
373
        .addClass('form-select')
374
        .addClass('shs-select-level-' + level)
375
        .bind('change', function() {
376
          updateElements($(this), base_id, settings, level);
377
        })
378
        .hide();
442
    if (settings.settings.hasOwnProperty('required') && settings.settings.required) {
443
      $element.addClass('required');
379 444
    }
380 445
    // Return the new element.
381 446
    return $element;
382 447
  }
383 448

  
449
  /**
450
   * Create label for dropdown in hierarchy.
451
   *
452
   * @param base_id
453
   *   ID of original field which is rewritten as "taxonomy_shs".
454
   * @param settings
455
   *   Field settings.
456
   * @param level
457
   *   Current level in hierarchy.
458
   *
459
   * @return
460
   *   The new <label> element or false if no label should be created.
461
   */
462
  shsLabelCreate = function(base_id, settings, level) {
463
    var labelKey = level - 1;
464
    if (!settings.hasOwnProperty('labels')) {
465
      return false;
466
    }
467
    if (!settings.labels.hasOwnProperty(labelKey) || settings.labels[labelKey] === false) {
468
      return false;
469
    }
470
    // Create element.
471
    $element = $('<label>')
472
      .attr('for', base_id + '-select-' + level)
473
      .addClass('element-invisible')
474
      .html(settings.labels[labelKey]);
475
    // Return the new element.
476
    return $element;
477
  }
478

  
384 479
  /**
385 480
   * Update value of original (hidden) field.
386 481
   *
......
390 485
   *   ID of original field which is rewritten as "taxonomy_shs".
391 486
   * @param level
392 487
   *   Current level in hierarchy.
488
   * @param settings
489
   *   Field settings.
393 490
   */
394
  updateFieldValue = function($triggering_element, base_id, level, multiple) {
491
  updateFieldValue = function($triggering_element, base_id, level, settings) {
395 492
    // Reset value of original field.
396 493
    $field_orig = $('#' + base_id);
397
    $field_orig.val(0);
494
    $field_orig.val(settings.any_value);
398 495
    // Set original field value.
399
    if ($triggering_element.val() == 0 || $triggering_element.val() == '_add_new_') {
400
      if (level > 1) {
496
    if ($triggering_element.val() === settings.any_value || $triggering_element.val() == '_add_new_') {
497
      if ($triggering_element.prev('select').length) {
401 498
        // Use value from parent level.
402 499
        $field_orig.val($triggering_element.prev('select').val());
403 500
      }
404 501
    }
405 502
    else {
406 503
      var new_val = $triggering_element.val();
407
      if (level > 1 && multiple) {
504
      if (level > 1 && settings.multiple) {
408 505
        var new_value = '';
409 506
        for (i = 0; i < level - 1; i++) {
410 507
          var prev_value = $('.shs-select:eq(' + i + ')').val();
......
422 519
        $field_orig.val(new_val.join(','));
423 520
      }
424 521
      else {
425
        $field_orig.val(new_val);
522
        if ($field_orig.children('option[value="' + new_val + '"]').length > 0) {
523
          // Value exists.
524
          $field_orig.val(new_val);
525
        }
526
        else {
527
          // We need to append the new option.
528
          if ($field_orig.prop) {
529
            var options = $field_orig.prop('options');
530
          }
531
          else {
532
            var options = $field_orig.attr('options');
533
          }
534
          options[options.length] = new Option(new_val, new_val);
535
          $field_orig.val(new_val);
536
        }
426 537
      }
427 538
    }
539
    // Notify listeners about the change in the original select.
540
    $field_orig.trigger({
541
      type: 'change',
542
      shs: {
543
        triggeringElement: $triggering_element,
544
        level: level,
545
        settings: settings,
546
        value: $triggering_element.val()
547
      }
548
    });
428 549
  }
429 550

  
430 551
  /**
......
433 554
   * @see http://drupal.org/project/chosen
434 555
   */
435 556
  elementConvertToChosen = function($element, settings) {
436
    if (Drupal.settings.chosen) {
437
      var minWidth = Drupal.settings.chosen.minimum_width;
438
      // Define options for chosen.
439
      var options = {};
440
      options.search_contains = Drupal.settings.chosen.search_contains;
441
      options.placeholder_text_multiple = Drupal.settings.chosen.placeholder_text_multiple;
442
      options.placeholder_text_single = Drupal.settings.chosen.placeholder_text_single;
443
      options.no_results_text = Drupal.settings.chosen.no_results_text;
444

  
445
      // Get element selector from settings (and remove "visible" option since
446
      // our select element is hidden by default).
447
      var selector = Drupal.settings.chosen.selector.replace(/:visible/, '');
448

  
449
      if ((settings.settings.use_chosen == 'always') || ((settings.settings.use_chosen == 'chosen') && ($element.is(selector) && $element.find('option').size() >= Drupal.settings.chosen.minimum))) {
450
        $element.css({
451
          width : ($element.width() < minWidth) ? minWidth : $element.width()
452
        }).chosen(options);
453
        return true;
454
      }
557
    // Returns false if chosen is not available or its settings are undefined.
558
    if ($.fn.chosen === void 0 || !Drupal.settings.hasOwnProperty('chosen') || Drupal.settings.chosen === void 0) {
559
      return false;
560
    }
561

  
562
    var name = $element.attr('name');
563
    settings.chosen = settings.chosen || Drupal.settings.chosen;
564
    var minWidth = settings.chosen.minimum_width;
565
    var multiple = Drupal.settings.chosen.multiple;
566
    var maxSelectedOptions = Drupal.settings.chosen.max_selected_options;
567

  
568
    // Define options.
569
    var options = {
570
      inherit_select_classes: true
571
    };
572

  
573
    var minimum = multiple && multiple[name] ? settings.chosen.minimum_multiple : settings.chosen.minimum_single;
574

  
575
    if (maxSelectedOptions && maxSelectedOptions[name]) {
576
      options.max_selected_options = maxSelectedOptions[name];
455 577
    }
578

  
579
    // Merges the user defined settings for chosen.
580
    options = $.extend(options, settings.chosen);
581

  
582
    // Get element selector from settings (and remove "visible" option since
583
    // our select element is hidden by default).
584
    var selector = settings.chosen.selector.replace(/:visible/, '');
585
    if ((settings.settings.use_chosen === 'always') || ((settings.settings.use_chosen === 'chosen') && $element.is(selector) && ($element.find('option').size() >= minimum || minimum === 'Always Apply'))) {
586
      options = $.extend(options, {
587
        width: (($element.width() < minWidth) ? minWidth : $element.width()) + 'px'
588
      });
589

  
590
      // Apply chosen to the element.
591
      return $element.chosen(options);
592
    }
593
    else if ((settings.settings.use_chosen === 'never') && (!$element.hasClass('chosen-disable'))) {
594
      // Tell chosen to not process this element.
595
      $element.addClass('chosen-disable');
596
    }
597

  
456 598
    return false;
457 599
  }
458 600

  
459
})(jQuery);
601
})(jQuery, Drupal);

Formats disponibles : Unified diff