Search code examples
javascriptdom-eventsjavascript-objects

Path of <form> elements in onsubmit event listener


I managed to find the event element's path to change the color of a <form> input field's <label> from a event listener.Now I want to do the same from an onsubmit handler, but I can't figure out the correct path:

<form id="myForm">
  <label id="labelForInput" for="inputField">LABEL</label>
  <input id="inputField">
  <input id="submitButton" type="submit" value="Send"/>
</form>

<script>
  document.getElementById("inputField").addEventListener("click", clickHandler);

  function clickHandler(event) {
      // onClick on input element, the label's color changes to red:
      event.srcElement.labels[0].style.color='red';
  }

  document.getElementById("myForm").addEventListener( "submit", {return submitHandler} );

  function submitHandler(event) {
      // What's the path to change the label's color to 'green' upon click on submit button?
      // **???** .style.color='`green';
      return false;
  }
</script>

EDIT: Sorry, my question was a bit oversimplyfied. I don't know the labels ids and names in the onsubmit handler, only the input field's names, thus I can't use outright getElementById. Actually, in the paticular case, the labels don't have ids nor names defined, but they are bound to their input fields by 'for='. I'm looping over an array containing the input field names and I want to change a label's color upon a condition:

const fieldNames=['form_name','form_email','form_message'];
const fieldConds=[true, false, true];

function submitHandler(event) {
  fieldConds.forEach( (value, idx) => { 
            if (!value) { ... CHANGE COLOR ... }
}

So, I think what I'm looking for is something like callingFormObject.inputFields[].label.style.color , like I used in clickHandler. But in onsubmit, the event object seems to only contains the string representing the form, no property fields.


Solution

  • Regarding the edit of the original post:

    One can add to the querySelector also attributes. So in particular the input with a certain name can be obtained as myForm.querySelector("input[name='form_name']"). To find the corresponding labels one can first get the list of all labels with querySelectorAll() yielding a NodeList and then filter them to obtain the one that refers to the current input-field in its for-attribute. NodeList doesn't have its own filter()-method, so one has to borrow it from the Array.prototype or simply from an empty array [] (see here for the filter-method and here for the borrowing via call syntax):

    function submitHandler(event) {
    fieldConds.forEach( (value, idx) => { 
       if (!value) {
          const input = myForm.querySelector(`input[name=${fieldNames[idx]}]`);
          const labels = myForm.querySelectorAll("label");
          const labelForInput = [].filter.call(labels, l => l.getAttribute('for') == input.id)[0]; // filter should only leave a single entry in the resulting array
          labelForInput.style.color = "green"; 
       }
    }