Home > Back-end >  How to disable my button based on dynamically generated radio buttons
How to disable my button based on dynamically generated radio buttons

Time:12-31

As you can see my radio button ids are dynamic. I want to disable input type file button if my value value="0" or value="2" radio buttons without affecting other section.

/*First Section*/
<input type="file" name="files" multiple="multiple" id="Button_select_1" />
<div >
    <div >
        <label>
            <input data-val="true" data-val-required="Kindly submit your response" id="10_3" name="AnswerResponse" type="radio" value="1" />
            <label>Yes</label>
        </label>
    </div>
</div>
<div >
    <div >
        <label>
            <input checked="checked" id="10_4" name="AnswerResponse" type="radio" value="0" />
            <label>No</label>
        </label>
    </div>
</div>
<div >
    <div >
        <label>
            <input id="10_5" name="AnswerResponse" type="radio" value="2" />
            <label>N/A</label>
        </label>
    </div>
</div>
/*Second Section*/
<input type="file" name="files" multiple="multiple" id="Button_select_1" />
<div >
    <div >
        <label>
            <input data-val="true" data-val-required="Kindly submit your response" id="11_3" name="AnswerResponse" type="radio" value="1" />
            <label>Yes</label>
        </label>
    </div>
</div>
<div >
    <div >
        <label>
            <input checked="checked" id="11_4" name="AnswerResponse" type="radio" value="0" />
            <label>No</label>
        </label>
    </div>
</div>
<div >
    <div >
        <label>
            <input id="11_5" name="AnswerResponse" type="radio" value="2" />
            <label>N/A</label>
        </label>
    </div>
</div>
 /*Third Section*/
 <input type="file" name="files" multiple="multiple" id="Button_select_1" />
<div >
    <div >
        <label>
            <input data-val="true" data-val-required="Kindly submit your response" id="16_3" name="AnswerResponse" type="radio" value="1" />
            <label>Yes</label>
        </label>
    </div>
</div>
<div >
    <div >
        <label>
            <input checked="checked" id="16_4" name="AnswerResponse" type="radio" value="0" />
            <label>No</label>
        </label>
    </div>
</div>
<div >
    <div >
        <label>
            <input id="16_5" name="AnswerResponse" type="radio" value="2" />
            <label>N/A</label>
        </label>
    </div>
</div>
....
/*nth Section*/
<input type="file" name="files" multiple="multiple" id="Button_select_1" />
<div >
    <div >
        <label>
            <input data-val="true" data-val-required="Kindly submit your response" id="nth_3" name="AnswerResponse" type="radio" value="1" />
            <label>Yes</label>
        </label>
    </div>
</div>
<div >
    <div >
        <label>
            <input checked="checked" id="nth_4" name="AnswerResponse" type="radio" value="0" />
            <label>No</label>
        </label>
    </div>
</div>
<div >
    <div >
        <label>
            <input id="nth_5" name="AnswerResponse" type="radio" value="2" />
            <label>N/A</label>
        </label>
    </div>
</div>
    
I'm loading my form dynamically so my radio button ids are dynamic well. Each section contain input type file button. My input type file id will have the same id that is "Button_select_1" for some reason.

CodePudding user response:

Here is my suggestion

  1. Find the closest static container of all the sections and delegate from there - I made a div with id="container"
  2. wrap each section in a div with class section to be able to navigate to the input from the related radio
  3. Initialise if needed - if the radios may already have been selected from the server

With this code the IDs of the radios and file elements are not needed.

I also removed the nested label which is not valid HTML but this change is not relevant to the question

document.getElementById("container").addEventListener("click", (e) => {
  const tgt = e.target;
  if (!tgt.matches("[name=AnswerResponse]")) return; // not a radio
  tgt.closest(".section").querySelector("[type=file]").disabled = ["0", "2"].includes(tgt.value)
});
// init: 
document.querySelectorAll(".section").forEach(section => {
  const selectedRad = section.querySelector("input[name=AnswerResponse]:checked");
  if (selectedRad) {
    section.querySelector("[type=file]").disabled = ["0", "2"].includes(selectedRad.value);
  }  
})
.section {
  border: 1px solid black;
}
<div id="container">
  <div >
    /*First Section*/
    <input type="file" name="files" multiple="multiple" id="Button_select_1" />
    <div >
      <div >
        <label>            <input data-val="true" data-val-required="Kindly submit your response" id="10_3" name="AnswerResponse" type="radio" value="1" />
            Yes</label>

      </div>
    </div>

    <div >
      <div >
        <label>
            <input checked="checked" id="10_4" name="AnswerResponse" type="radio" value="0" />
 No</label>

      </div>
    </div>
    <div >
      <div >
        <label>
            <input id="10_5" name="AnswerResponse" type="radio" value="2" />
N/A</label>

      </div>
    </div>
  </div>
  <div >
    /*Second Section*/
    <input type="file" name="files" multiple="multiple" id="Button_select_1" />
    <div >
      <div >
        <label>
            <input data-val="true" data-val-required="Kindly submit your response" id="11_3" name="AnswerResponse" type="radio" value="1" />
Yes</label>

      </div>
    </div>
    <div >
      <div >
        <label>
            <input checked="checked" id="11_4" name="AnswerResponse" type="radio" value="0" />
No</label>

      </div>
    </div>
    <div >
      <div >
        <label>
            <input id="11_5" name="AnswerResponse" type="radio" value="2" />
N/A</label>

      </div>
    </div>
  </div>
  <div >
    /*Third Section*/
    <input type="file" name="files" multiple="multiple" id="Button_select_1" />
    <div >
      <div >
        <label>
            <input data-val="true" data-val-required="Kindly submit your response" id="16_3" name="AnswerResponse" type="radio" value="1" />
Yes</label>

      </div>
    </div>
    <div >
      <div >
        <label>
            <input checked="checked" id="16_4" name="AnswerResponse" type="radio" value="0" />
No</label>

      </div>
    </div>
    <div >
      <div >
        <label>
            <input id="16_5" name="AnswerResponse" type="radio" value="2" />
N/A</label>

      </div>
    </div>
  </div>
  <div >
    .... /*nth Section*/
    <input type="file" name="files" multiple="multiple" id="Button_select_1" />
    <div >
      <div >
        <label>
            <input data-val="true" data-val-required="Kindly submit your response" id="nth_3" name="AnswerResponse" type="radio" value="1" />
Yes</label>

      </div>
    </div>
    <div >
      <div >
        <label>
            <input checked="checked" id="nth_4" name="AnswerResponse" type="radio" value="0" />
No</label>

      </div>
    </div>
    <div >
      <div >
        <label>
            <input id="nth_5" name="AnswerResponse" type="radio" value="2" />
N/A</label>

      </div>
    </div>
  </div>

CodePudding user response:

Assuming that there can be more than 1 checkbox/radio button checked at a time throughout the entire collection of elements you need some means by which to distinguish them as a group, otherwise as they are all called the same thing you will only be able to check one at a time. To that end you can remove ID attributes generally as they often cause issues and use a name[x] type syntax for the radio button names. If there are a unlimited possible number of these, dynamically generated, it becomes easy to assign a number ( or unique string ) within the square braces in whatever code generates the sections.

As mentioned by @mplungian, nesting the elements within a common parent ( a section is perfect ) it becomes very easy to process the checking of radio buttons and the required enable/disable of the file input. A delegated event listener, bound to the page in this case, will work regardless of the number of dynamic elements added to the DOM and some very simple code within the event handler will find the file input and disable it if any radio other than the Yes radio is checked. As that is to be the default behaviour and the No is selected by default it makes sense to disable the file input initially.

The name[x] type syntax can also help when processing a large dataset serverside as that x value acts as a key within the array!

document.addEventListener('change',e=>{
  if( e.target instanceof HTMLInputElement && e.target.type=='radio' ){
    let bttn=e.target.closest('section').querySelector('[type="file"]');
        bttn.disabled=( parseInt( e.target.value )!==1 );
    }
})
body{
  counter-reset:sections;
}

section:before{
  counter-increment:sections;
  content:'Section: 'counter(sections)
}
<section>
  <input type="file" name="files" multiple="multiple" disabled />
  <div >
    <div >
      <label><input data-val="true" data-val-required="Kindly submit your response"  name="AnswerResponse[1]" type="radio" value="1" />Yes</label>
    </div>
  </div>
  <div >
    <div >
      <label><input checked="checked" name="AnswerResponse[1]" type="radio" value="0" />No</label>
    </div>
  </div>
  <div >
    <div >
      <label><input name="AnswerResponse[1]" type="radio" value="2" /> N/A</label>
    </div>
  </div>
</section>



<section>
  <input type="file" name="files" multiple="multiple" disabled />
  <div >
    <div >
      <label><input data-val="true" data-val-required="Kindly submit your response"  name="AnswerResponse[2]" type="radio" value="1" />Yes</label>
    </div>
  </div>
  <div >
    <div >
      <label><input checked="checked" name="AnswerResponse[2]" type="radio" value="0" />No</label>
    </div>
  </div>
  <div >
    <div >
      <label><input name="AnswerResponse[2]" type="radio" value="2" />N/A</label>
    </div>
  </div>
</section>



<section>
  <input type="file" name="files" multiple="multiple" disabled />
  <div >
    <div >
      <label><input data-val="true" data-val-required="Kindly submit your response" name="AnswerResponse[3]" type="radio" value="1" />Yes</label>
    </div>
  </div>
  <div >
    <div >
      <label><input checked="checked" name="AnswerResponse[3]" type="radio" value="0" />No</label>
    </div>
  </div>
  <div >
    <div >
      <label><input name="AnswerResponse[3]" type="radio" value="2" />N/A</label>
    </div>
  </div>
</section>



<section>
  <input type="file" name="files" multiple="multiple" disabled />
  <div >
    <div >
      <label><input data-val="true" data-val-required="Kindly submit your response" name="AnswerResponse[n]" type="radio" value="1" />Yes</label>
    </div>
  </div>
  <div >
    <div >
      <label><input checked="checked" name="AnswerResponse[n]" type="radio" value="0" />No</label>
    </div>
  </div>
  <div >
    <div >
      <label><input name="AnswerResponse[n]" type="radio" value="2" />N/A</label>
    </div>
  </div>
</section>

  • Related