jQuery – 像radiobuttons这样的复选框

我有组复选框,我喜欢这个组的行为,如具有相同名称属性的radiobuttons。

每个复选框都有不同的名称

只能从复选框中选择一个。

我怎么能这样做?


为什么我需要这个? 因为我们需要一致性webUI。 请问,这不是我们的应用程序架构的问题。 🙂

HTML示例

111
112
113
121
122
123
131
132
133

JavaScript的

 var $groups = $("span.multiGroup", $that); $groups.each(function() { var $group = $(this); var $checkboxes = $(":checkbox", $group); $checkboxes.click(function() { var $activeCheckbox = $(this); var state = $activeCheckbox.attr('checked'); $checkboxes.attr('checked', false); $activeCheckbox.attr('checked', state); }); }); 

这是一个提示:使用单选按钮。 ;)

我不建议这样做,因为它会被认为对可用性不利,并且肯定会违反最少惊喜的原则。 用户已经习惯于期望无线电接受1个支票和复选框以接受许多。 不要让用户思考。

但是,如果你有理由,这里是如何使用jQuery做到这一点:

    

和jQuery:

 var $unique = $('input.unique'); $unique.click(function() { $unique.filter(':checked').not(this).removeAttr('checked'); }); 

这是一个现场样本 。

编辑

正如评论中所指出的,这将允许用户取消选择所有复选框,即使他们最初选择了一个,这与单选按钮不完全相同。 如果你想要这个,那么jQuery看起来像这样:

 var $unique = $('input.unique'); $unique.click(function() { $unique.removeAttr('checked'); $(this).attr('checked', true); }); 

你为什么不用单选按钮?

差异是有原因的。 它是以这种方式设计的,从用户的角度来看,单选按钮意味着“选择一个”,而复选框意味着“选择多个”。

不要通过改变这种经过良好尝试的范例来打破用户的期望。 当应用程序开发人员更喜欢“看起来”而不是可用性和约定时,这是一件坏事,所以不要成为其中之一。

用户界面起作用是因为使用的隐喻(复选框,按钮,鼠标指针的形状,颜色等)是以某种方式表现的。 用户将遇到您的应用程序问题,甚至可能不知道为什么当您执行此类操作时。

这是一个反模式,与使用复选框状态更改标签属于同一类别:

 []启用选项与[]选项
 [x]禁用选项[x]选项

我有类似的问题。 我无法使用单选按钮,因为在某些情况下,相同的表单必须显示多个选项复选框。 我拿了你的标记并写了一小段jQuery:

 $("span.multiGroup input").click(function() { $("span.multiGroup input").attr('checked', false); $(this).attr('checked', true); }); 
 $(".checkboxClass").click(function() { $(".checkboxClass").each(function() { $(this)[0].checked = false;}); $(this)[0].checked = true; }); 

首先清除所有复选框,然后检查单击的复选框。

 var $unique = $('input.unique'); $unique.click(function() { $checked = $(this).is(':checked') ; // check if that was clicked. $unique.removeAttr('checked'); //clear all checkboxes $(this).attr('checked', $checked); // update that was clicked. }); 

HTML

    

使用Javascript

 $('input.unique').each(function() { $(this).on('touchstart click', function() { $('input.unique').not(this).removeAttr('checked'); }); }); 

小提琴: http : //jsfiddle.net/L2ad1vd8/

如果您的页面上只有一组,那么Pablo的答案非常有用。 我试图解决一个让我遇到麻烦的引导实现时遇到了这个问题,因为单选按钮已被完全覆盖,事实certificate只使用复选框作为单选按钮会更容易。

这是此代码的一个版本,它通过引用调用元素的第二个类来允许多个集合。

 $('input.unique').each(function() { $(this).on('touchstart click', function() { var secondClass = $(event.target).attr('class').split(' ')[1]; $('input.' + secondClass).not(this).removeAttr('checked'); }); }); 
     

这个现场演示说明单选按钮可以执行您想要的:

http://jsfiddle.net/ftnwg8yf/

 function selectiongrp_control( s_selectiongrpName, b_useJQueryUiThemeToDecorate ) { var ADF_THIS_IS_LAST_SELECTED_ATTR='adf_this-is-last-selected-attr' var ADF_THIS_IS_LAST_SELECTED_VALUE='adf_this-is-last-selected-val'; if ( !s_selectiongrpName ) return -1; $( '#fieldset-' + s_selectiongrpName + '-result' ).hide(); if( b_useJQueryUiThemeToDecorate ) $( '#jQueryUi-' + s_selectiongrpName).buttonset(); $( 'input[name=' + s_selectiongrpName + ']' ).each( function() { $( this ).on( 'click', function() { if( $( this ).attr( ADF_THIS_IS_LAST_SELECTED_ATTR ) ) { $( this ).removeAttr( 'checked' ); $( this ).removeAttr( ADF_THIS_IS_LAST_SELECTED_ATTR ); } else { $( this ).attr( ADF_THIS_IS_LAST_SELECTED_ATTR, ADF_THIS_IS_LAST_SELECTED_VALUE ); } $( 'input[name=' + s_selectiongrpName + ']' ).not( this ).removeAttr( ADF_THIS_IS_LAST_SELECTED_ATTR ); if( b_useJQueryUiThemeToDecorate ) $( '#jQueryUi-' + s_selectiongrpName ).buttonset( 'refresh' ); if( $( 'input[name=' + s_selectiongrpName + ']:checked' ).length > 0 ) { $( '#fieldset-' + s_selectiongrpName + '-resultarea' ).html( 'You have selected : [' + $( this ).val() + '].'); } else { $( '#fieldset-' + s_selectiongrpName + '-resultarea' ).html( 'Nothing is selected.' ); } $( '#fieldset-' + s_selectiongrpName + '-result' ).show(); }); }); } $( document ).ready( function() { var ADF_USE_JQUERYUI_THEME_TO_DECORATE=true; selectiongrp_control( 'selectiongrp-01', !ADF_USE_JQUERYUI_THEME_TO_DECORATE ); selectiongrp_control( 'selectiongrp-02', ADF_USE_JQUERYUI_THEME_TO_DECORATE ); }); 
        

Plain (without styling/decoration):

Please click to select or re-click to deselect
Result

Decorated by "jQueryUI Theme":

Please click to select or re-click to deselect
Result

基于“单选按钮组”的原始行为,在同一组中只能选择一个单选按钮,“单选按钮方法”始终优于“复选框方法”,因为它可以帮助防止exception数据提交JavaScript或jQuery编码无法正确加载。

然后,我们要解决的唯一挑战是使所选的单选按钮“不可选”。

所以,这里有一个例子来说明,通过使用额外的JavaScript控件,仍然可以取消选择单选按钮。 这个例子使用jQuery作为主要的JavaScript框架。

JSFiddle.net也提供在线版本: http : //jsfiddle.net/0fbef3up/

此示例考虑了在JavaScript或jQuery编码未加载的情况下迎合意外情况,因此提供了“偶然选项”。 为了了解这种特殊情况将如何以及应急如何工作,您可以通过注释/删除相关的代码行来省略加载jQuery库:

  

以下是用于演示的完整HTML / JavaScript代码。 本质是JavaScript函数’selectiongrp_logicControl’,您可以将其研究以供参考。

第一个编码帧的JavaScript(即控制/模型层)和第二个编码帧的HTML(即表示层):

 function selectiongrp_logicControl( s_selectiongrpName, b_useJQueryUiThemeToDecorate ) { // Safeguard measure: If the mandatory function parameter is undefined or empty, nothing can be proceed further, so quit the current function with excit code: if ( !s_selectiongrpName ) return -1; // Define a constant for future use: var ADF_THIS_IS_LAST_SELECTED='adf_this-is-last-selected'; // Hide the 'contingent select option item' and all its relevant ancillary objects (ie the label element): $( '#' + s_selectiongrpName + '-option-X' ).hide(); $( '#' + s_selectiongrpName + '-option-X' ).next( 'label' ).hide(); // Decorate the selection group option items and their labels by applying the jQueryUI 'buttonset' function: if( b_useJQueryUiThemeToDecorate ) $( '#jQueryUi-' + s_selectiongrpName).buttonset(); // Loop for each option item within the selection group: $( 'input[name=' + s_selectiongrpName + ']' ).each( function() { // Define an 'onClick' event for every option item within the selection group: $( this ).on( 'click', function() { // If the option item being clicked is the last selected one, then de-select such item. // Two ways can achieve de-selection, apply either one below to adapt to your programming style or desired controller mechanism. if( $( this ).attr( ADF_THIS_IS_LAST_SELECTED ) ) { // Way[1]: Force selecting another item within the same selection group. // This Way entails the 'contingent select option item'. So, if you consider such 'contingent select option item' is unnecessary/inappropriate to your programming style or controller mechanism, please don't choose this Way. // (Note: Such 'contingent select option item' was deliberately hidden at the outset). // $( '#' + s_selectiongrpName + '-option-X' ).prop( 'checked', true ); // Way[2]: Simply remove the current item's "checked" attribute: $( this ).removeAttr( 'checked' ); // Both Way[1] and Way[2]: Remove the additional attribute from the item being clicked. $( this ).removeAttr( ADF_THIS_IS_LAST_SELECTED ); } else { // Apply an additional attribute to the item being clicked. This additional attribe functioned as a secret hint for internal reference to signify the item was the last seledcted one: $( this ).attr( ADF_THIS_IS_LAST_SELECTED, ADF_THIS_IS_LAST_SELECTED ); } // Other than the item being clicked, all other items (ie denotes by the jQuery 'not( this )' selector) should have removed such additional attribute: $( 'input[name=' + s_selectiongrpName + ']' ).not( this ).removeAttr( ADF_THIS_IS_LAST_SELECTED ); // Force the jQueryUI engine to re-render the decoration to reflect the latest selection by applying the 'buttonset' function again ( provide the 'refresh' parameter ): if( b_useJQueryUiThemeToDecorate ) $( '#jQueryUi-' + s_selectiongrpName ).buttonset( 'refresh' ); // Lastly, this is an optional step, refresh the Result Area for displaying user's latest selection on specific screen area: selectiongrp_visualControl_refreshResultArea( s_selectiongrpName ); }); }); } function selectiongrp_visualControl_refreshResultArea( s_selectiongrpName ) { // Safeguard measure: If the mandatory function parameter is undefined or empty, nothing can be proceed further, so quit the current function with excit code: if( !s_selectiongrpName ) return -1; var adf_resultArea_string; var ADF_RESULTAREA_STRING_NOTHING_SELECTED='Nothing is selected'; // If Way[1] is adopted: if( $( '#' + s_selectiongrpName + '-option-X' ).prop( 'checked' ) ) { adf_resultArea_string=ADF_RESULTAREA_STRING_NOTHING_SELECTED; } else // If Way[2] is adopted: { // If some option items are selected within the selection group: if( $( 'input[name=' + s_selectiongrpName + ']:checked' ).length > 0 ) { adf_resultArea_string='You have selected : [' + $( 'input[name=' + s_selectiongrpName + ']:checked' ).next( 'label' ).text() + ']'; } else { adf_resultArea_string=ADF_RESULTAREA_STRING_NOTHING_SELECTED; } } $( '#fieldset-' + s_selectiongrpName + '-resultarea' ).html( adf_resultArea_string ); $( '#fieldset-' + s_selectiongrpName + '-result' ).show(); } $( document ).ready( function() { var ADF_USE_JQUERYUI_THEME_TO_DECORATE=true; selectiongrp_logicControl( 'selectiongrp-01', !ADF_USE_JQUERYUI_THEME_TO_DECORATE ); selectiongrp_logicControl( 'selectiongrp-02', ADF_USE_JQUERYUI_THEME_TO_DECORATE ); // If jQuery can be loaded properly, the error message must be hidden: $( '#jquery-compatibility-error' ).hide(); }); 
        This webpage is primarily to demonstrate de-selectable radio boxes. 

ERROR: It was detected that JavaScript or jQuery coding does not load properly, so some advance feature cannot be realised.

Style1: Raw (ie no styling/decoration):

Please click to select or re-click to deselect

Style2: Decorated by "jQueryUI Theme" (jQueryUI Theme adopted: 'Redmond'):

Please click to select or re-click to deselect