PageSourceSearch

https://www.lca.org.tw/modules/civicrm/js/jquery/jquery.crmasmselect.js?tlv55b

js lca.org.tw collected 2026-09-24 22:33:05 UTC 12,157 bytes, 421 lines download raw bytes

1/*
2 * Alternate Select Multiple (crmasmSelect) 1.0.4 beta - jQuery Plugin
3 * http://www.ryancramer.com/projects/crmasmSelect/
4 * 
5 * Copyright (c) 2008 by Ryan Cramer - http://www.ryancramer.com
6 * 
7 * Dual licensed under the MIT (MIT-LICENSE.txt)
8 * and GPL (GPL-LICENSE.txt) licenses.
9 *
10 */
11
12(function($) {
13
14	$.fn.crmasmSelect = function(customOptions) {
15
16		var options = {
17
18			listType: 'ul',						// Ordered list 'ol', or unordered list 'ul'
19			sortable: false, 					// Should the list be sortable?
20			highlight: false,					// Use the highlight feature? 
21			animate: false,						// Animate the the adding/removing of items in the list?
22			addItemTarget: 'bottom',				// Where to place new selected items in list: top or bottom
23			hideWhenAdded: false,					// Hide the option when added to the list? works only in FF
24			debugMode: false,					// Debug mode keeps original select visible 
25
26			removeLabel: 'X',					// Text used in the "remove" link
27			highlightAddedLabel: 'Added: ',				// Text that precedes highlight of added item
28			highlightRemovedLabel: 'Removed: ',			// Text that precedes highlight of removed item
29
30			containerClass: 'crmasmContainer',				// Class for container that wraps this widget
31			selectClass: 'crmasmSelect',				// Class for the newly created <select>
32			optionDisabledClass: 'asmOptionDisabled',		// Class for items that are already selected / disabled
33			listClass: 'crmasmList',					// Class for the list ($ol)
34			listSortableClass: 'crmasmListSortable',			// Another class given to the list when it is sortable
35			listItemClass: 'crmasmListItem',				// Class for the <li> list items
36			listItemLabelClass: 'crmasmListItemLabel',			// Class for the label text that appears in list items
37			removeClass: 'crmasmListItemRemove',			// Class given to the "remove" link
38			highlightClass: 'crm asmHighlight',				// Class given to the highlight <span>
39
40			respectParents: false				// Force selection of "parent" option items
41			};
42
43		$.extend(options, customOptions); 
44
45		return this.each(function(index) {
46
47			var $original = $(this); 				// the original select multiple
48			var $container; 					// a container that is wrapped around our widget
49			var $select; 						// the new select we have created
50			var $ol; 						// the list that we are manipulating
51			var buildingSelect = false; 				// is the new select being constructed right now?
52			var ieClick = false;					// in IE, has a click event occurred? ignore if not
53			var ignoreOriginalChangeEvent = false;			// originalChangeEvent bypassed when this is true
54
55			function init() {
56
57				// initialize the alternate select multiple
58
59				// this loop ensures uniqueness, in case of existing crmasmSelects placed by ajax (1.0.3)
60				while($("#" + options.containerClass + index).size() > 0) index++; 
61
62				$select = $("<select></select>")
63					.addClass(options.selectClass)
64					.attr('id', options.selectClass + index); 
65
66				$selectRemoved = $("<select></select>"); 
67
68				$ol = $("<" + options.listType + "></" + options.listType + ">")
69					.addClass(options.listClass)
70					.attr('id', options.listClass + index); 
71
72				$container = $("<div></div>")
73					.addClass(options.containerClass) 
74					.attr('id', options.containerClass + index); 
75
76				buildSelect();
77
78				$select.change(selectChangeEvent)
79					.click(selectClickEvent); 
80
81				$original.change(originalChangeEvent)
82					.wrap($container).before($select).before($ol);
83
84				if(options.sortable) makeSortable();
85
86				if($.browser.msie) $ol.css('display', 'inline-block'); 
87			}
88
89			function makeSortable() {
90
91				// make any items in the selected list sortable
92				// requires jQuery UI sortables, draggables, droppables
93
94				$ol.sortable({
95					items: 'li.' + options.listItemClass,
96					handle: '.' + options.listItemLabelClass,
97					axis: 'y',
98					update: function(e, data) {
99
100						var updatedOptionId;
101
102						$(this).children("li").each(function(n) {
103
104							$option = $('#' + $(this).attr('rel')); 
105
106							if($(this).is(".ui-sortable-helper")) {
107								updatedOptionId = $option.attr('id'); 
108								return;
109							}
110
111							$original.append($option); 
112						}); 
113
114						if(updatedOptionId) triggerOriginalChange(updatedOptionId, 'sort'); 
115					}
116
117				}).addClass(options.listSortableClass); 
118			}
119
120			function selectChangeEvent(e) {
121				
122				// an item has been selected on the regular select we created
123				// check to make sure it's not an IE screwup, and add it to the list
124
125				if($.browser.msie && $.browser.version < 7 && !ieClick) return;
126				var id = $(this).children("option:selected").slice(0,1).attr('rel'); 
127				addListItem(id); 	
128				ieClick = false; 
129				triggerOriginalChange(id, 'add'); // for use by user-defined callbacks
130			}
131
132			function selectClickEvent() {
133
134				// IE6 lets you scroll around in a select without it being pulled down
135				// making sure a click preceded the change() event reduces the chance
136				// if unintended items being added. there may be a better solution?
137
138				ieClick = true; 
139			}
140
141			function originalChangeEvent(e) {
142
143				// select or option change event manually triggered
144				// on the original <select multiple>, so rebuild ours
145
146				if(ignoreOriginalChangeEvent) {
147					ignoreOriginalChangeEvent = false; 
148					return; 
149				}
150
151				$select.empty();
152				$ol.empty();
153				buildSelect();
154
155				// opera has an issue where it needs a force redraw, otherwise
156				// the items won't appear until something else forces a redraw
157				if($.browser.opera) $ol.hide().fadeIn("fast");
158			}
159
160			function buildSelect() {
161
162				// build or rebuild the new select that the user
163				// will select items from
164
165				buildingSelect = true; 
166
167				// add a first option to be the home option / default selectLabel
168				$select.prepend("<option>" + $original.attr('title') + "</option>"); 
169
170				$original.children("option").each(function(n) {
171
172					var $t = $(this); 
173					var id; 
174
175					if(!$t.attr('id')) $t.attr('id', 'asm' + index + 'option' + n); 
176					id = $t.attr('id');
177					classes = $t.attr('class'); 
178
179					if($t.is(":selected")) {
180						addListItem(id); 
181						addSelectOption(id, classes, true); 						
182					} else {
183						addSelectOption(id,classes); 
184					}
185				});
186
187				if(!options.debugMode) $original.hide(); // IE6 requires this on every buildSelect()
188				selectFirstItem();
189				buildingSelect = false; 
190			}
191
192			function addSelectOption(optionId, optionClasses, disabled) {
193
194				// add an <option> to the <select>
195				// used only by buildSelect()
196
197				if(disabled == undefined) var disabled = false; 
198
199				var $O = $('#' + optionId); 
200				var $option = $("<option>" + $O.text() + "</option>")
201					.val($O.val())
202					.attr('rel', optionId)
203					.addClass(optionClasses);
204
205				if(disabled) disableSelectOption($option); 
206
207				$select.append($option); 
208			}
209
210			function selectFirstItem() {
211
212				// select the firm item from the regular select that we created
213
214				$select.children(":eq(0)").attr("selected", true); 
215			}
216
217			function disableSelectOption($option) {
218
219				// make an option disabled, indicating that it's already been selected
220				// because safari is the only browser that makes disabled items look 'disabled'
221				// we apply a class that reproduces the disabled look in other browsers
222
223				$option.addClass(options.optionDisabledClass)
224					.attr("selected", false)
225					.attr("disabled", true);
226
227				if(options.hideWhenAdded) $option.hide();
228				if($.browser.msie) $select.hide().show(); // this forces IE to update display
229			}
230
231			function enableSelectOption($option) {
232
233				// given an already disabled select option, enable it
234
235				$option.removeClass(options.optionDisabledClass)
236					.attr("disabled", false);
237
238				if(options.hideWhenAdded) $option.show();
239				if($.browser.msie) $select.hide().show(); // this forces IE to update display
240			}
241
242			function addListItem(optionId) {
243
244				// add a new item to the html list
245
246				var $O = $('#' + optionId); 
247
248				if(!$O) return; // this is the first item, selectLabel
249
250				var $removeLink = $("<a></a>")
251					.attr("href", "#")
252					.addClass(options.removeClass)
253					.prepend(options.removeLabel)
254					.click(function() { 
255						dropListItem($(this).parent('li').attr('rel')); 
256						return false; 
257					}); 
258
259				var $itemLabel = $("<span></span>")
260					.addClass(options.listItemLabelClass)
261					.html($O.html()); 
262
263				var $item = $("<li></li>")
264					.attr('rel', optionId)
265					.addClass(options.listItemClass)
266					.addClass($O.attr('class'))
267					.append($itemLabel)
268					.append($removeLink)
269					.hide();
270
271				if(!buildingSelect) {
272					if($O.is(":selected")) return; // already have it
273					$O.attr('selected', true); 
274				}
275
276				if(options.addItemTarget == 'top' && !buildingSelect) {
277					$ol.prepend($item); 
278					if(options.sortable) $original.prepend($O); 
279				} else {
280					$ol.append($item); 
281					if(options.sortable) $original.append($O); 
282				}
283
284				addListItemShow($item); 
285
286				disableSelectOption($("[rel=" + optionId + "]", $select));
287
288				if(!buildingSelect) {
289					setHighlight($item, options.highlightAddedLabel); 
290					selectFirstItem();
291					if(options.sortable) $ol.sortable("refresh"); 	
292				}
293				
294				if(options.respectParents) {
295				
296				if($O.hasClass('child')) {
297					parentName = $O.attr('class').split('parent-')[1];
298					parentName = parentName.split(' ')[0];
299					parentId = $('.option-'+parentName).attr('rel');
300					addListItem(parentId);
301					};
302				};
303			}
304
305			function addListItemShow($item) {
306
307				// reveal the currently hidden item with optional animation
308				// used only by addListItem()
309
310				if(options.animate && !buildingSelect) {
311					$item.animate({
312						opacity: "show",
313						height: "show"
314					}, 100, "swing", function() { 
315						$item.animate({
316							height: "+=2px"
317						}, 50, "swing", function() {
318							$item.animate({
319								height: "-=2px"
320							}, 25, "swing"); 
321						}); 
322					}); 
323				} else {
324					$item.show();
325				}
326			}
327
328			function dropListItem(optionId, highlightItem) {
329
330				// remove an item from the html list
331
332				if(highlightItem == undefined) var highlightItem = true; 
333				var $O = $('#' + optionId); 
334
335				$O.attr('selected', false); 
336				$item = $ol.children("li[rel=" + optionId + "]");
337
338				dropListItemHide($item); 
339				enableSelectOption($("[rel=" + optionId + "]", options.removeWhenAdded ? $selectRemoved : $select));
340
341				if(highlightItem) setHighlight($item, options.highlightRemovedLabel); 
342
343				triggerOriginalChange(optionId, 'drop'); 
344				
345			}
346
347			function dropListItemHide($item) {
348
349				// remove the currently visible item with optional animation
350				// used only by dropListItem()
351
352				if(options.animate && !buildingSelect) {
353
354					$prevItem = $item.prev("li");
355
356					$item.animate({
357						opacity: "hide",
358						height: "hide"
359					}, 100, "linear", function() {
360						$prevItem.animate({
361							height: "-=2px"
362						}, 50, "swing", function() {
363							$prevItem.animate({
364								height: "+=2px"
365							}, 100, "swing"); 
366						}); 
367						$item.remove(); 
368					}); 
369					
370				} else {
371					$item.remove(); 
372				}
373			}
374
375			function setHighlight($item, label) {
376
377				// set the contents of the highlight area that appears
378				// directly after the <select> single
379				// fade it in quickly, then fade it out
380
381				if(!options.highlight) return; 
382
383				$select.next("#" + options.highlightClass + index).remove();
384
385				var $highlight = $("<span></span>")
386					.hide()
387					.addClass(options.highlightClass)
388					.attr('id', options.highlightClass + index)
389					.html(label + $item.children("." + options.listItemLabelClass).slice(0,1).text()); 
390					
391				$select.after($highlight); 
392
393				$highlight.fadeIn("fast", function() {
394					setTimeout(function() { $highlight.fadeOut("slow"); }, 50); 
395				}); 
396			}
397
398			function triggerOriginalChange(optionId, type) {
399
400				// trigger a change event on the original select multiple
401				// so that other scripts can pick them up
402
403				ignoreOriginalChangeEvent = true; 
404				$option = $("#" + optionId); 
405
406				$original.trigger('change', [{
407					'option': $option,
408					'value': $option.val(),
409					'id': optionId,
410					'item': $ol.children("[rel=" + optionId + "]"),
411					'type': type
412				}]); 
413			}
414
415			init();
416		});
417	};
418
419})(jQuery); 
420
421 

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.