2014-02-13 29 views
-1

我在這裏貼上我的腳本jquerymultiselect.js如何僅在一個下拉列表中應用腳本?

(function($, undefined) { 

    var multiselectID = 0; 
    var $doc = $(document); 

    $.widget("ech.multiselect", { 

// default options 
options: { 
    header: true, 
    height: 175, 
    minWidth: 225, 
    classes: '', 
    checkAllText: 'Check all', 
    uncheckAllText: 'Uncheck all', 
    noneSelectedText: 'Select options', 
    selectedText: '# selected', 
    selectedList: 0, 
    show: null, 
    hide: null, 
    autoOpen: false, 
    multiple: true, 
    position: {}, 
    appendTo: "body" 
}, 

_create: function() { 
    var el = this.element.hide(); 
    var o = this.options; 

    this.speed = $.fx.speeds._default; // default speed for effects 
    this._isOpen = false; // assume no 

    // create a unique namespace for events that the widget 
    // factory cannot unbind automatically. Use eventNamespace if on 
    // jQuery UI 1.9+, and otherwise fallback to a custom string. 
    this._namespaceID = this.eventNamespace || ('multiselect' + multiselectID); 

    var button = (this.button = $('<button type="button"><span class="ui-icon ui-icon-triangle-1-s"></span></button>')) 
    .addClass('ui-multiselect ui-widget ui-state-default ui-corner-all') 
    .addClass(o.classes) 
    .attr({ 'title':el.attr('title'), 'aria-haspopup':true, 'tabIndex':el.attr('tabIndex') }) 
    .insertAfter(el), 

    buttonlabel = (this.buttonlabel = $('<span />')) 
     .html(o.noneSelectedText) 
     .appendTo(button), 

    menu = (this.menu = $('<div />')) 
     .addClass('ui-multiselect-menu ui-widget ui-widget-content ui-corner-all') 
     .addClass(o.classes) 
     .appendTo($(o.appendTo)), 

    header = (this.header = $('<div />')) 
     .addClass('ui-widget-header ui-corner-all ui-multiselect-header ui-helper-clearfix') 
     .appendTo(menu), 

    headerLinkContainer = (this.headerLinkContainer = $('<ul />')) 
     .addClass('ui-helper-reset') 
     .html(function() { 
     if(o.header === true) { 
      return '<li><a class="ui-multiselect-all" href="#"><span class="ui-icon ui-icon-check"></span><span>' + o.checkAllText + '</span></a></li><li><a class="ui-multiselect-none" href="#"><span class="ui-icon ui-icon-closethick"></span><span>' + o.uncheckAllText + '</span></a></li>'; 
     } else if(typeof o.header === "string") { 
      return '<li>' + o.header + '</li>'; 
     } else { 
      return ''; 
     } 
     }) 
     .append('<li class="ui-multiselect-close"><a href="#" class="ui-multiselect-close"><span class="ui-icon ui-icon-circle-close"></span></a></li>') 
     .appendTo(header), 

    checkboxContainer = (this.checkboxContainer = $('<ul />')) 
     .addClass('ui-multiselect-checkboxes ui-helper-reset') 
     .appendTo(menu); 

    // perform event bindings 
    this._bindEvents(); 

    // build menu 
    this.refresh(true); 

    // some addl. logic for single selects 
    if(!o.multiple) { 
     menu.addClass('ui-multiselect-single'); 
    } 

    // bump unique ID 
    multiselectID++; 
}, 

_init: function() { 
    if(this.options.header === false) { 
    this.header.hide(); 
    } 
    if(!this.options.multiple) { 
    this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none').hide(); 
    } 
    if(this.options.autoOpen) { 
    this.open(); 
    } 
    if(this.element.is(':disabled')) { 
    this.disable(); 
    } 
}, 

refresh: function(init) { 
    var el = this.element; 
    var o = this.options; 
    var menu = this.menu; 
    var checkboxContainer = this.checkboxContainer; 
    var optgroups = []; 
    var html = ""; 
    var id = el.attr('id') || multiselectID++; // unique ID for the label & option tags 

    // build items 
    el.find('option').each(function(i) { 
    var $this = $(this); 
    var parent = this.parentNode; 
    var description = this.innerHTML; 
    var title = this.title; 
    var value = this.value; 
    var inputID = 'ui-multiselect-' + (this.id || id + '-option-' + i); 
    var isDisabled = this.disabled; 
    var isSelected = this.selected; 
    var labelClasses = [ 'ui-corner-all' ]; 
    var liClasses = (isDisabled ? 'ui-multiselect-disabled ' : ' ') + this.className; 
    var optLabel; 

    // is this an optgroup? 
    if(parent.tagName === 'OPTGROUP') { 
     optLabel = parent.getAttribute('label'); 

     // has this optgroup been added already? 
     if($.inArray(optLabel, optgroups) === -1) { 
     html += '<li class="ui-multiselect-optgroup-label ' + parent.className + '"><a href="#">' + optLabel + '</a></li>'; 
     optgroups.push(optLabel); 
     } 
    } 

    if(isDisabled) { 
     labelClasses.push('ui-state-disabled'); 
    } 

    // browsers automatically select the first option 
    // by default with single selects 
    if(isSelected && !o.multiple) { 
     labelClasses.push('ui-state-active'); 
    } 

    html += '<li class="' + liClasses + '">'; 

    // create the label 
    html += '<label for="' + inputID + '" title="' + title + '" class="' + labelClasses.join(' ') + '">'; 
    html += '<input id="' + inputID + '" name="multiselect_' + id + '" type="' + (o.multiple ? "checkbox" : "radio") + '" value="' + value + '" title="' + title + '"'; 

    // pre-selected? 
    if(isSelected) { 
     html += ' checked="checked"'; 
     html += ' aria-selected="true"'; 
    } 

    // disabled? 
    if(isDisabled) { 
     html += ' disabled="disabled"'; 
     html += ' aria-disabled="true"'; 
    } 

    // add the title and close everything off 
    html += ' /><span>' + description + '</span></label></li>'; 
    }); 

    // insert into the DOM 
    checkboxContainer.html(html); 

    // cache some moar useful elements 
    this.labels = menu.find('label'); 
    this.inputs = this.labels.children('input'); 

    // set widths 
    this._setButtonWidth(); 
    this._setMenuWidth(); 

    // remember default value 
    this.button[0].defaultValue = this.update(); 

    // broadcast refresh event; useful for widgets 
    if(!init) { 
    this._trigger('refresh'); 
    } 
}, 

// updates the button text. call refresh() to rebuild 
update: function() { 
    var o = this.options; 
    var $inputs = this.inputs; 
    var $checked = $inputs.filter(':checked'); 
    var numChecked = $checked.length; 
    var value; 

    if(numChecked === 0) { 
    value = o.noneSelectedText; 
    } else { 
    if($.isFunction(o.selectedText)) { 
     value = o.selectedText.call(this, numChecked, $inputs.length, $checked.get()); 
    } else if(/\d/.test(o.selectedList) && o.selectedList > 0 && numChecked <= o.selectedList) { 
     value = $checked.map(function() { return $(this).next().html(); }).get().join(', '); 
    } else { 
     value = o.selectedText.replace('#', numChecked).replace('#', $inputs.length); 
    } 
    } 

    this._setButtonValue(value); 

    return value; 
}, 

// this exists as a separate method so that the developer 
// can easily override it. 
_setButtonValue: function(value) { 
    this.buttonlabel.text(value); 
}, 

// binds events 
_bindEvents: function() { 
    var self = this; 
    var button = this.button; 

    function clickHandler() { 
    self[ self._isOpen ? 'close' : 'open' ](); 
    return false; 
    } 

    // webkit doesn't like it when you click on the span :(
    button 
    .find('span') 
    .bind('click.multiselect', clickHandler); 

    // button events 
    button.bind({ 
    click: clickHandler, 
    keypress: function(e) { 
     switch(e.which) { 
     case 27: // esc 
      case 38: // up 
      case 37: // left 
      self.close(); 
     break; 
     case 39: // right 
      case 40: // down 
      self.open(); 
     break; 
     } 
    }, 
    mouseenter: function() { 
     if(!button.hasClass('ui-state-disabled')) { 
     $(this).addClass('ui-state-hover'); 
     } 
    }, 
    mouseleave: function() { 
     $(this).removeClass('ui-state-hover'); 
    }, 
    focus: function() { 
     if(!button.hasClass('ui-state-disabled')) { 
     $(this).addClass('ui-state-focus'); 
     } 
    }, 
    blur: function() { 
     $(this).removeClass('ui-state-focus'); 
    } 
    }); 

    // header links 
    this.header.delegate('a', 'click.multiselect', function(e) { 
    // close link 
    if($(this).hasClass('ui-multiselect-close')) { 
     self.close(); 

     // check all/uncheck all 
    } else { 
     self[$(this).hasClass('ui-multiselect-all') ? 'checkAll' : 'uncheckAll'](); 
    } 

    e.preventDefault(); 
    }); 

    // optgroup label toggle support 
    this.menu.delegate('li.ui-multiselect-optgroup-label a', 'click.multiselect', function(e) { 
    e.preventDefault(); 

    var $this = $(this); 
    var $inputs = $this.parent().nextUntil('li.ui-multiselect-optgroup-label').find('input:visible:not(:disabled)'); 
    var nodes = $inputs.get(); 
    var label = $this.parent().text(); 

    // trigger event and bail if the return is false 
    if(self._trigger('beforeoptgrouptoggle', e, { inputs:nodes, label:label }) === false) { 
     return; 
    } 

    // toggle inputs 
    self._toggleChecked(
     $inputs.filter(':checked').length !== $inputs.length, 
     $inputs 
    ); 

    self._trigger('optgrouptoggle', e, { 
     inputs: nodes, 
     label: label, 
     checked: nodes[0].checked 
    }); 
    }) 
    .delegate('label', 'mouseenter.multiselect', function() { 
    if(!$(this).hasClass('ui-state-disabled')) { 
     self.labels.removeClass('ui-state-hover'); 
     $(this).addClass('ui-state-hover').find('input').focus(); 
    } 
    }) 
    .delegate('label', 'keydown.multiselect', function(e) { 
    e.preventDefault(); 

    switch(e.which) { 
     case 9: // tab 
     case 27: // esc 
     self.close(); 
     break; 
     case 38: // up 
     case 40: // down 
     case 37: // left 
     case 39: // right 
     self._traverse(e.which, this); 
     break; 
     case 13: // enter 
     $(this).find('input')[0].click(); 
     break; 
    } 
    }) 
    .delegate('input[type="checkbox"], input[type="radio"]', 'click.multiselect', function(e) { 
    var $this = $(this); 
    var val = this.value; 
    var checked = this.checked; 
    var tags = self.element.find('option'); 

    // bail if this input is disabled or the event is cancelled 
    if(this.disabled || self._trigger('click', e, { value: val, text: this.title, checked: checked }) === false) { 
     e.preventDefault(); 
     return; 
    } 

    // make sure the input has focus. otherwise, the esc key 
    // won't close the menu after clicking an item. 
    $this.focus(); 

    // toggle aria state 
    $this.attr('aria-selected', checked); 

    // change state on the original option tags 
    tags.each(function() { 
     if(this.value === val) { 
     this.selected = checked; 
     } else if(!self.options.multiple) { 
     this.selected = false; 
     } 
    }); 

    // some additional single select-specific logic 
    if(!self.options.multiple) { 
     self.labels.removeClass('ui-state-active'); 
     $this.closest('label').toggleClass('ui-state-active', checked); 

     // close menu 
     self.close(); 
    } 

    // fire change on the select box 
    self.element.trigger("change"); 

    // setTimeout is to fix multiselect issue #14 and #47. caused by jQuery issue #3827 
    // http://bugs.jquery.com/ticket/3827 
    setTimeout($.proxy(self.update, self), 10); 
    }); 

    // close each widget when clicking on any other element/anywhere else on the page 
    $doc.bind('mousedown.' + this._namespaceID, function(event) { 
    var target = event.target; 

    if(self._isOpen 
     && target !== self.button[0] 
     && target !== self.menu[0] 
     && !$.contains(self.menu[0], target) 
     && !$.contains(self.button[0], target) 
    ) { 
     self.close(); 
    } 
    }); 

    // deal with form resets. the problem here is that buttons aren't 
    // restored to their defaultValue prop on form reset, and the reset 
    // handler fires before the form is actually reset. delaying it a bit 
    // gives the form inputs time to clear. 
    $(this.element[0].form).bind('reset.multiselect', function() { 
    setTimeout($.proxy(self.refresh, self), 10); 
    }); 
}, 

// set button width 
_setButtonWidth: function() { 
    var width = this.element.outerWidth(); 
    var o = this.options; 

    if(/\d/.test(o.minWidth) && width < o.minWidth) { 
    width = o.minWidth; 
    } 

    // set widths 
    this.button.outerWidth(width); 
}, 

// set menu width 
_setMenuWidth: function() { 
    var m = this.menu; 
    m.outerWidth(this.button.outerWidth()); 
}, 

// move up or down within the menu 
_traverse: function(which, start) { 
    var $start = $(start); 
    var moveToLast = which === 38 || which === 37; 

    // select the first li that isn't an optgroup label/disabled 
    var $next = $start.parent()[moveToLast ? 'prevAll' : 'nextAll']('li:not(.ui-multiselect-disabled, .ui-multiselect-optgroup-label)').first(); 

    // if at the first/last element 
    if(!$next.length) { 
    var $container = this.menu.find('ul').last(); 

    // move to the first/last 
    this.menu.find('label')[ moveToLast ? 'last' : 'first' ]().trigger('mouseover'); 

    // set scroll position 
    $container.scrollTop(moveToLast ? $container.height() : 0); 

    } else { 
    $next.find('label').trigger('mouseover'); 
    } 
}, 

// This is an internal function to toggle the checked property and 
// other related attributes of a checkbox. 
// 
// The context of this function should be a checkbox; do not proxy it. 
_toggleState: function(prop, flag) { 
    return function() { 
    if(!this.disabled) { 
     this[ prop ] = flag; 
    } 

    if(flag) { 
     this.setAttribute('aria-selected', true); 
    } else { 
     this.removeAttribute('aria-selected'); 
    } 
    }; 
}, 

_toggleChecked: function(flag, group) { 
    var $inputs = (group && group.length) ? group : this.inputs; 
    var self = this; 

    // toggle state on inputs 
    $inputs.each(this._toggleState('checked', flag)); 

    // give the first input focus 
    $inputs.eq(0).focus(); 

    // update button text 
    this.update(); 

    // gather an array of the values that actually changed 
    var values = $inputs.map(function() { 
    return this.value; 
    }).get(); 

    // toggle state on original option tags 
    this.element 
    .find('option') 
    .each(function() { 
     if(!this.disabled && $.inArray(this.value, values) > -1) { 
     self._toggleState('selected', flag).call(this); 
     } 
    }); 

    // trigger the change event on the select 
    if($inputs.length) { 
    this.element.trigger("change"); 
    } 
}, 

_toggleDisabled: function(flag) { 
    this.button.attr({ 'disabled':flag, 'aria-disabled':flag })[ flag ? 'addClass' : 'removeClass' ]('ui-state-disabled'); 

    var inputs = this.menu.find('input'); 
    var key = "ech-multiselect-disabled"; 

    if(flag) { 
    // remember which elements this widget disabled (not pre-disabled) 
    // elements, so that they can be restored if the widget is re-enabled. 
    inputs = inputs.filter(':enabled').data(key, true) 
    } else { 
    inputs = inputs.filter(function() { 
     return $.data(this, key) === true; 
    }).removeData(key); 
    } 

    inputs 
    .attr({ 'disabled':flag, 'arial-disabled':flag }) 
    .parent()[ flag ? 'addClass' : 'removeClass' ]('ui-state-disabled'); 

    this.element.attr({ 
    'disabled':flag, 
    'aria-disabled':flag 
    }); 
}, 

// open the menu 
open: function(e) { 
    var self = this; 
    var button = this.button; 
    var menu = this.menu; 
    var speed = this.speed; 
    var o = this.options; 
    var args = []; 

    // bail if the multiselectopen event returns false, this widget is disabled, or is already open 
    if(this._trigger('beforeopen') === false || button.hasClass('ui-state-disabled') || this._isOpen) { 
    return; 
    } 

    var $container = menu.find('ul').last(); 
    var effect = o.show; 

    // figure out opening effects/speeds 
    if($.isArray(o.show)) { 
    effect = o.show[0]; 
    speed = o.show[1] || self.speed; 
    } 

    // if there's an effect, assume jQuery UI is in use 
    // build the arguments to pass to show() 
    if(effect) { 
    args = [ effect, speed ]; 
    } 

    // set the scroll of the checkbox container 
    $container.scrollTop(0).height(o.height); 

    // positon 
    this.position(); 

    // show the menu, maybe with a speed/effect combo 
    $.fn.show.apply(menu, args); 

    // select the first not disabled option 
    // triggering both mouseover and mouseover because 1.4.2+ has a bug where triggering mouseover 
    // will actually trigger mouseenter. the mouseenter trigger is there for when it's eventually fixed 
    this.labels.filter(':not(.ui-state-disabled)').eq(0).trigger('mouseover').trigger('mouseenter').find('input').trigger('focus'); 

    button.addClass('ui-state-active'); 
    this._isOpen = true; 
    this._trigger('open'); 
}, 

// close the menu 
close: function() { 
if(this._trigger('beforeclose') === false) { 
    return; 
    } 

    var o = this.options; 
    var effect = o.hide; 
    var speed = this.speed; 
    var args = []; 

    // figure out opening effects/speeds 
    if($.isArray(o.hide)) { 
    effect = o.hide[0]; 
    speed = o.hide[1] || this.speed; 
    } 

    if(effect) { 
    args = [ effect, speed ]; 
    } 

    $.fn.hide.apply(this.menu, args); 
    this.button.removeClass('ui-state-active').trigger('blur').trigger('mouseleave'); 
    this._isOpen = false; 
    this._trigger('close'); 
}, 

enable: function() { 
    this._toggleDisabled(false); 
}, 

disable: function() { 
    this._toggleDisabled(true); 
}, 

checkAll: function(e) { 
    this._toggleChecked(true); 
    this._trigger('checkAll'); 
}, 

uncheckAll: function() { 
    this._toggleChecked(false); 
    this._trigger('uncheckAll'); 
}, 

getChecked: function() { 
    return this.menu.find('input').filter(':checked'); 
}, 

destroy: function() { 
    // remove classes + data 
    $.Widget.prototype.destroy.call(this); 

    // unbind events 
    $doc.unbind(this._namespaceID); 

    this.button.remove(); 
    this.menu.remove(); 
    this.element.show(); 

    return this; 
}, 

isOpen: function() { 
    return this._isOpen; 
}, 

widget: function() { 
    return this.menu; 
}, 

getButton: function() { 
    return this.button; 
}, 
position: function() { 
    var o = this.options; 

    // use the position utility if it exists and options are specifified 
    if ($.ui.position && !$.isEmptyObject(o.position)) { 
     o.position.of = o.position.of || this.button; 

     this.menu 
     .show() 
     .position(o.position) 
     .hide(); 

     // otherwise fallback to custom positioning 
    } else { 
     var pos = this.button.offset(); 

     this.menu.css({ 
      top: pos.top + this.button.outerHeight(), 
      left: pos.left 
     }); 
    } 
}, 

// react to option changes after initialization 
_setOption: function (key, value) { 
    var menu = this.menu; 

    switch (key) { 
     case 'header': 
      menu.find('div.ui-multiselect-header')[value ? 'show' : 'hide'](); 
      break; 
     case 'checkAllText': 
      menu.find('a.ui-multiselect-all span').eq(-1).text(value); 
      break; 
     case 'uncheckAllText': 
      menu.find('a.ui-multiselect-none span').eq(-1).text(value); 
      break; 
     case 'height': 
      menu.find('ul').last().height(parseInt(value, 10)); 
      break; 
     case 'minWidth': 
      this.options[key] = parseInt(value, 10); 
      this._setButtonWidth(); 
      this._setMenuWidth(); 
      break; 
     case 'selectedText': 
     case 'selectedList': 
     case 'noneSelectedText': 
      this.options[key] = value; // these all needs to update immediately for the update() call 
      this.update(); 
      break; 
     case 'classes': 
      menu.add(this.button).removeClass(this.options.classes).addClass(value); 
      break; 
     case 'multiple': 
      menu.toggleClass('ui-multiselect-single', !value); 
      this.options.multiple = value; 
      this.element[0].multiple = value; 
      this.refresh(); 
      break; 
     case 'position': 
      this.position(); 
    } 

    $.Widget.prototype._setOption.apply(this, arguments); 
} 
}); 

})(jQuery); 

雖然我在下降應用此腳本下拉列表中會影響我的網頁全部下降downlists。如何限制?

+0

這是很多代碼。將其縮小到相關部分。 –

+0

代碼原本來自這裏:https://raw2.github.com/ehynds/jquery-ui-multiselect-widget/1.13/src/jquery.multiselect.js –

回答

1

給下拉你想定位一個唯一的ID,並使用它,當你初始化插件。

例如

$("#myUniqueId").multiSelect(); 
+0

非常感謝@Jack Zelig – Madhu

+0

如何調用取消選擇所有方法? – kamal

+0

'$('#your-select')。multiSelect('deselect_all');' –

相關問題