21c7a2872bd9d08f29623b78f5a63eca040c1ead
chmalee
  Thu Oct 17 12:34:21 2024 -0700
Fix position of dropdownchecklists and make them correctly determine when the options have been selected or not, refs #34647

diff --git src/hg/js/ui.dropdownchecklist.js src/hg/js/ui.dropdownchecklist.js
index 2496fd8..bcceb3e 100644
--- src/hg/js/ui.dropdownchecklist.js
+++ src/hg/js/ui.dropdownchecklist.js
@@ -1,888 +1,889 @@
 ;(function($) {
 /*
     * ui.dropdownchecklist
     *
     * Copyright (c) 2008-2010 Adrian Tosca, Copyright (c) 2010-2011 Ittrium LLC
     * Dual licensed under the MIT (MIT-LICENSE.txt) OR GPL (GPL-LICENSE.txt) licenses.
     *
 */
     // The dropdown check list jQuery plugin transforms a regular select html element into a dropdown check list.
     $.widget("ui.dropdownchecklist", {
     	// Some globlals
     	// $.ui.dropdownchecklist.gLastOpened - keeps track of last opened dropdowncheck list so we can close it
     	// $.ui.dropdownchecklist.gIDCounter - simple counter to provide a unique ID as needed
         version: function() {
             alert('DropDownCheckList v1.3');
         },
         // Creates the drop container that keeps the items and appends it to the document
         _appendDropContainer: function( controlItem ) {
             var wrapper = $("<div/>");
             // the container is wrapped in a div
             wrapper.addClass("ui-dropdownchecklist ui-dropdownchecklist-dropcontainer-wrapper");
             wrapper.addClass("ui-widget");
             // assign an id
             wrapper.attr("id",controlItem.attr("id") + '-ddw');
             // initially positioned way off screen to prevent it from displaying
             // NOTE absolute position to enable width/height calculation
             wrapper.css({ position: 'absolute', left: "-33000px", top: "-33000px"  });
 
             var container = $("<div/>"); // the actual container
             container.addClass("ui-dropdownchecklist-dropcontainer ui-widget-content");
             container.css("overflow-y", "auto");
             wrapper.append(container);
 
             // insert the dropdown after the master control to try to keep the tab order intact
             // if you just add it to the end, tabbing out of the drop down takes focus off the page
             // @todo 22Sept2010 - check if size calculation is thrown off if the parent of the
             //		selector is hidden.  We may need to add it to the end of the document here,
             //		calculate the size, and then move it back into proper position???
 			//$(document.body).append(wrapper);
             wrapper.insertAfter(controlItem);
 
             // flag that tells if the drop container is shown or not
             wrapper.isOpen = false;
             return wrapper;
         },
         // Look for browser standard 'open' on a closed selector
 		_isDropDownKeyShortcut: function(e,keycode) {
 			return e.altKey && ($.ui.keyCode.DOWN == keycode);// Alt + Down Arrow
 		},
 		// Look for key that will tell us to close the open dropdown
 		_isDropDownCloseKey: function(e,keycode) {
 			return ($.ui.keyCode.ESCAPE == keycode) || ($.ui.keyCode.ENTER == keycode);
 		},
 		// Handler to change the active focus based on a keystroke, moving some count of
 		// items from the element that has the current focus
 		_keyFocusChange: function(target,delta,limitToItems) {
 			// Find item with current focus
 			var focusables = $(":focusable");
 			var index = focusables.index(target);
 			if ( index >= 0 ) {
 				index += delta;
 				if ( limitToItems ) {
 					// Bound change to list of input elements
 	            	var allCheckboxes = this.dropWrapper.find("input:not([disabled])");
 	            	var firstIndex = focusables.index(allCheckboxes.get(0));
 	            	var lastIndex = focusables.index(allCheckboxes.get(allCheckboxes.length-1));
 	            	if ( index < firstIndex ) {
 	            		index = lastIndex;
 	            	} else if ( index > lastIndex ) {
 	            		index = firstIndex;
 	            	}
 	            }
 				focusables.get(index).focus();
 			}
 		},
 		// Look for navigation, open, close (wired to keyup)
 		_handleKeyboard: function(e) {
 			var self = this;
 			var keyCode = (e.keyCode || e.which);
 			if (!self.dropWrapper.isOpen && self._isDropDownKeyShortcut(e, keyCode)) {
 				// Key command to open the dropdown
 				e.stopImmediatePropagation();
 				self._toggleDropContainer(true);
 			} else if (self.dropWrapper.isOpen && self._isDropDownCloseKey(e, keyCode)) {
 				// Key command to close the dropdown (but we retain focus in the control)
 				e.stopImmediatePropagation();
 				self._toggleDropContainer(false);
 				self.controlSelector.focus();
 			} else if (self.dropWrapper.isOpen
 					&& (e.target.type == 'checkbox')
 					&& ((keyCode == $.ui.keyCode.DOWN) || (keyCode == $.ui.keyCode.UP)) ) {
 				// Up/Down to cycle throught the open items
 				e.stopImmediatePropagation();
 				self._keyFocusChange(e.target, (keyCode == $.ui.keyCode.DOWN) ? 1 : -1, true);
 			} else if (self.dropWrapper.isOpen && (keyCode == $.ui.keyCode.TAB) ) {
 				// I wanted to adjust normal 'tab' processing here, but research indicates
 				// that TAB key processing is NOT a cancelable event. You have to use a timer
 				// hack to pull the focus back to where you want it after browser tab
 				// processing completes.  Not going to work for us.
 				//e.stopImmediatePropagation();
 				//self._keyFocusChange(e.target, (e.shiftKey) ? -1 : 1, true);
            }
 		},
 		// Look for change of focus
 		_handleFocus: function(e,focusIn,forDropdown) {
 			var self = this;
 			if (forDropdown && !self.dropWrapper.isOpen) {
 				// if the focus changes when the control is NOT open, mark it to show where the focus is/is not
 				e.stopImmediatePropagation();
 				if (focusIn) {
 					self.controlSelector.addClass("ui-state-hover");
 					if ($.ui.dropdownchecklist.gLastOpened != null) {
 						$.ui.dropdownchecklist.gLastOpened._toggleDropContainer( false );
 					}
 				} else {
 					self.controlSelector.removeClass("ui-state-hover");
 				}
            	} else if (!forDropdown && !focusIn) {
            		// The dropdown is open, and an item (NOT the dropdown) has just lost the focus.
            		// we really need a reliable method to see who has the focus as we process the blur,
            		// but that mechanism does not seem to exist.  Instead we rely on a delay before
            		// posting the blur, with a focus event cancelling it before the delay expires.
 				if ( e != null ) { e.stopImmediatePropagation(); }
 				self.controlSelector.removeClass("ui-state-hover");
 				self._toggleDropContainer( false );
            	}
 		},
 		// Clear the pending change of focus, which keeps us 'in' the control
 		_cancelBlur: function(e) {
 			var self = this;
 			if (self.blurringItem != null) {
 				clearTimeout(self.blurringItem);
 				self.blurringItem = null;
 			}
 		},
         // Creates the control that will replace the source select and appends it to the document
         // The control resembles a regular select with single selection
         _appendControl: function() {
             var self = this, sourceSelect = this.sourceSelect, options = this.options;
 
             // the control is wrapped in a basic container
             // inline-block at this level seems to give us better size control
             var wrapper = $("<span/>");
             wrapper.addClass("ui-dropdownchecklist ui-dropdownchecklist-selector-wrapper ui-widget");
             wrapper.css( { display: "inline-block", cursor: "default", overflow: "hidden" } );
 
             // assign an ID
             var baseID = sourceSelect.attr("id");
             if ((baseID == null) || (baseID == "")) {
             	baseID = "ddcl-" + $.ui.dropdownchecklist.gIDCounter++;
             } else {
             	baseID = "ddcl-" + baseID;
 			}
 			wrapper.attr("id",baseID);
 
             // the actual control which you can style
             // inline-block needed to enable 'width' but has interesting problems cross browser
             var control = $("<span/>");
             control.addClass("ui-dropdownchecklist-selector ui-state-default");
             control.css( { display: "inline-block", overflow: "hidden", 'white-space': 'nowrap'} );
             // Setting a tab index means we are interested in the tab sequence
             var tabIndex = sourceSelect.attr("tabIndex");
             if ( tabIndex == null ) {
             	tabIndex = 0;
             } else {
             	tabIndex = parseInt(tabIndex);
             	if ( tabIndex < 0 ) {
             		tabIndex = 0;
             	}
             }
 			control.attr("tabIndex", tabIndex);
 			control.keyup(function(e) {self._handleKeyboard(e);});
 			control.focus(function(e) {self._handleFocus(e,true,true);});
 			control.blur(function(e) {self._handleFocus(e,false,true);});
             wrapper.append(control);
 
 			// the optional icon (which is inherently a block) which we can float
 			if (options.icon != null) {
 				var iconPlacement = (options.icon.placement == null) ? "left" : options.icon.placement;
 	            var anIcon = $("<div/>");
 	            anIcon.addClass("ui-icon");
 	            anIcon.addClass( (options.icon.toOpen != null) ? options.icon.toOpen : "ui-icon-triangle-1-e");
 	            anIcon.css({ 'float': iconPlacement });
 	            control.append(anIcon);
 			}
             // the text container keeps the control text that is built from the selected (checked) items
             // inline-block needed to prevent long text from wrapping to next line when icon is active
             var textContainer = $("<span/>");
             textContainer.addClass("ui-dropdownchecklist-text");
             textContainer.css( {  display: "inline-block", 'white-space': "nowrap", overflow: "hidden" } );
             control.append(textContainer);
 
             // add the hover styles to the control
             wrapper.hover(
 	            function() {
 	                if (!self.disabled) {
 	                    control.addClass("ui-state-hover");
 	                }
 	            }
 	        , 	function() {
 	                if (!self.disabled) {
 	                    control.removeClass("ui-state-hover");
 	                }
 	            }
 	        );
             // clicking on the control toggles the drop container
             wrapper.click(function(event) {
                 if (!self.disabled) {
                     event.stopImmediatePropagation();
                     self._toggleDropContainer( !self.dropWrapper.isOpen );
                 }
             });
             wrapper.insertAfter(sourceSelect);
 
 			// Watch for a window resize and adjust the control if open
             ///// UCSC Stop ugly bug in IE where onChange gets called on every selection.
             if (theClient.isIe() !== true) {  ///// UCSC
                 $(window).resize(function() {
                     if (!self.disabled && self.dropWrapper.isOpen) {
                             // Reopen yourself to get the position right
                         self._toggleDropContainer(true);
                     }
                 });
             } ///// UCSC
             return wrapper;
         },
         // Creates a drop item that coresponds to an option element in the source select
         _createDropItem: function(index, tabIndex, value, text, optCss, checked, disabled, indent) {
             var self = this, options = this.options, sourceSelect = this.sourceSelect, controlWrapper = this.controlWrapper;
             // the item contains a div that contains a checkbox input and a lable for the text
             // the div
             var item = $("<div/>");
             item.addClass("ui-dropdownchecklist-item");
             item.css({'white-space': "nowrap"});
             var checkedString = checked ? ' checked="checked"' : '';
 			var classString = disabled ? ' class="inactive"' : ' class="active"';
 
 			// generated id must be a bit unique to keep from colliding
 			var idBase = controlWrapper.attr("id");
 			var id = idBase + '-i' + index;
             var checkBox;
 
             // all items start out disabled to keep them out of the tab order
             if (self.isMultiple) { // the checkbox
                 checkBox = $('<input disabled type="checkbox" id="' + id + '"' + checkedString + classString + ' tabindex="' + tabIndex + '" />');
             } else { // the radiobutton
                 checkBox = $('<input disabled type="radio" id="' + id + '" name="' + idBase + '"' + checkedString + classString + ' tabindex="' + tabIndex + '" />');
             }
             checkBox = checkBox.attr("index", index).val(value);
             item.append(checkBox);
 
             // the text
             var label = $("<label for=" + id + "/>");
             label.addClass("ui-dropdownchecklist-text");
             if ( optCss != null ) label.attr('style',optCss);
             label.css({ cursor: "default" });
             label.html(text);
 			if (indent) {
 				item.addClass("ui-dropdownchecklist-indent");
 			}
 			item.addClass("ui-state-default");
 			if (disabled) {
 				item.addClass("ui-state-disabled");
 			}
 	        label.click(function(e) {e.stopImmediatePropagation();});
 
             var span = $("<span/>");
             span.css( { cursor: "default" });
             span.html(" (0)");
             label.append(span);
 
             item.append(label);
 
            	// active items display themselves with hover
             item.hover(
             	function(e) {
             		var anItem = $(this);
                 	if (!anItem.hasClass("ui-state-disabled")) { anItem.addClass("ui-state-hover"); }
             	}
             , 	function(e) {
             		var anItem = $(this);
                 	anItem.removeClass("ui-state-hover");
             	}
             );
             // clicking on the checkbox synchronizes the source select
 	        checkBox.click(function(e) {
 	        	var aCheckBox = $(this);
 				e.stopImmediatePropagation();
 				if (aCheckBox.hasClass("active") ) {
 					// Active checkboxes take active action
 	                var callback = self.options.onItemClick;
 	                if ($.isFunction(callback)) try {
                         callback.call(self,aCheckBox);
                     } catch (ex) {
                         // reject the change on any error
-                        aCheckBox.attr("checked",!aCheckBox.attr("checked"));
+                        aCheckBox.prop("checked",!aCheckBox.prop("checked"));
                         return;
                     }
 	                self._syncSelected(aCheckBox);
 	                self.sourceSelect.trigger("change", 'ddcl_internal');
 	                if (!self.isMultiple && options.closeRadioOnClick) {
 	                	self._toggleDropContainer(false);
 	                }
 				}
 	        });
 	        // we are interested in the focus leaving the check box
 	        // but we need to detect the focus leaving one check box but
 	        // entering another. There is no reliable way to detect who
 	        // received the focus on a blur, so post the blur in the future,
 	        // knowing we will cancel it if we capture the focus in a timely manner
 	        // 23Sept2010 - unfortunately, IE 7+ and Chrome like to post a blur
 	        // 				event to the current item with focus when the user
 	        //				clicks in the scroll bar. So if you have a scrollable
 	        //				dropdown with focus on an item, clicking in the scroll
 	        //				will close the drop down.
 	        //				I have no solution for blur processing at this time.
 /*********
 			var timerFunction = function(){
 				// I had a hell of a time getting setTimeout to fire this, do not try to
 				// define it within the blur function
 				try { self._handleFocus(null,false,false); } catch(ex){ alert('timer failed: '+ex);}
 			};
 			checkBox.blur(function(e) {
 				self.blurringItem = setTimeout( timerFunction, 200 );
 			});
 			checkBox.focus(function(e) {self._cancelBlur();});
 **********/
 	        // check/uncheck the item on clicks on the entire item div
 	        item.click(function(e) {
 	        	var anItem = $(this);
                 e.stopImmediatePropagation();
 				if (!anItem.hasClass("ui-state-disabled") ) {
 					// check/uncheck the underlying control
 					var aCheckBox = anItem.find("input");
-	                var checked = aCheckBox.attr("checked");
-	                aCheckBox.attr("checked", !checked);
+	                var checked = aCheckBox.prop("checked");
+	                aCheckBox.prop("checked", !checked);
 
 	                var callback = self.options.onItemClick;
 	                if ($.isFunction(callback)) try {
                         callback.call(self,aCheckBox);
                     } catch (ex) {
                         // reject the change on any error
-                        aCheckBox.attr("checked",checked);
+                        aCheckBox.prop("checked",checked);
                         return;
                     }
 	                self._syncSelected(aCheckBox);
 	                self.sourceSelect.trigger("change", 'ddcl_internal');
 	                if (!checked && !self.isMultiple && options.closeRadioOnClick) {
 	                	self._toggleDropContainer(false);
 	                }
 				} else {
 					// retain the focus even if disabled
 					anItem.focus();
 					self._cancelBlur();
 				}
 	        });
 	        // do not let the focus wander around
 			item.focus(function(e) {
 	        	var anItem = $(this);
                 e.stopImmediatePropagation();
             });
 			item.keyup(function(e) {self._handleKeyboard(e);});
             return item;
         },
 		_createGroupItem: function(text,disabled) {
 			var self = this;
 			var group = $("<div />");
 			group.addClass("ui-dropdownchecklist-group ui-widget-header");
 			if (disabled) {
 				group.addClass("ui-state-disabled");
 			}
 			group.css({'white-space': "nowrap"});
 
             var label = $("<span/>");
             label.addClass("ui-dropdownchecklist-text");
             label.css( { cursor: "default" });
             label.text(text);
 			group.append(label);
 
 			// anything interesting when you click the group???
 	        group.click(function(e) {
 	        	var aGroup= $(this);
                 e.stopImmediatePropagation();
                 // retain the focus even if no action is taken
                 aGroup.focus();
                 self._cancelBlur();
             });
 	        // do not let the focus wander around
 			group.focus(function(e) {
 	        	var aGroup = $(this);
                 e.stopImmediatePropagation();
             });
 			return group;
 		},
 		_createCloseItem: function(text) {
 			var self = this;
 			var closeItem = $("<div />");
 			closeItem.addClass("ui-state-default ui-dropdownchecklist-close ui-dropdownchecklist-item");
 			closeItem.css({'white-space': 'nowrap', 'text-align': 'right'});
 
             var label = $("<span/>");
             label.addClass("ui-dropdownchecklist-text");
             label.css( { cursor: "default" });
             label.html(text);
 			closeItem.append(label);
 
 			// close the control on click
 	        closeItem.click(function(e) {
 	        	var aGroup= $(this);
                 e.stopImmediatePropagation();
                 // retain the focus even if no action is taken
                 aGroup.focus();
                 self._toggleDropContainer( false );
             });
             closeItem.hover(
             	function(e) { $(this).addClass("ui-state-hover"); }
             , 	function(e) { $(this).removeClass("ui-state-hover"); }
             );
 	        // do not let the focus wander around
 			closeItem.focus(function(e) {
 	        	var aGroup = $(this);
                 e.stopImmediatePropagation();
             });
 			return closeItem;
 		},
         // Creates the drop items and appends them to the drop container
         // Also calculates the size needed by the drop container and returns it
         _appendItems: function() {
             var self = this, config = this.options, sourceSelect = this.sourceSelect, dropWrapper = this.dropWrapper;
             var dropContainerDiv = dropWrapper.find(".ui-dropdownchecklist-dropcontainer");
 			sourceSelect.children().each(function(index) { // when the select has groups
 				var opt = $(this);
                 if (opt.is("option")) {
                     self._appendOption(opt, dropContainerDiv, index, false, false);
                 } else if (opt.is("optgroup")) {
 					var disabled = opt.attr("disabled");
                     var text = opt.attr("label");
                     if (text != "") {
 	                    var group = self._createGroupItem(text,disabled);
 	                    dropContainerDiv.append(group);
 	                }
                     self._appendOptions(opt, dropContainerDiv, index, true, disabled);
                 }
 			});
 			if ( config.explicitClose != null ) {
 				var closeItem = self._createCloseItem(config.explicitClose);
 				dropContainerDiv.append(closeItem);
 			}
             var divWidth = dropContainerDiv.outerWidth();
             var divHeight = dropContainerDiv.outerHeight();
             return { width: divWidth, height: divHeight };
         },
 		_appendOptions: function(parent, container, parentIndex, indent, forceDisabled) {
 			var self = this;
 			parent.children("option").each(function(index) {
                 var option = $(this);
                 var childIndex = (parentIndex + "." + index);
                 self._appendOption(option, container, childIndex, indent, forceDisabled);
             });
 		},
         _appendOption: function(option, container, index, indent, forceDisabled) {
             var self = this;
             // Note that the browsers destroy any html structure within the OPTION
             var text = option.html();
             var value = option.val();
             var optCss = option.attr('style');
             var selected = option.attr("selected");
 			var disabled = (forceDisabled || option.attr("disabled"));
 			// Use the same tab index as the selector replacement
 			var tabIndex = self.controlSelector.attr("tabindex");
             var item = self._createDropItem(index, tabIndex, value, text, optCss, selected, disabled, indent);
             container.append(item);
         },
         // Synchronizes the items checked and the source select
         // When firstItemChecksAll option is active also synchronizes the checked items
         // senderCheckbox parameters is the checkbox input that generated the synchronization
         _syncSelected: function(senderCheckbox) {
             var self = this, options = this.options, sourceSelect = this.sourceSelect, dropWrapper = this.dropWrapper;
             var selectOptions = sourceSelect.get(0).options;
             var allCheckboxes = dropWrapper.find("input.active");
             if (options.firstItemChecksAll) {
             	if ((senderCheckbox == null) && $(selectOptions[0]).attr("selected") ) {
             		// Initialization call with first item active so force all to be active
-                    allCheckboxes.attr("checked", true);
+                    allCheckboxes.prop("checked", true);
                 } else if ((senderCheckbox != null) && (senderCheckbox.attr("index") == 0)) {
                 	// Check all checkboxes if the first one is checked
-                    allCheckboxes.attr("checked", senderCheckbox.attr("checked"));
+                    allCheckboxes.prop("checked", senderCheckbox.prop("checked"));
                 } else  {
                     // check the first checkbox if all the other checkboxes are checked
                     var allChecked = true;
                     var firstCheckbox = null;
                     allCheckboxes.each(function(index) {
                         if (index > 0) {
-                            var checked = $(this).attr("checked");
+                            var checked = $(this).prop("checked");
                             if (!checked) { allChecked = false; }
                         } else {
                         	firstCheckbox = $(this);
                         }
                     });
                     if ( firstCheckbox != null ) {
-                    	firstCheckbox.attr("checked", allChecked );
+                    	firstCheckbox.prop("checked", allChecked );
                     }
                 }
             }
             // do the actual synch with the source select
             allCheckboxes = dropWrapper.find("input");
             allCheckboxes.each(function(index) {
-                $(selectOptions[index]).attr("selected", $(this).attr("checked"));
+                $(selectOptions[index]).attr("selected", $(this).prop("checked"));
             });
             // update the text shown in the control
             self._updateControlText();
 
         	// Ensure the focus stays pointing where the user is working
         	if ( senderCheckbox != null) { senderCheckbox.focus(); }
         },
         _sourceSelectChangeHandler: function(event) {
             var self = this, dropWrapper = this.dropWrapper;
             dropWrapper.find("input").val(self.sourceSelect.val());
 
         	// update the text shown in the control
         	self._updateControlText();
         },
         // Updates the text shown in the control depending on the checked (selected) items
         _updateControlText: function() {
             var self = this, sourceSelect = this.sourceSelect, options = this.options, controlWrapper = this.controlWrapper;
             var firstOption = sourceSelect.find("option:first");
             var selectOptions = sourceSelect.find("option");
             var text = self._formatText(selectOptions, options.firstItemChecksAll, firstOption);
             var controlLabel = controlWrapper.find(".ui-dropdownchecklist-text");
             controlLabel.html(text);
             // the attribute needs naked text, not html
             controlLabel.attr("title", controlLabel.text());
         },
         // Formats the text that is shown in the control
         _formatText: function(selectOptions, firstItemChecksAll, firstOption) {
             var text;
             if ( $.isFunction(this.options.textFormatFunction) ) {
             	// let the callback do the formatting, but do not allow it to fail
             	try {
                 	text = this.options.textFormatFunction(selectOptions);
                 } catch(ex) {
                 	alert( 'textFormatFunction failed: ' + ex );
                 }
             } else if (firstItemChecksAll && (firstOption != null) && firstOption.attr("selected")) {
                 // just set the text from the first item
                 text = firstOption.html();
             } else {
                 // concatenate the text from the checked items
                 text = "";
                 selectOptions.each(function() {
                     if ($(this).attr("selected")) {
                         if ( text != "" ) { text += ", "; }
                         /* NOTE use of .html versus .text, which can screw up ampersands for IE */
                         var optCss = $(this).attr('style');
                         var tempspan = $('<span/>');
                         tempspan.html( $(this).html() );
                         if ( optCss == null ) {
                         	text += tempspan.html();
                         } else {
                         	tempspan.attr('style',optCss);
                         	text += $("<span/>").append(tempspan).html();
                         }
                     }
                 });
                 if ( text == "" ) {
                     text = (this.options.emptyText != null) ? this.options.emptyText : "&nbsp;";
                 }
             }
             return text;
         },
         // Shows and hides the drop container
         _toggleDropContainer: function( makeOpen ) {
             var self = this;
             // hides the last shown drop container
             var hide = function(instance) {
                 if ((instance != null) && instance.dropWrapper.isOpen ){
                     instance.dropWrapper.isOpen = false;
                     $.ui.dropdownchecklist.gLastOpened = null;
 
 	            	var config = instance.options;
                     instance.dropWrapper.css({
                         top: "-33000px",
                         left: "-33000px"
                     });
                     var aControl = instance.controlSelector;
 	                aControl.removeClass("ui-state-active");
 	                aControl.removeClass("ui-state-hover");
 
                     var anIcon = instance.controlWrapper.find(".ui-icon");
                     if ( anIcon.length > 0 ) {
                     	anIcon.removeClass( (config.icon.toClose != null) ? config.icon.toClose : "ui-icon-triangle-1-s");
                     	anIcon.addClass( (config.icon.toOpen != null) ? config.icon.toOpen : "ui-icon-triangle-1-e");
                     }
                     $(document).unbind("click", hide);
 
                     // keep the items out of the tab order by disabling them
                     instance.dropWrapper.find("input.active").attr("disabled","disabled");
 
                     // the following blur just does not fire???  because it is hidden???  because it does not have focus???
 			  		//instance.sourceSelect.trigger("blur");
 			  		//instance.sourceSelect.triggerHandler("blur");
 			  		if($.isFunction(config.onComplete)) { try {
 			     		config.onComplete.call(instance,instance.sourceSelect.get(0));
                     } catch(ex) {
                     	alert( 'callback failed: ' + ex );
                     }}
                 }
             };
             // shows the given drop container instance
             var show = function(instance) {
             	if ( !instance.dropWrapper.isOpen ) {
 	                instance.dropWrapper.isOpen = true;
 	                $.ui.dropdownchecklist.gLastOpened = instance;
 
 	            	var config = instance.options;
+                    config.positionHow = $.ui.dropdownchecklist.defaults.positionHow;
 /**** Issue127 (and the like) to correct positioning when parent element is relative
  ****	This positioning only worked with simple, non-relative parent position
 	                instance.dropWrapper.css({
 	                    top: instance.controlWrapper.offset().top + instance.controlWrapper.outerHeight() + "px",
 	                    left: instance.controlWrapper.offset().left + "px"
 	                });
 ****/
              		if ((config.positionHow == null) || (config.positionHow == 'absolute')) {
              			/** Floats above subsequent content, but does NOT scroll */
 		                instance.dropWrapper.css({
 		                    position: 'absolute'
 		                ,   top: instance.controlWrapper.offset().top + instance.controlWrapper.outerHeight() + "px"
 		                ,   left: instance.controlWrapper.offset().left + "px"
 		                });
 		            } else if (config.positionHow == 'relative') {
 		            	/** Scrolls with the parent but does NOT float above subsequent content */
 		                instance.dropWrapper.css({
 		                    position: 'relative'
 		                ,   top: "0px"
 		                ,   left: "0px"
 		                });
 					}
 					var zIndex = 0;
 					if (config.zIndex == null) {
 						var ancestorsZIndexes = instance.controlWrapper.parents().map(
 							function() {
 								var zIndex = $(this).css("z-index");
 								return isNaN(zIndex) ? 0 : zIndex; }
 							).get();
 						var parentZIndex = Math.max.apply(Math, ancestorsZIndexes);
 						if ( parentZIndex >= 0) zIndex = parentZIndex+1;
 					} else {
 						/* Explicit set from the optins */
 						zIndex = parseInt(config.zIndex);
 					}
 					if (zIndex > 0) {
 						instance.dropWrapper.css( { 'z-index': zIndex } );
 					}
 
 	                var aControl = instance.controlSelector;
 	                aControl.addClass("ui-state-active");
 	                aControl.removeClass("ui-state-hover");
 
 	                var anIcon = instance.controlWrapper.find(".ui-icon");
 	                if ( anIcon.length > 0 ) {
 	                	anIcon.removeClass( (config.icon.toOpen != null) ? config.icon.toOpen : "ui-icon-triangle-1-e");
 	                	anIcon.addClass( (config.icon.toClose != null) ? config.icon.toClose : "ui-icon-triangle-1-s");
 	                }
 	                $(document).bind("click", function(e) {hide(instance);} );
 
                     // insert the items back into the tab order by enabling all active ones
                     var activeItems = instance.dropWrapper.find("input.active");
                     activeItems.removeAttr("disabled");
 
                     // we want the focus on the first active input item
                     var firstActiveItem = activeItems.get(0);
                     if ( firstActiveItem != null ) {
                     	firstActiveItem.focus();
                     }
 			    }
             };
             if ( makeOpen ) {
             	hide($.ui.dropdownchecklist.gLastOpened);
             	show(self);
             } else {
             	hide(self);
             }
         },
         // Set the size of the control and of the drop container
         _setSize: function(dropCalculatedSize) {
             var options = this.options, dropWrapper = this.dropWrapper, controlWrapper = this.controlWrapper;
 
             // use the width from config options if set, otherwise set the same width as the drop container
             var controlWidth = dropCalculatedSize.width;
             if (options.width != null) {
                 controlWidth = parseInt(options.width);
             } else if (options.minWidth != null) {
                 var minWidth = parseInt(options.minWidth);
                 // if the width is too small (usually when there are no items) set a minimum width
                 if (controlWidth < minWidth) {
                     controlWidth = minWidth;
                 }
             }
             var control = this.controlSelector;
             control.css({ width: controlWidth + "px" });
 
             // if we size the text, then Firefox places icons to the right properly
             // and we do not wrap on long lines
             var controlText = control.find(".ui-dropdownchecklist-text");
             var controlIcon = control.find(".ui-icon");
             if ( controlIcon != null ) {
             	// Must be an inner/outer/border problem, but IE6 needs an extra bit of space,
             	// otherwise you can get text pushed down into a second line when icons are active
             	controlWidth -= (controlIcon.outerWidth() + 4);
             	controlText.css( { width: controlWidth + "px" } );
             }
             // Account for padding, borders, etc
             controlWidth = controlWrapper.outerWidth();
 
             // the drop container height can be set from options
             var maxDropHeight = (options.maxDropHeight != null)
             					? parseInt(options.maxDropHeight)
             					: -1;
             var dropHeight = ((maxDropHeight > 0) && (dropCalculatedSize.height > maxDropHeight))
             					? maxDropHeight
             					: dropCalculatedSize.height;
             // ensure the drop container is not less than the control width (would be ugly)
             var dropWidth = dropCalculatedSize.width < controlWidth ? controlWidth : dropCalculatedSize.width;
 
             $(dropWrapper).css({
                 height: dropHeight + "px",
                 width: dropWidth + "px"
             });
             dropWrapper.find(".ui-dropdownchecklist-dropcontainer").css({
                 height: dropHeight + "px"
             });
         },
         // Initializes the plugin
         _init: function() {
             var self = this, options = this.options;
 			if ( $.ui.dropdownchecklist.gIDCounter == null) {
 				$.ui.dropdownchecklist.gIDCounter = 1;
 			}
             // item blurring relies on a cancelable timer
             self.blurringItem = null;
 
             // sourceSelect is the select on which the plugin is applied
             var sourceSelect = self.element;
             self.initialDisplay = sourceSelect.css("display");
             sourceSelect.css("display", "none");
             self.initialMultiple = sourceSelect.attr("multiple");
             self.isMultiple = self.initialMultiple;
             if (options.forceMultiple != null) { self.isMultiple = options.forceMultiple; }
             ////// UCSC as suggested in issue 176 on DDCL website (not fixed in 1.4)
             ////// This fixes chrome problem of only selecting the first item
             if (!self.initialMultiple && self.isMultiple) ///// UCSC
                 sourceSelect.attr("multiple", true);      ///// UCSC
             self.sourceSelect = sourceSelect;
 
             // append the control that resembles a single selection select
             var controlWrapper = self._appendControl();
             self.controlWrapper = controlWrapper;
             self.controlSelector = controlWrapper.find(".ui-dropdownchecklist-selector");
 
             // create the drop container where the items are shown
             var dropWrapper = self._appendDropContainer(controlWrapper);
             self.dropWrapper = dropWrapper;
 
             // append the items from the source select element
             var dropCalculatedSize = self._appendItems();
 
             // updates the text shown in the control
             self._updateControlText(controlWrapper, dropWrapper, sourceSelect);
 
             // set the sizes of control and drop container
             self._setSize(dropCalculatedSize);
 
             // look for possible auto-check needed on first item
 			if ( options.firstItemChecksAll ) {
 				self._syncSelected(null);
 			}
             // BGIFrame for IE6
 			if (options.bgiframe && typeof self.dropWrapper.bgiframe == "function") {
 				self.dropWrapper.bgiframe();
 			}
           	// listen for change events on the source select element
           	// ensure we avoid processing internally triggered changes
           	self.sourceSelect.change(function(event, eventName) {
 	            if (eventName != 'ddcl_internal') {
 	                self._sourceSelectChangeHandler(event);
 	            }
 	        });
         },
         // Refresh the disable and check state from the underlying control
         _refreshOption: function(item,disabled,selected) {
 			var aParent = item.parent();
 			// account for enabled/disabled
             if ( disabled ) {
             	item.attr("disabled","disabled");
             	item.removeClass("active");
             	item.addClass("inactive");
             	aParent.addClass("ui-state-disabled");
             } else {
             	item.removeAttr("disabled");
             	item.removeClass("inactive");
             	item.addClass("active");
             	aParent.removeClass("ui-state-disabled");
             }
             // adjust the checkbox state
-            item.attr("checked",selected);
+            item.prop("checked",selected);
         },
         _refreshGroup: function(group,disabled) {
             if ( disabled ) {
             	group.addClass("ui-state-disabled");
             } else {
             	group.removeClass("ui-state-disabled");
             }
         },
         // External command to explicitly close the dropdown
         close: function() {
 			this._toggleDropContainer(false);
         },
         // External command to refresh the ddcl from the underlying selector
         refresh: function() {
             var self = this, sourceSelect = this.sourceSelect, dropWrapper = this.dropWrapper;
 
             var allCheckBoxes = dropWrapper.find("input");
             var allGroups = dropWrapper.find(".ui-dropdownchecklist-group");
 
             var groupCount = 0;
             var optionCount = 0;
 			sourceSelect.children().each(function(index) {
 				var opt = $(this);
 				var disabled = opt.attr("disabled");
                 if (opt.is("option")) {
                 	var selected = opt.attr("selected");
                 	var anItem = $(allCheckBoxes[optionCount]);
                     self._refreshOption(anItem, disabled, selected);
                     optionCount += 1;
                 } else if (opt.is("optgroup")) {
                     var text = opt.attr("label");
                     if (text != "") {
                     	var aGroup = $(allGroups[groupCount]);
                     	self._refreshGroup(aGroup, disabled);
                     	groupCount += 1;
 	                }
 					opt.children("option").each(function() {
 		                var subopt = $(this);
 						var subdisabled = (disabled || subopt.attr("disabled"));
                 		var selected = subopt.attr("selected");
                 		var subItem = $(allCheckBoxes[optionCount]);
 		                self._refreshOption(subItem, subdisabled, selected );
 		                optionCount += 1;
 		            });
                 }
 			});
 			// sync will handle firstItemChecksAll and updateControlText
 			self._syncSelected(null);
         },
         // External command to enable the ddcl control
         enable: function() {
             this.controlSelector.removeClass("ui-state-disabled");
             this.disabled = false;
         },
         // External command to disable the ddcl control
         disable: function() {
             this.controlSelector.addClass("ui-state-disabled");
             this.disabled = true;
         },
         // External command to destroy all traces of the ddcl control
         destroy: function() {
             $.Widget.prototype.destroy.apply(this, arguments);
             this.sourceSelect.css("display", this.initialDisplay);
             this.sourceSelect.attr("multiple", this.initialMultiple);
             this.controlWrapper.unbind().remove();
             this.dropWrapper.remove();
         }
     });
 
     $.extend($.ui.dropdownchecklist, {
         defaults: {
             width: null
         ,   maxDropHeight: null
         ,   firstItemChecksAll: false
         ,   closeRadioOnClick: false
         ,   minWidth: 50
-        ,   positionHow: 'absolute'
+        ,   positionHow: 'relative'
         ,   bgiframe: false
         ,	explicitClose: null
         }
     });
 
 })(jQuery);