我有一个select
元素,其中包含option
个分组。单击option
时,我需要选择(或取消选中)optgroup
中的所有option
。我还需要能够同时选择多个optgroup
。
我希望它的工作方式是:
查看Stack Overflow上的其他答案,我创建了以下内容:
HTML:
<select multiple="multiple" size="10">
<optgroup label="Queen">
<option value="Mercury">Freddie</option>
<option value="May">Brian</option>
<option value="Taylor">Roger</option>
<option value="Deacon">John</option>
</optgroup>
<optgroup label="Pink Floyd">
<option value="Waters">Roger</option>
<option value="Gilmour">David</option>
<option value="Mason">Nick</option>
<option value="Wright">Richard</option>
</optgroup>
</select>
jQuery的:
$('select').click(selectSiblings);
function selectSiblings(ev) {
var clickedOption = $(ev.target);
var siblings = clickedOption.siblings();
if (clickedOption.is(":selected")) {
siblings.attr("selected", "selected");
} else {
siblings.removeAttr("selected");
}
}
我在这里举了一个例子:http://jsfiddle.net/mflodin/Ndkct/ (遗憾的是,jsFiddle似乎不再支持IE8了。)
这在Firefox(16.0)中按预期工作,但在IE8中它根本不起作用。从其他答案中我发现IE8无法处理click
或optgroup
上的option
事件,这就是我将其绑定到select
然后使用的原因$(ev.target)
。但在IE8中,$(ev.target)
仍然指向整个select
,而不是指向被点击的option
。如何找出被点击的option
(或包含optgroup
)以及是否已选中或取消选择?
另一个意外的行为,但相比较小,是在Chrome(20.0)中,取消选择直到鼠标离开select
才会发生。有人知道解决方法吗?
答案 0 :(得分:3)
不是选择选项跨浏览器问题的具体问题的答案,我认为已经回答了,但是选择数据并将其传回服务器的问题的解决方案是将您的标记更改为某些内容哪个更适合多种选择
如果您使用复选框,则可以将它们放在列表中并添加enhanching js以选择all并取消选择所有
<dl>
<dt>Queen</dt>
<dd>
<ul>
<li>
<input id="Mercury" name="bandmembers" value="Mercury" type="checkbox" />
<label for="Mercury">Freddie</label>
</li>
<li>
<input id="May" name="bandmembers" value="May" type="checkbox" />
<label for="May">Brian</label>
</li>
<li>
<input id="Taylor" name="bandmembers" value="Taylor" type="checkbox" />
<label for="Taylor">Roger</label>
</li>
<li>
<input id="Deacon" name="bandmembers" value="Deacon" type="checkbox" />
<label for="Deacon">John</label>
</li>
</ul>
</dd>
<dt>Pink Floyd</dt> ...
js现在足够简单了
$("dt")
.css("cursor","pointer")
.click(function(){
var $el = $(this).next();
var $checks = $el.find(":checkbox");
if($checks.is(":not(:checked)")){
$checks.attr("checked",true);
}else{
$checks.attr("checked",false);
}
});
(这个小提琴http://jsfiddle.net/Ndkct/44/添加一个父复选框以使其更有用)
答案 1 :(得分:1)
由于版本10的Internet Explorer仍然不支持optgroup
或option
上的任何有用事件,因此任何针对此问题的跨浏览器解决方案都不能依赖于这些元素的直接事件。 / p>
注意: MSDN文档声称optgroup
支持click
个事件,但从IE 10开始,这似乎仍未成为现实:http://msdn.microsoft.com/en-us/library/ie/ms535876(v=vs.85).aspx < / p>
我在Chrome 27,Firefox 20,Safari 6,IE 9和IE 10中测试了以下内容(我目前无法访问IE 8)。
以下是您可以使用的示例:http://jsfiddle.net/potatosalad/Ndkct/38/
// Detect toggle key (toggle selection)
$('select')
.on('mousedown', function(event) {
// toggleKey = Command for Mac OS X; Control for others
var toggleKey = (!event.metaKey && event.ctrlKey && !(/Mac OS/.test(navigator.userAgent))) ? event.ctrlKey : event.metaKey;
if (toggleKey === true) {
$(this).data('toggleKey', true);
}
$(this).data('_mousedown', true);
})
.on('mouseup', function() {
$(this).data('_mousedown', null);
});
// Chrome fix for mouseup outside select
$(document).on('mouseup', ':not(select)', function() {
var $select = $('select');
if ($select.data('_mousedown') === true) {
$select.data('_mousedown', null);
$select.trigger('change');
}
});
$('select')
.on('focus', storeState)
.on('change', changeState);
function storeState() {
$(this).data('previousGroup', $('option:selected', this).closest('optgroup'));
$(this).data('previousVal', $(this).val());
};
function changeState() {
var select = this,
args = Array.prototype.slice.call(arguments);
var previousGroup = $(select).data('previousGroup'),
previousVal = $(select).data('previousVal');
var currentGroup = null,
currentVal = $(select).val();
var selected = $('option:selected', select),
groups = selected.closest('optgroup');
console.log("[change] %o -> %o", previousVal, currentVal);
if ((previousVal === currentVal) && (groups && groups.length == 1)) {
// selected options have not changed
// AND
// only 1 optgroup is selected
// -> do nothing
} else if (currentVal === null || currentVal.length === 0) {
// zero options selected
// -> store state and do nothing
storeState.apply(select, args);
} else { // a select/deselect change has occurred
if ($(select).data('toggleKey') === true
&& (previousVal !== null && previousGroup !== null && groups !== null)
&& (previousVal.length > currentVal.length)
&& (previousGroup.length === groups.length)
&& (previousGroup.get(0) === groups.get(0))) {
// options within the same optgroup have been deselected
// -> deselect all and store state
$(select).val(null);
storeState.apply(select, args);
} else if (currentVal.length === 1) {
// single option selected
// -> use groups
currentGroup = groups;
} else if (groups.length === 1) {
// multiple options selected within same optgroup
// -> use groups
currentGroup = groups;
} else {
// multiple options selected spanning multiple optgroups
// -> use last optgroup
currentGroup = groups.last();
}
}
$(select).data('toggleKey', null);
if (currentGroup !== null) {
$('optgroup', select).not(currentGroup).children(':selected').attr('selected', false);
$(currentGroup).children(':not(:selected)').attr('selected', true);
storeState.apply(select, args);
}
};
它的工作原理是在select
元素上存储先前选择的组和选项,并确定应选择(或取消选择)optgroup
。
可以根据开发人员的需求更改某些行为。例如,如果选择跨越多个options
的多个optgroups
(通过点击并向下拖动,如屏幕截图所示):
此情况的默认冲突解决方案是始终使用最后一个optgroup
,但可以更改为始终使用第一个,或optgroup
已选择最多的选项。< / p>
答案 2 :(得分:0)
这解决了问题,你只需要在init选择后添加这段代码。
$( '.chzn-results .group-result' ).each( function () {
var self = $( this )
, options = $( '~li', self )
, next = options.filter( '.group-result' ).get( 0 )
;
self.data( 'chzn-options', options.slice( 0, options.index( next ) ) );
} )
.click( function () {
$( this ).data( 'chzn-options' ).mouseup()
} )
.hover( function () {
$( this ).data( 'chzn-options' ).addClass( 'highlighted' );
}, function () {
$( this ).data( 'chzn-options' ).removeClass( 'highlighted' );
} )
.css( { cursor: 'pointer' } )
感谢adriengibrat在github上发布了此修复程序:
https://github.com/harvesthq/chosen/issues/323
答案 3 :(得分:0)
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
$(document).ready(function() {
$('select').click(function(tar) {
var justClickValue = tar.target.value;
var selectedGroup = $('option[value="'+justClickValue+'"]').parent();
if (selectedGroup.hasClass("allSelected")) {
selectedGroup.removeClass("allSelected");
$("option").each(function() {
$(this).removeAttr("selected");
});
} else {
$(".allSelected").removeClass("allSelected");
selectedGroup.addClass("allSelected");
$(".allSelected option").each(function() {
$(this).attr("selected", "selected");
});
}
});
});
答案 4 :(得分:-1)
根据您的问题选择/取消选择所有选项。 您可以尝试以下代码,可能会对您有所帮助。
代码:
javascript代码:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js">
$(function(){
$('#allcheck').click(function(){
var chk=$('#select_option >optgroup > option');
chk.each(function(){
$(this).attr('selected','selected');
});
});
$('#alluncheck').click(function(){
var chk=$('#select_option >optgroup > option');
chk.each(function(){
$(this).removeAttr('selected');
});
});});
HtML代码:
<select multiple="multiple" size="10" id="select_option" name="option_value[]">
<optgroup label="Queen">
<option value="Mercury">Freddie</option>
<option value="May">Brian</option>
<option value="Taylor">Roger</option>
<option value="Deacon">John</option>
</optgroup>
<optgroup label="Pink Floyd">
<option value="Waters">Roger</option>
<option value="Gilmour">David</option>
<option value="Mason">Nick</option>
<option value="Wright">Richard</option>
</optgroup>
</select>
<br>
<strong>Select <a style="cursor:pointer;" id="allcheck">All</a>
| <a style="cursor:pointer;" id="alluncheck">None</a></strong>
答案 5 :(得分:-1)
希望这会起作用
$("#SelectID").live("click",function() {
var elements = this.options; //or document.getElementById("SelectID").options;
for(var i = 0; i < elements.length; i++){
if(!elements[i].selected)
elements[i].selected = true;
}
}