JQuery - флажки, такие как радиокнопки - PullRequest
19 голосов
/ 19 мая 2009

У меня есть флажки группы, и мне нравится, если эта группа ведет себя как радио-кнопки с тем же атрибутом имени.

Каждый флажок имеет свое имя.

Из флажков можно выбрать только один.

Как я могу это сделать?


Решение

Зачем мне это нужно? Потому что нам нужна согласованность webUI. Пожалуйста, это не вопрос архитектуры нашего приложения. :)

Образец HTML

<div class="multiCheckBox">
 <span class="multiGroup">
  <div><input class="multiItem" value="111" name="list" type="checkbox" />111</div>
  <div><input class="multiItem" value="112" name="list" type="checkbox" />112</div>
  <div><input class="multiItem" value="113" name="list" type="checkbox" />113</div>
 </span>
 <span>
  <div><input class="multiItem" value="121" name="list" type="checkbox" />121</div>
  <div><input class="multiItem" value="122" name="list" type="checkbox" />122</div>
  <div><input class="multiItem" value="133" name="list" type="checkbox" />123</div>
 </span>
 <span>
  <div><input class="multiItem" value="131" name="list" type="checkbox" />131</div>
  <div><input class="multiItem" value="132" name="list" type="checkbox" />132</div>
  <div><input class="multiItem" value="133" name="list" type="checkbox" />133</div>
 </span>
</div>

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);
    });
});

Ответы [ 9 ]

67 голосов
/ 19 мая 2009

Вот подсказка: используйте радио-кнопки. ;)

Я бы не рекомендовал делать это, потому что это было бы плохо для юзабилити и, конечно, нарушало бы принцип наименьшего удивления. Пользователи должны были ожидать, что радиоприемники примут 1 флажок, а флажки - много. Не заставляйте пользователей думать.

Если у вас есть свои причины, вот как это сделать с помощью jQuery:

<input type='checkbox' name='mygroup1' value='1' class='unique'>
<input type='checkbox' name='mygroup2' value='2' class='unique'>
<input type='checkbox' name='mygroup3' value='3' class='unique'>

И JQuery:

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

А вот живой пример .

EDIT

Как указано в комментариях, это позволит пользователю отменить выбор всех флажков, даже если они изначально выбрали один, что не совсем так, как переключатели. Если вы хотите это, то jQuery будет выглядеть так:

var $unique = $('input.unique');
$unique.click(function() {
    $unique.removeAttr('checked');
    $(this).attr('checked', true);
});
6 голосов
/ 19 мая 2009

Почему бы вам не использовать радио-кнопки?

Разница есть по причине. Он был разработан таким образом, и с точки зрения пользователя переключатели означают «выбрать один», а флажки означают «выбрать много».

Не нарушайте ожиданий пользователей, изменяя эту проверенную парадигму. Плохо, когда разработчики приложений предпочитают «взгляды» на удобство использования и соглашения, поэтому не будьте одним из них.

Пользовательские интерфейсы работают, потому что используемые метафоры (флажки, кнопки, форма указателя мыши, цвета и т. Д.) Действуют и ведут себя определенным образом. Пользователи будут иметь проблемы с вашим приложением и могут даже не знать, почему, когда вы делаете подобные вещи.

Это анти-шаблон, относящийся к той же категории, что и изменение метки с состоянием флажка:

[ ] enable option        vs.      [ ] option
[x] disable option                [x] option
2 голосов
/ 08 июня 2012

У меня была похожая проблема. Я не мог использовать переключатель, потому что в некоторых ситуациях одна и та же форма должна была отображать флажки с несколькими вариантами выбора. Я взял вашу разметку и написал этот маленький кусочек jQuery:

$("span.multiGroup input").click(function() {
    $("span.multiGroup input").attr('checked', false);
    $(this).attr('checked', true);
});
1 голос
/ 17 октября 2013
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.

});
1 голос
/ 19 мая 2009
$(".checkboxClass").click(function() {
    $(".checkboxClass").each(function() {
        $(this)[0].checked = false;});
    $(this)[0].checked = true;
});

Сначала снимите все флажки, затем отметьте тот, который был нажат.

0 голосов
/ 08 мая 2015

Исходя из примитивного поведения «группы радиокнопок», когда в одной и той же группе можно выбрать только одну радиокнопку, «подход радиокнопок» всегда предпочтительнее, чем «подход флажков», поскольку это может помочь предотвратить аномальную передачу данных событие JavaScript или кодирования jQuery не может быть загружено должным образом.

Тогда единственная задача, которую мы должны решить, - это сделать выбранный переключатель «отменяемым».

Итак, вот пример, демонстрирующий, что с помощью дополнительного элемента управления JavaScript переключатели все еще можно отменить. В этом примере jQuery использовался как основная структура JavaScript.

Онлайн-версия также доступна в JSFiddle.net: http://jsfiddle.net/0fbef3up/

В этом примере рассматривается сценарий непредвиденных обстоятельств, если не загружается кодирование JavaScript или jQuery, и поэтому предоставляется «элемент условного варианта». Чтобы увидеть, каким будет такой особый сценарий и как работает непредвиденный случай, вы можете просто пропустить загрузку библиотеки jQuery, комментируя / удаляя соответствующую строку кода:

<script type='text/javascript' src='http://code.jquery.com/jquery-2.1.4.min.js'></script>

Ниже приведен полный код 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 (i.e. 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 (i.e. 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();
});
<!-- Load jQuery core library -->
<script type='text/javascript' src='http://code.jquery.com/jquery-2.1.4.min.js'></script>

<!-- Load jQueryUI library -->
<script type='text/javascript' src='http://code.jquery.com/ui/1.11.4/jquery-ui.min.js'></script>

<!-- Load jQueryUI Theme library (make either one effective) -->
<!--
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.min.css'/>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/ui-darkness/jquery-ui.min.css'/>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/blitzer/jquery-ui.min.css'/>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/eggplant/jquery-ui.min.css'/>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/flick/jquery-ui.min.css'/>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.min.css'/>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/sunny/jquery-ui.min.css'/>
-->
<link rel='stylesheet' type='text/css' href='http://code.jquery.com/ui/1.11.4/themes/redmond/jquery-ui.min.css'>


This webpage is primarily to demonstrate de-selectable radio boxes.

<h3 id='jquery-compatibility-error'>ERROR: It was detected that JavaScript or jQuery coding does not load properly, so some advance feature cannot be realised.</h3>

<h3>Style1: Raw (i.e. no styling/decoration):</h3>
<fieldset id='fieldset-selectiongrp-01'>
	<legend>Please <b>click</b> to <b>select</b> or <b>re-click</b> to <b>deselect</b></legend>
	<span id='jQueryUi-selectiongrp-01'>
		<input type='radio' name='selectiongrp-01' value='X' id='selectiongrp-01-option-X' checked/><label for='selectiongrp-01-option-X'>None/NULL/Non-Selected <small><small>(This option is provided for contingency purpose in case JavaScript or jQuery does not load)</small></small></label>
		<input type='radio' name='selectiongrp-01' value='Y' id='selectiongrp-01-option-Y'/><label for='selectiongrp-01-option-Y'>Yes</label>
		<input type='radio' name='selectiongrp-01' value='N' id='selectiongrp-01-option-N'/><label for='selectiongrp-01-option-N'>No</label>
		<input type='radio' name='selectiongrp-01' value='U' id='selectiongrp-01-option-U' /><label for='selectiongrp-01-option-U'>Unknown</label>
	</span>
</fieldset>
<fieldset id='fieldset-selectiongrp-01-result' style='display:none'>  <!-- Initaially hidden by using stylesheet attribute "style='display:none'"-->
	<legend>Selection</legend>
	<span id='fieldset-selectiongrp-01-resultarea'><br/></span>
</fieldset>

<br/>

<h3>Style2: Decorated by &quot;jQueryUI Theme&quot; <small><small>(jQueryUI Theme adopted: '<i>Redmond</i>')</small></small>:</h3>
<fieldset id='fieldset-selectiongrp-02'>
	<legend>Please <b>click</b> to <b>select</b> or <b>re-click</b> to <b>deselect</b></legend>
	<span id='jQueryUi-selectiongrp-02'>
		<input type='radio' name='selectiongrp-02' value='X' id='selectiongrp-02-option-X' checked/><label for='selectiongrp-02-option-X'>None/NULL/Non-Selected <small><small>(This option is provided for contingency purpose in case JavaScript or jQuery does not load)</small></small></label>
		<input type='radio' name='selectiongrp-02' value='Y' id='selectiongrp-02-option-Y'/><label for='selectiongrp-02-option-Y'>Yes</label>
		<input type='radio' name='selectiongrp-02' value='N' id='selectiongrp-02-option-N'/><label for='selectiongrp-02-option-N'>No</label>
		<input type='radio' name='selectiongrp-02' value='U' id='selectiongrp-02-option-U' /><label for='selectiongrp-02-option-U'>Unknown</label>
	</span>
</fieldset>
<fieldset id='fieldset-selectiongrp-02-result'style='display:none;'>  <!-- Initaially hidden by using stylesheet attribute "style='display:none'"-->
	<legend>Selection</legend>
	<span id='fieldset-selectiongrp-02-resultarea'><br/></span>
</fieldset>
0 голосов
/ 06 мая 2015

Эта демонстрация в прямом эфире показывает, что Radio Button может выполнять то, что вы хотели:

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 );
});
<!-- Load jQuery core library -->
<script type='text/javascript' src='http://code.jquery.com/jquery-2.1.4.min.js'></script>

<!-- Load jQueryUI library-->
<script type='text/javascript' src='http://code.jquery.com/ui/1.11.4/jquery-ui.js'></script>

<!-- Load jQueryUI Theme library (make either one effective) -->
<!--
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css'>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/ui-darkness/jquery-ui.css'>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/blitzer/jquery-ui.css'>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/eggplant/jquery-ui.css'>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/flick/jquery-ui.css'>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css'>
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/sunny/jquery-ui.css'>
-->
<link rel="stylesheet" type="text/css" href='http://code.jquery.com/ui/1.11.4/themes/redmond/jquery-ui.css'>



<h3>Plain (without styling/decoration):</h3>
<fieldset id='fieldset-selectiongrp-01'>
	<legend>Please <b>click</b> to <b>select</b> or <b>re-click</b> to <b>deselect</b> </legend>
	<span id='jQueryUi-selectiongrp-01'>
		<input type='radio' name='selectiongrp-01' value='Yes' id='selectiongrp-01-option-Y'/><label for='selectiongrp-01-option-Y'>Yes</label>
		<input type='radio' name='selectiongrp-01' value='No' id='selectiongrp-01-option-N'/><label for='selectiongrp-01-option-N'>No</label>
		<input type='radio' name='selectiongrp-01' value='Unknown' id='selectiongrp-01-option-U' /><label for='selectiongrp-01-option-U'>Unknown</label>
	</span>
</fieldset>
<fieldset id='fieldset-selectiongrp-01-result'>
	<legend>Result</legend>
	<span id='fieldset-selectiongrp-01-resultarea'></span>
</fieldset>

<br/>

<h3>Decorated by &quot;jQueryUI Theme&quot;:</h3>
<fieldset id='fieldset-selectiongrp-02'>
	<legend>Please <b>click</b> to <b>select</b> or <b>re-click</b> to <b>deselect</b> </legend>
	<span id='jQueryUi-selectiongrp-02'>
		<input type='radio' name='selectiongrp-02' value='Yes' id='selectiongrp-02-option-Y'/><label for='selectiongrp-02-option-Y'>Yes</label>
		<input type='radio' name='selectiongrp-02' value='No' id='selectiongrp-02-option-N'/><label for='selectiongrp-02-option-N'>No</label>
		<input type='radio' name='selectiongrp-02' value='Unknown' id='selectiongrp-02-option-U' /><label for='selectiongrp-02-option-U'>Unknown</label>
	</span>
</fieldset>
<fieldset id='fieldset-selectiongrp-02-result'>
	<legend>Result</legend>
	<span id='fieldset-selectiongrp-02-resultarea'></span>
</fieldset>
0 голосов
/ 30 марта 2015

Ответ Пабло прекрасно работает, если у вас есть только один из них на вашей странице. Я сталкивался с этим, когда пытался обойти загрузочную реализацию, которая доставляла мне некоторые проблемы, потому что переключатели были полностью перезаписаны, и оказалось, что будет проще использовать флажки в качестве переключателей.

Вот версия этого кода, которая допускает множественные множества, ссылаясь на второй класс вызывающего элемента.

$('input.unique').each(function() {
  $(this).on('touchstart click', function() {
    var secondClass = $(event.target).attr('class').split(' ')[1];
    $('input.' + secondClass).not(this).removeAttr('checked');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type='checkbox' name='mygroup1' value='1' class='unique check1'>
<input type='checkbox' name='mygroup2' value='2' class='unique check1'>
<input type='checkbox' name='mygroup3' value='3' class='unique check1'>
<br>
<hr>
<input type='checkbox' name='mygroup1' value='1' class='unique check2'>
<input type='checkbox' name='mygroup2' value='2' class='unique check2'>
<input type='checkbox' name='mygroup3' value='3' class='unique check2'>

JSFiddle

0 голосов
/ 24 февраля 2015

HTML

<input type='checkbox' name='mygroup1' value='1' class='unique'>
<input type='checkbox' name='mygroup2' value='2' class='unique'>
<input type='checkbox' name='mygroup3' value='3' class='unique'>

Javascript

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

Скрипка: http://jsfiddle.net/L2ad1vd8/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...