|
128 | 128 | },
|
129 | 129 |
|
130 | 130 | refresh: function(init) {
|
| 131 | + var inputIdCounter = 0; |
131 | 132 | var el = this.element;
|
132 | 133 | var o = this.options;
|
133 | 134 | var menu = this.menu;
|
134 | 135 | var checkboxContainer = this.checkboxContainer;
|
135 |
| - var optgroups = {}; |
136 | 136 | var html = "";
|
| 137 | + var $dropdown = $("<ul/>").addClass('ui-multiselect-checkboxes ui-helper-reset'); |
137 | 138 | var id = el.attr('id') || multiselectID++; // unique ID for the label & option tags
|
138 | 139 |
|
139 |
| - // update header link container visibility if needed |
140 |
| - if (this.options.header) { |
141 |
| - if(!this.options.multiple) { |
142 |
| - this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none').hide(); |
143 |
| - } else { |
144 |
| - this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none').show(); |
145 |
| - } |
146 |
| - } |
147 |
| - |
148 |
| - // build items |
149 |
| - el.find('option').each(function(i) { |
150 |
| - var $this = $(this); |
151 |
| - var parent = this.parentNode; |
152 |
| - var contents = this.innerHTML; |
153 |
| - var title = this.title; |
154 |
| - var value = this.value; |
155 |
| - var inputID = 'ui-multiselect-' + multiselectID + '-' + (this.id || id + '-option-' + i); |
156 |
| - var isDisabled = this.disabled; |
157 |
| - var isSelected = this.selected; |
| 140 | + function makeItem(option, isInOptionGroup) { |
| 141 | + var title = option.title ? option.title : null; |
| 142 | + var value = option.value; |
| 143 | + var inputID = 'ui-multiselect-' + multiselectID + '-' + (option.id || id + '-option-' + inputIdCounter++); |
| 144 | + var isDisabled = option.disabled; |
| 145 | + var isSelected = option.selected; |
158 | 146 | var labelClasses = [ 'ui-corner-all' ];
|
159 | 147 | var liClasses = [];
|
160 |
| - var optLabel; |
161 | 148 |
|
162 | 149 | if(isDisabled) {
|
163 | 150 | liClasses.push('ui-multiselect-disabled');
|
| 151 | + labelClasses.push('ui-state-disabled'); |
164 | 152 | }
|
165 |
| - |
166 |
| - if(this.className) { |
167 |
| - liClasses.push(this.className); |
| 153 | + if(option.className) { |
| 154 | + liClasses.push(option.className); |
168 | 155 | }
|
169 |
| - |
170 |
| - // is this an optgroup? |
171 |
| - if(parent.tagName === 'OPTGROUP') { |
172 |
| - optLabel = parent.getAttribute('label'); |
| 156 | + if(isSelected && !o.multiple) { |
| 157 | + labelClasses.push('ui-state-active'); |
| 158 | + } |
| 159 | + if(isInOptionGroup) { |
173 | 160 | liClasses.push('ui-multiselect-optgrp-child');
|
174 |
| - |
175 |
| - // has this optgroup been added already? |
176 |
| - if(!optgroups[optLabel]) { |
177 |
| - var optLabelEscaped = optLabel.replace(/&/g, '&') |
178 |
| - .replace(/>/g, '>') |
179 |
| - .replace(/</g, '<') |
180 |
| - .replace(/'/g, ''') |
181 |
| - .replace(/\//g, '/') |
182 |
| - .replace(/"/g, '"'); |
183 |
| - html += '<li class="ui-multiselect-optgroup-label ' + parent.className + '"><a href="#">' + optLabelEscaped + '</a></li>'; |
184 |
| - optgroups[optLabel] = true; |
185 |
| - } |
186 | 161 | }
|
187 | 162 |
|
188 |
| - if(isDisabled) { |
189 |
| - labelClasses.push('ui-state-disabled'); |
190 |
| - } |
| 163 | + var $item = $("<li/>").addClass(liClasses.join(' ')); |
| 164 | + var $label = $("<label/>").attr({ |
| 165 | + "for": inputID, |
| 166 | + "title": title |
| 167 | + }).addClass(labelClasses.join(' ')).appendTo($item); |
| 168 | + var $input = $("<input/>").attr({ |
| 169 | + "name": "multiselect_" + id, |
| 170 | + "type": o.multiple ? "checkbox" : "radio", |
| 171 | + "value": value, |
| 172 | + "title": title, |
| 173 | + "id": inputID, |
| 174 | + "checked": isSelected ? "checked" : null, |
| 175 | + "aria-selected": isSelected ? "true" : null, |
| 176 | + "disabled": isDisabled ? "disabled" : null, |
| 177 | + "aria-disabled": isDisabled ? "true" : null |
| 178 | + }).appendTo($label); |
| 179 | + |
| 180 | + $("<span/>").text($(option).text()).appendTo($label); |
| 181 | + |
| 182 | + return $item; |
| 183 | + }//makeItem |
191 | 184 |
|
192 |
| - // browsers automatically select the first option |
193 |
| - // by default with single selects |
194 |
| - if(isSelected && !o.multiple) { |
195 |
| - labelClasses.push('ui-state-active'); |
| 185 | + // update header link container visibility if needed |
| 186 | + if (this.options.header) { |
| 187 | + if(!this.options.multiple) { |
| 188 | + this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none').hide(); |
| 189 | + } else { |
| 190 | + this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none').show(); |
196 | 191 | }
|
| 192 | + } |
197 | 193 |
|
198 |
| - html += '<li class="' + liClasses.join(' ') + '">'; |
199 |
| - |
200 |
| - // create the label |
201 |
| - html += '<label for="' + inputID + '" title="' + title + '" class="' + labelClasses.join(' ') + '">'; |
202 |
| - html += '<input id="' + inputID + '" name="multiselect_' + id + '" type="' + (o.multiple ? "checkbox" : "radio") + '" value="' + value + '" title="' + title + '"'; |
| 194 | + //Turn all the options and optiongroups into list items |
| 195 | + el.children().each(function(i) { |
| 196 | + var $this = $(this); |
203 | 197 |
|
204 |
| - // pre-selected? |
205 |
| - if(isSelected) { |
206 |
| - html += ' checked="checked"'; |
207 |
| - html += ' aria-selected="true"'; |
208 |
| - } |
| 198 | + if(this.tagName === 'OPTGROUP') { |
| 199 | + var $groupLabel = $("<li/>").addClass('ui-multiselect-optgroup-label ' + this.className).appendTo($dropdown); |
| 200 | + var $link = $("<a/>").attr("href", "#").text(this.getAttribute('label')).appendTo($groupLabel); |
209 | 201 |
|
210 |
| - // disabled? |
211 |
| - if(isDisabled) { |
212 |
| - html += ' disabled="disabled"'; |
213 |
| - html += ' aria-disabled="true"'; |
| 202 | + $this.children().each(function() { |
| 203 | + var $listItem = makeItem(this, true).appendTo($dropdown); |
| 204 | + }); |
| 205 | + } else { |
| 206 | + var $listItem = makeItem(this).appendTo($dropdown); |
214 | 207 | }
|
215 | 208 |
|
216 |
| - // add the contents and close everything off |
217 |
| - html += ' /><span>' + contents + '</span></label></li>'; |
218 | 209 | });
|
219 | 210 |
|
220 |
| - // insert into the DOM |
221 |
| - checkboxContainer.html(html); |
| 211 | + this.menu.find(".ui-multiselect-checkboxes").remove(); |
| 212 | + this.menu.append($dropdown); |
222 | 213 |
|
223 | 214 | // cache some moar useful elements
|
224 | 215 | this.labels = menu.find('label');
|
|
0 commit comments