1/** 2 * @file 3 * Attaches behaviors for the Chosen module. 4 */ 5 6(function($, Drupal, drupalSettings, once) { 7 'use strict'; 8 9 // Temporal workaround while https://github.com/harvesthq/chosen/issues/515 10 // is fixed. This fix was taken from: 11 // https://github.com/harvesthq/chosen/issues/515#issuecomment-104602031 12 $.fn.oldChosen = $.fn.chosen; 13 $.fn.chosen = function(options) { 14 var select = $(this) 15 , is_creating_chosen = !!options; 16 17 if (is_creating_chosen && select.css('position') === 'absolute') { 18 // if we are creating a chosen and the select already has the appropriate styles added 19 // we remove those (so that the select hasn't got a crazy width), then create the chosen 20 // then we re-add them later 21 select.removeAttr('style'); 22 } 23 24 var ret = select.oldChosen(options); 25 26 // only act if the select has display: none, otherwise chosen is unsupported (iPhone, etc) 27 if (is_creating_chosen && select.css('display') === 'none') { 28 // https://github.com/harvesthq/chosen/issues/515#issuecomment-33214050 29 // only do this if we are initializing chosen (no params, or object params) not calling a method 30 select.attr('style','display:visible; position:absolute; width:0px; height: 0px; clip:rect(0,0,0,0)'); 31 select.attr('tabindex', -1); 32 } 33 return ret; 34 }; 35 36 // Update Chosen elements when state has changed. 37 $(document).on('state:disabled', 'select', function (e) { 38 $(e.target).trigger('chosen:updated'); 39 }); 40 41 Drupal.behaviors.chosen = { 42 43 settings: { 44 45 /** 46 * Completely ignores elements that match one of these selectors. 47 * 48 * Disabled on: 49 * - Field UI 50 * - WYSIWYG elements 51 * - Tabledrag weights 52 * - Elements that have opted-out of Chosen 53 * - Elements already processed by Chosen. 54 * 55 * @type {string} 56 */ 57 ignoreSelector: '#field-ui-field-storage-add-form select, #entity-form-display-edit-form select, #entity-view-display-edit-form select, .wysiwyg, .draggable select[name$="[weight]"], .draggable select[name$="[position]"], .locale-translate-filter-form select, .chosen-disable, .chosen-processed', 58 59 /** 60 * Explicit "opt-in" selector. 61 * 62 * @type {string} 63 */ 64 optedInSelector: 'select.chosen-enable', 65 66 /** 67 * The default selector, overridden by drupalSettings. 68 * 69 * @type {string} 70 */ 71 selector: 'select:visible' 72 }, 73 74 /** 75 * Drupal attach behavior. 76 */ 77 attach: function(context, settings) { 78 this.settings = this.getSettings(settings); 79 $(once('chosen', this.getElements(context))).each(function (i, element) { 80 this.createChosen(element); 81 }.bind(this)); 82 }, 83 84 /** 85 * Creates a Chosen instance for a specific element. 86 * 87 * @param {jQuery|HTMLElement} element 88 * The element. 89 */ 90 createChosen: function(element) { 91 var $element = $(element); 92 $element.chosen(this.getElementOptions($element)); 93 }, 94 95 /** 96 * Filter out elements that should not be converted into Chosen. 97 * 98 * @param {jQuery|HTMLElement} element 99 * The element. 100 * 101 * @return {boolean} 102 * TRUE if the element should stay, FALSE otherwise. 103 */ 104 filterElements: function (element) { 105 var $element = $(element); 106 107 // Remove elements that should be ignored completely. 108 if ($element.is(this.settings.ignoreSelector)) { 109 return false; 110 } 111 112 // Zero value means no minimum. 113 var minOptions = $element.attr('multiple') ? this.settings.minimum_multiple : this.settings.minimum_single; 114 return !minOptions || $element.find('option').length >= minOptions; 115 }, 116 117 /** 118 * Retrieves the elements that should be converted into Chosen instances. 119 * 120 * @param {jQuery|Element} context 121 * A DOM Element, Document, or jQuery object to use as context. 122 * @param {string} [selector] 123 * A selector to use, defaults to the default selector in the settings. 124 */ 125 getElements: function (context, selector) { 126 var $context = $(context || document); 127 var $elements = $context.find(selector || this.settings.selector); 128 129 // Remove elements that should not be converted into Chosen. 130 $elements = $elements.filter(function(i, element) { 131 return this.filterElements(element); 132 }.bind(this)); 133 134 // Add elements that have explicitly opted in to Chosen. 135 $elements = $elements.add($context.find(this.settings.optedInSelector)); 136 137 return $elements; 138 }, 139 140 /** 141 * Retrieves options used to create a Chosen instance based on an element. 142 * 143 * @param {jQuery|HTMLElement} element 144 * The element to process. 145 * 146 * @return {Object} 147 * The options object used to instantiate a Chosen instance with. 148 */ 149 getElementOptions: function (element) { 150 var $element = $(element); 151 var options = $.extend({}, this.settings.options); 152 var dimension; 153 var width; 154 155 // The width default option is considered the minimum width, so this 156 // must be evaluated for every option. 157 if (this.settings.minimum_width > 0) { 158 // Given we need to manage settings as both percentage and pixel widths, 159 // we need to handle width calculations separately. 160 if (this.settings.use_relative_width) { 161 dimension = '%'; 162 width = ($element.width() / $element.parent().width() * 100).toPrecision(5); 163 } 164 else { 165 dimension = 'px'; 166 width = $element.width(); 167 } 168 169 if (width < this.settings.minimum_width) { 170 options.width = this.settings.minimum_width + dimension; 171 } 172 else { 173 options.width = width + dimension; 174 } 175 } 176 177 // Some field widgets have cardinality, so we must respect that. 178 // @see \Drupal\chosen\ChosenFormRender::preRenderSelect() 179 var cardinality; 180 if ($element.attr('multiple') && (cardinality = $element.data('cardinality'))) { 181 options.max_selected_options = cardinality; 182 } 183 184 return options; 185 }, 186 187 /** 188 * Retrieves the settings passed from Drupal. 189 * 190 * @param {Object} [settings] 191 * Passed Drupal settings object, if any. 192 */ 193 getSettings: function (settings) { 194 return $.extend(true, {}, this.settings, settings && settings.chosen || drupalSettings.chosen); 195 } 196 197}; 198 199}
199)(jQuery, Drupal, drupalSettings, once);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.