1

I have a form with many text-input-fields and checkboxes. Whenever a checkbox is checked, all text-input fields and all other checkboxes (exept the one that was checked) should be disabled. After unchecking this checkbox, all disabled fields should be enabled again. This works with the following code (shown are only the first 3 lines):

<form id="myForm">

    Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" onclick="enableDisableAll();" />
    <input type="text" id="id1" name="name1" /><br>

    Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" onclick="enableDisableAll();" />
    <input type="text" id="id2" name="name2" /><br>

    Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" onclick="enableDisableAll();" />
    <input type="text" id="id3" name="name3" /><br>

</form>


function enableDisableAll() {

    cb1 = document.getElementById('checkboxOne').checked;
    cb2 = document.getElementById('checkboxTwo').checked;
    cb3 = document.getElementById('checkboxThree').checked;


    document.getElementById('checkboxOne').disabled = (cb2 || cb3);
    document.getElementById('id1').disabled = (cb1 || cb2 || cb3);

    document.getElementById('checkboxTwo').disabled = (cb1 || cb3);
    document.getElementById('id2').disabled = (cb1 || cb2 || cb3);

    document.getElementById('checkboxThree').disabled = (cb1 || cb2);
    document.getElementById('id3').disabled = (cb1 || cb2 || cb3);

}

Since the code becomes confusing with many checkboxes (cb1 || cb2 || cb3 || ....... cb(n)), I wonder if there would be a more elegant possibility to do this, e.g.:

function enableDisableAll() {

cb1 = document.getElementById('checkboxOne').checked;
cb2 = document.getElementById('checkboxTwo').checked;
cb3 = document.getElementById('checkboxThree').checked;

var cb_array = [];

cb_array.push("cb1");
cb_array.push("cb2");

var cb_array_imploded = cb_array.join(" || ");

document.getElementById('id1').disabled = (cb_array_imploded);

Unfortunately, this does not work.

Does anyone have a simple solution for my problem?

3 Answers 3

1

select all the form elements and loop through and check for id same as clicked element id.if so don't disabled it.

function enableDisableAll(e) {
        var own = e;
        var form = document.getElementById("myForm");
        var elements = form.elements;

    for (var i = 0 ; i < elements.length ; i++) {
          if(own !== elements[i] ){
          
            if(own.checked == true){
              
              elements[i].disabled = true;  
             
            }else{
            
              elements[i].disabled = false;  
            }
          
           }

     }
    
}

function clearAll(){
 document.getElementById("myForm").reset();
}
<form id="myForm">

    Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" onclick="enableDisableAll(this);" />
    <input type="text" id="id1" name="name1" /><br>

    Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" onclick="enableDisableAll(this);" />
    <input type="text" id="id2" name="name2" /><br>

    Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" onclick="enableDisableAll(this);" />
    <input type="text" id="id3" name="name3" /><br>
 
   

</form>

<input class="field button2" type="button" value="Clear form" size="10" onclick="clearAll(this);">

Update : To clear all the form fields

document.getElementById("myForm").reset();
Sign up to request clarification or add additional context in comments.

9 Comments

Dinesh, the disabling works perfect, but there is no enabling when the respective checkbox is unchecked again
@Dinesh, your solution would not work if the elements had no ID attribute
@Dinesh Since your answer is the accepted one please do update it so that it doesn't rely on IDs. You can directly compare element references: own !== elemets[i]
Dinesh, one final question: with your code, it should be possible to clear all elements of a form, too. I tried it with document.myForm.elements[i].value = ""; instead of elements[i].disabled = true; but it didn´t work.
@Columbus updated my answer for you requirement. check now. is that you wanted?
|
1

One possible approach is the following; though note that I amended your HTML, wrapping the <input type="checkbox"> elements in a parent <label> element, and removing the unnecessary <br /> elements along with the obtrusive in-line event-handlers in the HTML:

// a named function bound to an element via
// via JavaScript; the 'event' argument
// is passed automatically from the
// EventTarget.addEventListener() method:
function disableIfChecked(event) {

  // the event.target node is the node upon which
  // the listened-for event was originally triggered:
  let target = event.target;

  // 'this' is also passed from the
  // EventTarget.addEventListener() method; here
  // retrieved all <input> elements within the
  // <form> (the 'this'), convert that NodeList
  // explicitly to an Array and then filter that
  // Array using an Arrow function:
  Array.from(this.querySelectorAll('input')).filter(

    // we retain only those elements ('el') in the Array
    // which are not equal to, and therefore are not, the
    // changed element:
    el => el !== target

    // iterating over the filtered collection:
  ).forEach(

    // each <input> element remaining in the collection
    // will be disabled if the changed element is clicked,
    // or enabled if the changed element is no longer clicked:
    el => el.disabled = target.checked
  );
}

document.querySelector('#myForm').addEventListener('change', disableIfChecked);
/* Selecting the <label> element that follows
   an <input> element: */

input+label::before {
  /* Adding a line-feed character using the CSS
     'content' property of the pseudo-element
     to force each <label> to a new-line: */
  content: '\A';
  display: block;
}
<form id="myForm">

  <!-- the label element associates the text with the enclosed
       input, so clicking the text focuses that input element: -->
  <label>Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" /></label>
  <input type="text" id="id1" name="name1" />

  <label>Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" /></label>
  <input type="text" id="id2" name="name3" />

  <label>Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" /></label>
  <input type="text" id="id3" name="name3" />

</form>

JS Fiddles: commented, uncommented

In order to support browsers without support for ES6, the following is an alternative approach doing the same thing:

// a named function bound to an element via
// via JavaScript; the 'event' argument
// is passed automatically from the
// EventTarget.addEventListener() method:
function disableIfChecked(event) {

  // the event.target node is the node upon which
  // the listened-for event was originally triggered:
  let target = event.target;

  // 'this' is also passed from the
  // EventTarget.addEventListener() method; here
  // retrieved all <input> elements within the
  // <form> (the 'this'), convert that NodeList
  // explicitly to an Array by treating the NodeList
  // as an Array, using Function.prototype.call(),
  // and Array.prototype.slice():
  Array.prototype.slice.call(
    this.querySelectorAll('input')
  ).filter(function(el) {

    // we retain only those elements ('el') in the Array
    // which are not equal to, and therefore are not, the
    // changed element:
    return el !== target;

    // iterating over the filtered collection:
  }).forEach(function(el) {

    // each <input> element remaining in the collection
    // will be disabled if the changed element is clicked,
    // or enabled if the changed element is no longer clicked:
    el.disabled = target.checked;
  });
}

document.querySelector('#myForm').addEventListener('change', disableIfChecked);
/* Selecting the <label> element that follows
   an <input> element: */

input+label::before {
  /* Adding a line-feed character using the CSS
     'content' property of the pseudo-element
     to force each <label> to a new-line: */
  content: '\A';
  display: block;
}
<form id="myForm">

  <!-- the label element associates the text with the enclosed
       input, so clicking the text focuses that input element: -->
  <label>Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" /></label>
  <input type="text" id="id1" name="name1" />

  <label>Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" /></label>
  <input type="text" id="id2" name="name3" />

  <label>Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" /></label>
  <input type="text" id="id3" name="name3" />

</form>

JS Fiddles.

References:

5 Comments

Thanks David Thomas, for your suggesttion, but unfortunately, this does not work
It does for me, in Chrome, Opera, Firefox and Edge, both in the posted Snippet and in the external JS Fiddle demos; in your own use what happens instead? Are there any errors?
When I run the code snippet, I get the following error: Error: { "message": "Syntaxfehler", "filename": "stacksnippets.net/js", "lineno": 56, "colno": 9 }
What browser are you using Columbus, looks like it doesnt have support for ES6
Are you using Internet Explorer by any chance? I've just tried it with IE and, predictably, that fails; I'll post an updated backwards-compatible version momentarily.
0

It's usually best to use onchange instead of onclick event on inputs such as checkboxes, radiobuttons, or selects.

In order to make a general solution for as many inputs as you need, it's best to use document.querySelectorAll to fetch all inputs within the form. You can then iterate over all inputs and set their disabled property to the checked value of the targeted checkbox.

Solution snippet below:

function enableDisableAll(event) {
  var allInputs = document.querySelectorAll('#myForm input');

  allInputs.forEach(function(input) {
    if (input !== event.target) {
      input.disabled = event.target.checked;
    }
  });
}
<form id="myForm">

  Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" onchange="enableDisableAll(event);" />
  <input type="text" id="id1" name="name1" /><br> Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" onchange="enableDisableAll(event);" />
  <input type="text" id="id2" name="name2" /><br> Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" onchange="enableDisableAll(event);" />
  <input type="text" id="id3" name="name3" /><br>

</form>

An important detail here is that if you want to assign a typical event handler function directly to an HTML attribute, the function must have a single parameter explicitly named event. It is however recommended to assign event handlers in javascript and not in HTML. The syntax for that would be myCheckbox.addEventListener('change', enableDisableAll); You may want to add listeners to every checkbox, by iterating over a selector of all checkboxes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.