How to check/uncheck radio button on click?

后端 未结 18 1282
情深已故
情深已故 2020-11-29 02:16

I want to be able to uncheck a radio button by clicking on it.

So, if a radio button is unchecked, I want to check it, if it is checked, I want to uncheck it.

<
相关标签:
18条回答
  • 2020-11-29 02:16

    try this:

    $('input[type=radio]').click(function(){
        if (this.previous) {
            this.checked = false;
        }
        this.previous = this.checked;
    });
    
    0 讨论(0)
  • 2020-11-29 02:16

    Here's a super lightweight script you can add to a page through the console window that allows you to deselect a radio button by holding down Ctrl while clicking it with the mouse.

    document.addEventListener('click', function(e){
       if (e.ctrlKey == true && 
           e.target.tagName == 'INPUT' && 
           e.target.type == "radio" && 
           e.target.checked == true) {
           e.target.checked = false;
       }
    });
    

    Since it doesn't rely on jQuery, you can easily add it to any page to temporarily allow deselection.
    For slightly more info, you can read an article I just wrote on How To Deselect A Radio Button.

    0 讨论(0)
  • 2020-11-29 02:17

    As HexInteractive mentioned, radio button is handled outside the normal event chain. So, following example judges the button state by class name, not by property.

    var $self;
    
    $('input[type=radio]').on('click', function() {
      $self = $(this);
      if ( $self.hasClass('is-checked') ) {
        $self.prop('checked', false).removeClass('is-checked');
      } else {
        $self.addClass('is-checked');
      }
    });
    
    0 讨论(0)
  • 2020-11-29 02:23

    It is better UX to have a default-selected "Select none" explicit option, and not let the user uncheck any radio button.

    (List item 9 in this nngroup (neilsen) article:

    http://www.nngroup.com/articles/checkboxes-vs-radio-buttons/

    0 讨论(0)
  • 2020-11-29 02:24

    I must be missing it but after all these years AFAIK none of the solutions above seem to work or maybe I'm just dumb.

    There is absolutely no reason to use a radio button unless there is more than one radio button in the same group. If it's a lone radio button then just use a checkbox. The reason to use a radio button is for selecting one of mutually exclusive options. That means any solution which only looks at individual buttons will fail since clicking a one button will effect the state of the other buttons

    In other words since we're using radioboxes the solution needs to work for

    <input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
    <input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
    <input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>
    

    Here's one that looks at all the buttons.

    This seems to work

    document.querySelectorAll(
        'input[type=radio][name=foo]').forEach((elem) => {
      elem.addEventListener('click', allowUncheck);
      // only needed if elem can be pre-checked
      elem.previous = elem.checked;
    });
    
    function allowUncheck(e) {
      if (this.previous) {
        this.checked = false;
      }
      // need to update previous on all elements of this group
      // (either that or store the id of the checked element)
      document.querySelectorAll(
          `input[type=radio][name=${this.name}]`).forEach((elem) => {
        elem.previous = elem.checked;
      });
    }
    body { font-size: xx-large; }
    label, input {
      /* added because a second click to unselect radio often
         appears as a double click to select text */
      -webkit-user-select: none;
      user-select: none;
    }
    <input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
    <input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
    <input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>

    note if elem.previous worries you you could use elem.dataset.previous

    Another solution would be to store which button is checked

    function makeRadioboxGroupUnCheckable(groupSelector) {
    
      let currentId;
    
      document.querySelectorAll(groupSelector).forEach((elem) => {
        elem.addEventListener('click', allowUncheck);
        // only needed if can be pre-checked
        if (elem.checked) {
          currentId = elem.id;
        }
      });
    
      function allowUncheck(e) {
        if (this.id === currentId) {
          this.checked = false;
          currentId = undefined;
        } else {
          currentId = this.id;
        }
      }
    }
    
    makeRadioboxGroupUnCheckable('input[type=radio][name=foo]');
    body { font-size: xx-large; }
    label, input {
      /* added because a second click to unselect radio often
         appears as a double click to select text */
      -webkit-user-select: none;
      user-select: none;
    }
    <input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
    <input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
    <input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>

    0 讨论(0)
  • 2020-11-29 02:24

    Based on answer by Stephen - this deals with multiple radio button groups and also you mostly don't need to double click radio buttons. It isn't perfect as if you switch between groups the check for id will necessitate an extra click but works ok.

    $("input[type='radio']").on('click', function (e) {
                if (this.previous && this.value == previousvalue && this.id == previousid) {
                    this.checked = false;
                }
                this.previous = this.checked;
                previousvalue = this.value;
                previousid = this.id;
    
            });
    
    0 讨论(0)
提交回复
热议问题