Home > Software engineering >  How to disable a radio button if the other one is selected?
How to disable a radio button if the other one is selected?

Time:10-15

I'm trying to disable a radio button if the other one is selected.

Next to the radio input is a text input in which if they choose the option, they would write the age depending on the selection of the radio (months or years).

Ideally, the text input would be disabled too. I have this code right now but it's not working:

<div >
    <i ></i><label data-error="wrong" data-success="right" style="padding-left: 5px">Age: </label>
    <br />
    <input type="radio"  id="age_in_years" name="age_in_years" value="years">
    <label for="age_in_years">Años:</label><input id="age_in_years"type="number" name="age_in_years" ng-model="age_in_years"  style="margin-left: 5px;width: 70px;"/>
    <input type="radio"  id="age_in_months" name="age_in_months" value="months">
    <label for="age_in_months">Months:</label><input id="age_in_months" type="number" name="age_in_months" value="age_in_months" ng-model="age_in_months"  style="margin-left: 5px;width:70px;"/>
</div>


<script>
    function selection() {
        let x = document.getElementById("age_in_years");
        let y = document.getElementById("age_in_months");

        if (x.checked()) {
            document.getElementById("age_in_months").disabled = true;
        }
        else if (y.checked()) {
            document.getElementById("age_in_years").disabled = true;
        }
    }
</script>

CodePudding user response:

I would refactor the HTML slightly and generate the radio buttons with the same name so that only 1 can ever be checked at a time. With that in place some simple javascript to determine the other inputs can be used to disable the number input.

label elements should not be used for arbitrary HTML - they are to be associated with input elements ( either using for=ID syntax or by wrapping the input element itself ) - hence some alterations to the markup.

document.addEventListener('change',e=>{
  if( e.target.name=='age_unit' ){
    let parent=e.target.parentNode;
    
    let self=parent.querySelector(`input[type='number'][name='age[${e.target.value}]']`);
    let other=parent.querySelector(`input[type='number']:not( [name='age[${e.target.value}]'] )`);
    
    self.disabled=false;
    other.disabled=true;
    
    self.required=true;
    other.required=false;
    
    self.focus();
  }
})
[type='number']{
  width:70px;
}
<div >
  <i ></i>
  <h2>Age:</h2>


  <input type="radio" name="age_unit" value="years" />
  <label>Años:
   <input type="number" name="age[years]" ng-model="age_in_years"  disabled />
  </label>



  <input type="radio" name="age_unit" value="months" />
  <label>Months:
    <input type="number" name="age[months]" ng-model="age_in_months"  disabled />
  </label>


</div>

CodePudding user response:

A radio type is grouped by the name, so using the same name would already give the behavior you want, without needing any JavaScript.

<div >
  <i ></i>
  <label data-error="wrong" data-success="right" style="padding-left: 5px">Age: </label>
  <br>
  <input type="radio" id="age_in_years" name="age" value="years">
  <label for="age_in_years">Años:</label><input id="age_in_years"type="number" name="age_in_years" ng-model="age_in_years"  style="margin-left: 5px;width: 70px;"/>
  <input type="radio"  id="age_in_months" name="age" value="months">
  <label for="age_in_months">Months:</label>
  <input id="age_in_months" type="number" name="age_in_months" value="age_in_months" ng-model="age_in_months"  style="margin-left: 5px;width:70px;"/>
</div>

This would make sure that if one of radio elements is clicked or, once another one is clicked, the previous would be unchecked.

Because you have a value there, there's no reason to use different names, because the value already hints what kind of data has been submitted or is required.

  • Related