html встановити лише одну прапорець у групі


125

Тож як я можу дозволити користувачеві вибрати лише один прапорець?

Я знаю, що кнопки радіо «ідеальні», але для моєї мети ... це не так.

У мене є поле, де користувачі повинні вибрати один або два варіанти, але не обидва. Проблема полягає в тому, що мені потрібні мої користувачі, щоб вони також могли скасувати вибір, і саме тут перемикаються перемикачі, оскільки після вибору групи ви повинні вибрати варіант.

Я буду перевіряти інформацію через php, але я все-таки хотів би обмежити користувачів однією відповіддю, якщо вони хочуть її надати.


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

12
А як щодо додаткової радіо кнопки з написом "немає"?
FelipeAls

2
3-й варіант не відповідає моєму дизайну ... Хоча хороша альтернатива :)
user962449

2
Поставити прапорець з одним вибором - це насправді радіо-кнопка. Хіба це не здивує користувачів?
Герман

@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 (": встановлено") the "є", щоб перевірити, чи перевірявся прапорець у пункті
sergioadh

2
Зауважте, що .attr більше не працює, використовуйте .prop ("перевірено") замість нових версій jQuery
user871784

@ user871784 - Дякую за голову ... Я оновив скрипку!
bPratik

3
Ви пропустили радіоселектор: $ ("input: checkbox.radio")
Sven

@Sven - Це був би надмірно конкретний вибір у цьому прикладі. Сказавши, що якщо на сторінці міститься інший набір прапорців, у яких не повинно бути такої поведінки, то використання .radioселектора допоможе. Дякуємо, що
вказали

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
Це хороше рішення, але я скоріше дотримуюся прапорців, оскільки моя конструкція не ідеальна для 3-го варіанту.
користувач962449

6
Я настійно пропоную змінити дизайн. Позначити 0 або 1 з цих 2 варіантів не є загальною схемою і не буде настільки інтуїтивно зрозумілим для користувачів, як Tick ​​1 з цих 3 варіантів
Quentin

4
чому я б змінив весь дизайн на 2 прапорці?
користувач962449

9
Якщо така зміна вимагає від вас змінити "весь ваш дизайн", це говорить про те, що дизайн в першу чергу занадто негнучкий.
Квентін

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)">


Дякую, цей зробив це для мене з усіх тих інших =)
Кая

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

Це має працювати для будь-якої кількості прапорців у формі. Якщо у вас є інші, які не входять до групи, встановіть селекторам відповідні входи.


так, сер :) Це нормально, я знайшов щось, що працює для мене, хоча ваше рішення виглядає досить просто. Напевно, я зробив щось не так у своєму кінці. Спасибі все одно.
користувач962449

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

Моя версія: використовуйте атрибути даних та Vanilla 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

Некромантування:
І без 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.