html выберите только один флажок в группе


125

Итак, как я могу разрешить пользователю устанавливать только один флажок?

Я знаю, что радиокнопки "идеальны", но для моей цели ... это не так.

У меня есть поле, где пользователям нужно выбрать один или два варианта, но не оба. Проблема в том, что мне нужно, чтобы мои пользователи также могли отменить выбор своей опции, и здесь радио-кнопки не работают, потому что после выбора группы вы должны выбрать вариант.

Я буду проверять информацию через php, но я все равно хотел бы ограничить пользователей одним ответом, если они хотят его дать.


1
Только с HTML этого сделать нельзя. Вам понадобится JavaScript. Если вы открыты для jQuery, я могу предложить вам быстрое решение.
Surreal Dreams

12
А как насчет дополнительной радиокнопки с надписью "none"?
FelipeAls

2
третий вариант не подходит моему дизайну ... хорошая альтернатива :)
user962449

2
Флажок с единственным выбором на самом деле является переключателем. Не удивит ли это пользователей?
Gherman

@Surreal Dreams Это можно сделать в HTML, см. Мой ответ. Однако в большинстве случаев этот JS проще и не требует взлома.
SamGoody

Ответы:


179

Этот фрагмент будет:

  • Разрешить группировку по радио
  • Действовать как радио
  • Разрешить отменить выбор всех

// the selector will match all input controls of type :checkbox
// and attach a click event handler 
$("input:checkbox").on('click', function() {
  // in the handler, 'this' refers to the box clicked on
  var $box = $(this);
  if ($box.is(":checked")) {
    // the name of the box is retrieved using the .attr() method
    // as it is assumed and expected to be immutable
    var group = "input:checkbox[name='" + $box.attr("name") + "']";
    // the checked state of the group/box on the other hand will change
    // and the current value is retrieved using .prop() method
    $(group).prop("checked", false);
    $box.prop("checked", true);
  } else {
    $box.prop("checked", false);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


<div>
  <h3>Fruits</h3>
  <label>
    <input type="checkbox" class="radio" value="1" name="fooby[1][]" />Kiwi</label>
  <label>
    <input type="checkbox" class="radio" value="1" name="fooby[1][]" />Jackfruit</label>
  <label>
    <input type="checkbox" class="radio" value="1" name="fooby[1][]" />Mango</label>
</div>
<div>
  <h3>Animals</h3>
  <label>
    <input type="checkbox" class="radio" value="1" name="fooby[2][]" />Tiger</label>
  <label>
    <input type="checkbox" class="radio" value="1" name="fooby[2][]" />Sloth</label>
  <label>
    <input type="checkbox" class="radio" value="1" name="fooby[2][]" />Cheetah</label>
</div>


3
Правильным использованием будет использование $ (this) .is (": checked"), "is", чтобы проверить, установлен ли флажок в if {...} else {...} здесь ... jsfiddle .net / zGEaa / 31
sergioadh

2
Обратите внимание, что .attr больше не работает, используйте .prop ("проверено") вместо этого для новых версий jQuery
user871784

@ user871784 - Спасибо за предупреждение ... Я обновил скрипку!
bPratik

3
Вы пропустили селектор радио: $ ("input: checkbox.radio")
Свен

@Sven - в этом примере это был бы слишком специфичный селектор. При этом, если на странице есть другой набор флажков, которые не должны иметь такого поведения, то использование .radioселектора может помочь. Спасибо, что указали на это :)
bPratik

101

Вам нужно привязать change()обработчик, чтобы событие запускалось при изменении состояния флажка. Затем просто снимите все флажки, кроме того, который запускал обработчик:

$('input[type="checkbox"]').on('change', function() {
   $('input[type="checkbox"]').not(this).prop('checked', false);
});

Вот скрипка


Что касается группировки, если ваш флажок «группы» были братьями и сестрами:

<div>
    <input type="checkbox" />
    <input type="checkbox" />
    <input type="checkbox" />
</div>  
<div>
    <input type="checkbox" />
    <input type="checkbox" />
    <input type="checkbox" />
</div>   
<div>
    <input type="checkbox" />
    <input type="checkbox" />
    <input type="checkbox" />
</div>

Вы могли сделать это:

$('input[type="checkbox"]').on('change', function() {
   $(this).siblings('input[type="checkbox"]').prop('checked', false);
});

Вот еще одна скрипка


Если ваши флажки сгруппированы по другому атрибуту, например name:

<input type="checkbox" name="group1[]" />
<input type="checkbox" name="group1[]" />
<input type="checkbox" name="group1[]" />

<input type="checkbox" name="group2[]" />
<input type="checkbox" name="group2[]" />
<input type="checkbox" name="group2[]" />

<input type="checkbox" name="group3[]" />
<input type="checkbox" name="group3[]" />
<input type="checkbox" name="group3[]" />

Вы могли сделать это:

$('input[type="checkbox"]').on('change', function() {
    $('input[name="' + this.name + '"]').not(this).prop('checked', false);
});

Вот еще одна скрипка


Мне нравится твой (последний) код. Очень коротко и ясно. Я не был уверен, сработает ли «изменение», когда вы измените другие флажки, но этого не произошло, когда я попробовал. Так что я предпочитаю ваш код. Спасибо! :)
Фрэнк Фахардо

Мне это очень нравится, мне нужно сделать небольшую настройку для моих нужд. У меня есть два элемента, поэтому по умолчанию проверяется первый элемент, а если он не установлен, второй элемент становится отмеченным. Это помогло мне начать работу.
john.weland

Привет @ john.weland - Вы имеете в виду что - то вроде этого ?
billyonecan

@billyonecan почти точно, но с возможностью нацеливания на заданную группу. вот так . Спасибо
john.weland

2
плюс один для простоты
Чад

26

Радиокнопки идеальны. Вам просто нужен третий вариант «ни один», который выбран по умолчанию.


1
Это хорошее решение, но я предпочитаю использовать флажки, потому что мой дизайн не идеален для третьего варианта.
user962449

6
Я настоятельно рекомендую изменить дизайн. Отметка 0 или 1 из этих двух вариантов не является распространенным шаблоном и не будет столь же интуитивно понятной для пользователей, как отметка 1 из этих трех вариантов
Квентин,

4
зачем мне менять весь свой дизайн на 2 флажка?
user962449

9
Если такое изменение потребует от вас изменения «всего вашего дизайна», это говорит о том, что дизайн изначально слишком негибкий.
Quentin

10
Он не негибкий, он просто выглядит некорректно ... Он может хорошо смотреться в формах и подобных приложениях, но у нас есть другое использование для наших флажков.
user962449

13

На этот вопрос уже есть несколько ответов, основанных на чистом JS, но ни один из них не является столь кратким, как мне хотелось бы.

Вот мое решение, основанное на использовании тегов имен (например, с переключателями) и нескольких строк javascript.

function onlyOne(checkbox) {
    var checkboxes = document.getElementsByName('check')
    checkboxes.forEach((item) => {
        if (item !== checkbox) item.checked = false
    })
}
<input type="checkbox" name="check" onclick="onlyOne(this)">
<input type="checkbox" name="check" onclick="onlyOne(this)">
<input type="checkbox" name="check" onclick="onlyOne(this)">
<input type="checkbox" name="check" onclick="onlyOne(this)">


Спасибо, этот сделал это за меня от всех остальных =)
kaya

6
$("#myform input:checkbox").change(function() {
    $("#myform input:checkbox").attr("checked", false);
    $(this).attr("checked", true);
});

Это должно работать для любого количества флажков в форме. Если у вас есть другие, которые не являются частью группы, настройте селекторы для соответствующих входов.


да, сэр :) Ничего страшного, я нашел кое-что, что мне подходит, хотя ваше решение выглядит довольно простым. Я, наверное, со своей стороны что-то сделал не так. В любом случае спасибо.
user962449

5

Вот простое решение HTML и JavaScript, которое я предпочитаю:

// js-функция, позволяющая проверять только один будний день за раз:

function checkOnlyOne(b){

var x = document.getElementsByClassName('daychecks');
var i;

for (i = 0; i < x.length; i++) {
  if(x[i].value != b) x[i].checked = false;
}
}


Day of the week:
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Monday" />Mon&nbsp;&nbsp;&nbsp;
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Tuesday" />Tue&nbsp;&nbsp;&nbsp;
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Wednesday" />Wed&nbsp;&nbsp;&nbsp;
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Thursday" />Thu&nbsp;&nbsp;&nbsp;
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Friday" />Fri&nbsp;&nbsp;&nbsp;
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Saturday" />Sat&nbsp;&nbsp;&nbsp;
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Sunday" />Sun&nbsp;&nbsp;&nbsp;<br /><br />

4

Пусть этот код вам поможет.

$(document).ready(function(){
$('.slectOne').on('change', function() {
   $('.slectOne').not(this).prop('checked', false);
   $('#result').html($(this).data( "id" ));
   if($(this).is(":checked"))
   	$('#result').html($(this).data( "id" ));
   else
   	$('#result').html('Empty...!');
});
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

</head>
<body>
<input type="checkbox" class="slectOne" data-id="1 selected"/>
<input type="checkbox" class="slectOne" data-id="2 selected"/>
<input type="checkbox" class="slectOne" data-id="3 selected"/>
<input type="checkbox" class="slectOne" data-id="4 selected"/>
<input type="checkbox" class="slectOne" data-id="5 selected"/>
<input type="checkbox" class="slectOne" data-id="6 selected"/>
<input type="checkbox" class="slectOne" data-id="7 selected"/>
<input type="checkbox" class="slectOne" data-id="8 selected"/>
<input type="checkbox" class="slectOne" data-id="9 selected"/>
<input type="checkbox" class="slectOne" data-id="10 selected"/>
<span id="result"></span>
</body>
</html>

Рабочая ссылка Нажмите здесь


3

Основываясь на ответе billyonecan , вы можете использовать следующий код, если вам нужен этот фрагмент для нескольких флажков (при условии, что они имеют разные имена).

    $('input.one').on('change', function() {
        var name = $(this).attr('name');
        $('input[name='+name+'].one').not(this).prop('checked', false);
    }); 

3

Хотя, вероятно, лучше всего использовать JS, это можно сделать только с помощью HTML и CSS.

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

<style>
   #uncheck>input { display: none }
   input:checked + label { display: none }
   input:not(:checked) + label + label{ display: none } 
</style>

<div id='uncheck'>
  <input type="radio" name='food' id="box1" /> 
  Pizza 
    <label for='box1'>&#9678;</label> 
    <label for='box0'>&#9673;</label>
  <input type="radio" name='food' id="box2" /> 
  Ice cream 
    <label for='box2'>&#9678;</label> 
    <label for='box0'>&#9673;</label>
  <input type="radio" name='food' id="box0" checked />
</div>

Смотрите здесь: https://jsfiddle.net/tn70yxL8/2/

Предполагается, что вам нужны невыбираемые метки.

Если вы хотели включить метки, вы можете технически избежать повторения метки «снять отметку», изменив ее текст в CSS, см. Здесь: https://jsfiddle.net/7tdb6quy/2/


1

Пример с AngularJs

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>

<head>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script>
    angular.module('app', []).controller('appc', ['$scope',
      function($scope) {
        $scope.selected = 'other';
      }
    ]);
  </script>
</head>

<body ng-app="app" ng-controller="appc">
  <label>SELECTED: {{selected}}</label>
  <div>
    <input type="checkbox" ng-checked="selected=='male'" ng-true-value="'male'" ng-model="selected">Male
    <br>
    <input type="checkbox" ng-checked="selected=='female'" ng-true-value="'female'" ng-model="selected">Female
    <br>
    <input type="checkbox" ng-checked="selected=='other'" ng-true-value="'other'" ng-model="selected">Other
  </div>



</body>

</html>


1

С простым старым javascript.

<html>
<head>
</head>
<body>
<input type="checkbox" name="group1[]" id="groupname1" onClick="toggle(1,'groupname')"/>
<input type="checkbox" name="group1[]" id="groupname2" onClick="toggle(2,'groupname')"  />
<input type="checkbox" name="group1[]" id="groupname3" onClick="toggle(3,'groupname')" />

<input type="checkbox" name="group2[]" id="diffGroupname1" onClick="toggle(1,'diffGroupname')"/>
<input type="checkbox" name="group2[]" id="diffGroupname2" onClick="toggle(2,'diffGroupname')"  />
<input type="checkbox" name="group2[]" id="diffGroupname3" onClick="toggle(3,'diffGroupname')" />
<script>
function toggle(which,group){
var counter=1;
var checkbox=document.getElementById(group+counter);
while(checkbox){
if(counter==which){

}else{
checkbox.checked=false;
}
counter++;
checkbox=document.getElementById(group+counter);
}
}
</script>
</body>
</html>

изменить: также возможно

<html>
<head>
</head>
<body>
<input type="checkbox" name="group1[]" class="groupname" onClick="toggle(this,'groupname')"/>
<input type="checkbox" name="group1[]" class="groupname" onClick="toggle(this,'groupname')"  />
<input type="checkbox" name="group1[]" class="groupname" onClick="toggle(this,'groupname')" />

<input type="checkbox" name="group2[]" class="diffGroupname" onClick="toggle(this,'diffGroupname')"/>
<input type="checkbox" name="group2[]" class="diffGroupname" onClick="toggle(this,'diffGroupname')"  />
<input type="checkbox" name="group2[]" class="diffGroupname" onClick="toggle(this,'diffGroupname')" />
<script>
function toggle(which,theClass){
var checkbox=document.getElementsByClassName(theClass);
for(var i=0;i<checkbox.length;i++){
if(checkbox[i]==which){

}else{
checkbox[i].checked=false;
}
}
}
</script>
</body>
</html>

0

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>

<head>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script>
    angular.module('app', []).controller('appc', ['$scope',
      function($scope) {
        $scope.selected = 'male';
      }
    ]);
  </script>
</head>

<body ng-app="app" ng-controller="appc">
  <label>SELECTED: {{selected}}</label>
  <div>
    <input type="checkbox" ng-checked="selected=='male'" ng-true-value="'male'" ng-model="selected">Male
    <br>
    <input type="checkbox" ng-checked="selected=='female'" ng-true-value="'female'" ng-model="selected">Female
    <br>
    <input type="checkbox" ng-checked="selected=='other'" ng-true-value="'other'" ng-model="selected">Other
  </div>
</body>
</html>


0

Если кому-то нужно решение без внешних библиотек javascript, вы можете использовать этот пример. Группа флажков, позволяющая принимать значения 0..1. Вы можете нажать на компонент флажка или связанный текст метки.

    <input id="mygroup1" name="mygroup" type="checkbox" value="1" onclick="toggleRadioCheckbox(this)" /> <label for="mygroup1">Yes</label>
    <input id="mygroup0" name="mygroup" type="checkbox" value="0" onclick="toggleRadioCheckbox(this)" /> <label for="mygroup0">No</label>

- - - - - - - - 

    function toggleRadioCheckbox(sender) {
        // RadioCheckbox: 0..1 enabled in a group 
        if (!sender.checked) return;
        var fields = document.getElementsByName(sender.name);
        for(var idx=0; idx<fields.length; idx++) {
            var field = fields[idx];
            if (field.checked && field!=sender)
                field.checked=false;
        }
    }

0

Моя версия: использовать атрибуты данных и ванильный JavaScript

<div class="test-checkbox">
    Group One: <label>
        <input type="checkbox" data-limit="only-one-in-a-group" name="groupOne" value="Eat" />Eat</label>
    <label>
        <input type="checkbox" data-limit="only-one-in-a-group" name="groupOne" value="Sleep" />Sleep</label>
    <label>
        <input type="checkbox" data-limit="only-one-in-a-group" name="groupOne" value="Play" />Play</label>
    <br />
    Group Two: <label>
        <input type="checkbox" data-limit="only-one-in-a-group" name="groupTwo" value="Fat" />Fat</label>
    <label>
        <input type="checkbox" data-limit="only-one-in-a-group" name="groupTwo" value="Comfort" />Comfort</label>
    <label>
        <input type="checkbox" data-limit="only-one-in-a-group" name="groupTwo" value="Happy" />Happy</label>
</div>
<script>
    let cbxes = document.querySelectorAll('input[type="checkbox"][data-limit="only-one-in-a-group"]');
    [...cbxes].forEach((cbx) => {
        cbx.addEventListener('change', (e) => {
            if (e.target.checked)
                uncheckOthers(e.target);
        });
    });
    function uncheckOthers (clicked) {
        let name = clicked.getAttribute('name');
        // find others in same group, uncheck them
        [...cbxes].forEach((other) => {
            if (other != clicked && other.getAttribute('name') == name)
                other.checked = false;
        });
    }
</script>

-1

Necromancing:
И без jQuery, для такой структуры флажков:

<label>
<input type="checkbox" id="mytrackers_1" name="blubb_1" value="">--- Bitte ausw&#228;hlen ---
</label>
<label>
<input type="checkbox" id="mytrackers_2" name="blubb_2" value="7">Testtracker
</label>
<label>
<input type="checkbox" id="mytrackers_3" name="blubb_3" value="3">Kundenanfrage
</label>
<label>
<input type="checkbox" id="mytrackers_4" name="blubb_4" value="2">Anpassung
</label>
<label>
<input type="checkbox" id="mytrackers_5" name="blubb_5" value="1" checked="checked" >Fehler
</label>
<label>
<input type="checkbox" id="mytrackers_6" name="blubb_6" value="4">Bedienung
</label>
<label>
<input type="checkbox" id="mytrackers_7" name="blubb_7" value="5">Internes
</label>
<label>
<input type="checkbox" id="mytrackers_8" name="blubb_8" value="6">&#196;nderungswunsch
</label>

вы бы сделали это так:

    /// attach an event handler, now or in the future, 
    /// for all elements which match childselector,
    /// within the child tree of the element maching parentSelector.
    function subscribeEvent(parentSelector, eventName, childSelector, eventCallback) {
        if (parentSelector == null)
            throw new ReferenceError("Parameter parentSelector is NULL");
        if (childSelector == null)
            throw new ReferenceError("Parameter childSelector is NULL");
        // nodeToObserve: the node that will be observed for mutations
        var nodeToObserve = parentSelector;
        if (typeof (parentSelector) === 'string')
            nodeToObserve = document.querySelector(parentSelector);
        var eligibleChildren = nodeToObserve.querySelectorAll(childSelector);
        for (var i = 0; i < eligibleChildren.length; ++i) {
            eligibleChildren[i].addEventListener(eventName, eventCallback, false);
        } // Next i 
        // /programming/2712136/how-do-i-make-this-loop-all-children-recursively
        function allDescendants(node) {
            if (node == null)
                return;
            for (var i = 0; i < node.childNodes.length; i++) {
                var child = node.childNodes[i];
                allDescendants(child);
            } // Next i 
            // IE 11 Polyfill 
            if (!Element.prototype.matches)
                Element.prototype.matches = Element.prototype.msMatchesSelector;
            if (node.matches) {
                if (node.matches(childSelector)) {
                    // console.log("match");
                    node.addEventListener(eventName, eventCallback, false);
                } // End if ((<Element>node).matches(childSelector))
                // else console.log("no match");
            } // End if ((<Element>node).matches) 
            // else console.log("no matchfunction");
        } // End Function allDescendants 
        // Callback function to execute when mutations are observed
        var callback = function (mutationsList, observer) {
            for (var _i = 0, mutationsList_1 = mutationsList; _i < mutationsList_1.length; _i++) {
                var mutation = mutationsList_1[_i];
                // console.log("mutation.type", mutation.type);
                // console.log("mutation", mutation);
                if (mutation.type == 'childList') {
                    for (var i = 0; i < mutation.addedNodes.length; ++i) {
                        var thisNode = mutation.addedNodes[i];
                        allDescendants(thisNode);
                    } // Next i 
                } // End if (mutation.type == 'childList') 
                // else if (mutation.type == 'attributes') { console.log('The ' + mutation.attributeName + ' attribute was modified.');
            } // Next mutation 
        }; // End Function callback 
        // Options for the observer (which mutations to observe)
        var config = { attributes: false, childList: true, subtree: true };
        // Create an observer instance linked to the callback function
        var observer = new MutationObserver(callback);
        // Start observing the target node for configured mutations
        observer.observe(nodeToObserve, config);
    } // End Function subscribeEvent 


    function radioCheckbox_onClick() 
    { 
        // console.log("click", this);
        let box = this;
        if (box.checked) 
        {
            let name = box.getAttribute("name");
            let pos = name.lastIndexOf("_");
            if (pos !== -1) name = name.substr(0, pos);

            let group = 'input[type="checkbox"][name^="' + name + '"]';
            // console.log(group);
            let eles = document.querySelectorAll(group);
            // console.log(eles);
            for (let j = 0; j < eles.length; ++j) 
            {
                eles[j].checked = false;
            }
            box.checked = true;
        }
        else
            box.checked = false;
    }


    // /programming/9709209/html-select-only-one-checkbox-in-a-group
    function radioCheckbox()
    { 
        // on instead of document...
        let elements = document.querySelectorAll('input[type="checkbox"]')

        for (let i = 0; i < elements.length; ++i)
        {
            // console.log(elements[i]);
            elements[i].addEventListener("click", radioCheckbox_onClick, false);

        } // Next i 

    } // End Function radioCheckbox 


    function onDomReady()
    {
        console.log("dom ready");
        subscribeEvent(document, "click", 
            'input[type="checkbox"]', 
            radioCheckbox_onClick
        ); 

        // radioCheckbox();
    }

    if (document.addEventListener) document.addEventListener("DOMContentLoaded", onDomReady, false);
    else if (document.attachEvent) document.attachEvent("onreadystatechange", onDomReady);
    else window.onload = onDomReady;

    function onPageLoaded() {
        console.log("page loaded");
    }

    if (window.addEventListener) window.addEventListener("load", onPageLoaded, false);
    else if (window.attachEvent) window.attachEvent("onload", onPageLoaded);
    else window.onload = onPageLoaded;

-1
//Here is a solution using JQuery    
<input type = "checkbox" class="a"/>one
    <input type = "checkbox" class="a"/>two
    <input type = "checkbox" class="a"/>three
    <script>
       $('.a').on('change', function() {
            $('.a').not(this).prop('checked',false);
    });
    </script>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.