', { 'class': o.containerClass, id: this.uid });
+
+ this.buildSelect();
+
+ this.$original.change($.proxy(this.originalChangeEvent, this)).wrap(this.$container).before(this.$select);
+
+ // if the list isn't already in the document, add it (it might be inserted by a custom callback)
+ if (!this.$list.parent().length) { this.$original.before(this.$list); }
+
+ if (this.$original.attr('id')) {
+ $('label[for=' + this.$original.attr('id') + ']').attr('for', this.$select.attr('id'));
+ }
+
+ // set up remove event (may be a link, or the list item itself)
+ this.$list.delegate('.' + o.removeClass, 'click', function() {
+ self.dropListItem($(this).closest('li'));
+ return false;
+ });
+
+ $.each(o.plugins, function() { this.init(self); });
+ },
+
+ /**
+ * Triggered when an item has been selected
+ * Check to make sure it's not an IE screwup, and add it to the list
+ */
+ selectChangeEvent: function() {
+ if ($.browser && $.browser.msie && $.browser.version < 7 && !this.ieClick) { return; }
+ var bsmOpt = $('option:selected:eq(0)', this.$select);
+ if (bsmOpt.data('orig-option')) {
+ this.addListItem(bsmOpt);
+ this.triggerOriginalChange(bsmOpt.data('orig-option'), 'add');
+ }
+ this.ieClick = false;
+ },
+
+ /**
+ * IE6 lets you scroll around in a select without it being pulled down
+ * making sure a click preceded the change() event reduces the chance
+ * if unintended items being added. there may be a better solution?
+ */
+ selectClickEvent: function() {
+ this.ieClick = true;
+ },
+
+ /**
+ * Rebuild bsmSelect when the 'change' event is triggered on the original select
+ */
+ originalChangeEvent: function() {
+ if (this.ignoreOriginalChangeEvent) {
+ // We don't want to rebuild everything when an item is added / droped
+ this.ignoreOriginalChangeEvent = false;
+ } else {
+ this.buildSelect();
+ // opera has an issue where it needs a force redraw, otherwise
+ // the items won't appear until something else forces a redraw
+ if ($.browser && $.browser.opera) { this.$list.hide().show(); }
+ }
+ },
+
+ /**
+ * Build the DOM for the new select
+ */
+ buildSelect: function() {
+ var self = this;
+
+ this.buildingSelect = true;
+
+ // add a first option to be the home option / default selectLabel
+ this.$select.empty().prepend($('
').text(this.$original.attr('title') || this.options.title));
+ this.$list.empty();
+
+ this.$original.children().each(function() {
+ if ($(this).is('option')) {
+ self.addSelectOption(self.$select, $(this));
+ } else if ($(this).is('optgroup')) {
+ self.addSelectOptionGroup(self.$select, $(this));
+ }
+ });
+
+ if (!this.options.debugMode) { this.$original.hide(); }
+ this.selectFirstItem();
+ this.buildingSelect = false;
+ },
+
+ /**
+ * Append an option to the new select
+ *
+ * @param {jQuery} $parent Where to append the option
+ * @param {jQuery} $origOpt Option from the original select
+ */
+ addSelectOption: function ($parent, $origOpt) {
+ var $bsmOpt = $('