How can I set a javascript const to a value in a form element that could be either a dropdown select or a checked radio button?

I have an html form in a django site that is used for both add and update. If the form is for a new entry, I want the field estimateType to be radio buttons with three choices, one of which is checked by default. If the form is for an edit to an existing entry, I want the form widget to change to a select dropdown with additional choices to pick from.

In the javascript in the onchange event, I need to know what the value of the estimateType field is. I can get it to work for select, or radio input, but not both. For example, what I have right now is:

const estimateType = document.querySelector(input[name=estimateType]:checked).value;

That works for a radio button but not the select dropdown. How can I use the same const declaration but account for heterogeneous form input types?

You can use a comma to separate the selectors and it'll pull what it finds: Note that the JS is the identical for each snippet.

const estimateType = document.querySelector("input[name=estimateType]:checked,select[name=estimateType]").value;
console.log(estimateType)
<input type="radio" name="estimateType" value="A">A
<input type="radio" name="estimateType" value="B" checked>B
<input type="radio" name="estimateType" value="C">C

const estimateType = document.querySelector("input[name=estimateType]:checked,select[name=estimateType]").value;
console.log(estimateType)
<select name="estimateType" >
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D" selected>D</option>
  <option value="E">E</option>
</select>

In HTML, any <input>, <output>, <button>, or <textarea> elements are form's childrens.
Just use their name for identification in the form...

const myForm = document.querySelector('#my-form');

btnTest.onclick =_=>
  {
  console.clear();
  console.log( myForm.estimateType.value ); // estimateType is name of the form's element
  }
<form id="my-form">
  <input type="radio" name="estimateType" value="A">A
  <input type="radio" name="estimateType" value="B" checked>B
  <input type="radio" name="estimateType" value="C">C
</form>

<button id="btnTest"> get value </button>

const myForm = document.querySelector('#my-form');

btnTest.onclick = _ => 
  {
  console.clear();
  console.log( myForm.estimateType.value ); // estimateType is name of the form's element
  }
<form id="my-form">
  <select name="estimateType">
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C">C</option>
    <option value="D" selected>D</option>
    <option value="E">E</option>
  </select>
</form>

<br><br><br><br><br><br><br>
<button id="btnTest"> get value </button>

You get the value of either a select element or radiolist by it's value property. There is no difference between the two.

Don't use a queryselector for this. In the case of the radio buttons, the queryselector will just get one of the elements, whereas form.estimateType is the collection aka. a radioList, and the radioList has the selected value.

document.addEventListener('click', e => {
  if (e.target.name == 'get_estimate_type') {
    let form = e.target.form;
    console.log(form.estimateType.value);
  }
});
<p>Form with select</p>
<form>
  <select name="estimateType">
    <option value="a">a</option>
    <option value="b" selected>b</option>
    <option value="c">c</option>
  </select>
  <button type="button" name="get_estimate_type">Get estimate type</button>
</form>
<p>Form with radio</p>
<form>
  <label><input type="radio" name="estimateType" value="a" checked>a</label>
  <label><input type="radio" name="estimateType" value="b">b</label>
  <button type="button" name="get_estimate_type">Get estimate type</button>
</form>

Back to Top