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