Most efficient way to verify multiple html table row inputs in a JS cycle?

Viewed 75

Very much appreciated if you can help me since I am a newbie on this. I have a huge html table with more than 10 columns and around 20 rows.

I want to do a javascript cycle to verify the inputs of all the rows. My strategy was to insert Ids in each in which each row's id always increases +1. For example:

<td><input id="ingredient_percentage_1" type="text" name=" " form="form1" />%</td>
<td><input id="ingredient_percentage_2" type="text" name=" " form="form2" />%</td>

The code I've done is like this:

function verifyPercentages(){

  var total = 0;
  var i;

  if (batch.value === "") {
    alert ("Please insert value in Batch Size field");
    return false;
  }
  else {
    for (i=1; i<19; i++){
      var percentage = document.getElementById('ingredient_percentage_'+i);
      if( (((i>1) && (i<5)) || (i==11) || (i==13)) && (percentage.value == "")) {
        alert ("Mandatory fields are not filled up");
        return false;
      }
      if ((i>6) && (i<9) && (percentage.value == "")) {
        alert ("Please select an option in the Product type field above");
        return false;
      }
      if ((i>8) && (i<11) && (percentage.value >= 1)) {
        alert ("Please make sure that the percentages for oil are less than 1%");
        return false;
      }
      if ((i>14) && (i<17) && (percentage.value >= 1)) {
        alert ("Please make sure that (...)");
        return false;
      }
      if (percentage == null) continue;
    }

    calculatePercentages();
  }
}

But I feel that is not very optimized. Is there a more efficient/clean way to do this? Many thanks

2 Answers

Not wanting to interfere with your tech choices, but you could do this very easily (and robust!) with built in html5 validation. It will work on all modern browsers. You can do more this way than you probably believe. One example of how an email input field in a form could be validated:

<input 
  id="useremail" 
  type="text" 
  placeholder="your.email@example.com" 
  required 
  minlength="6" 
  maxlength="90" 
  pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$" 
  title="Wrong email address format">

Result when error is thrown on Chrome/Brave/Chromium:

input error html5

A more precise error text above, albeit onerous, would be "The email must contain between 5 and 89 alphanumeric characters plus the '@'".

In order to run your function when the form fully validates you can add it into your submit event like so:

const submitButton = document.querySelector('.btn-submit')

submitButton.addEventListener('click', (e) => {
   e.preventDefault()
   calculatePercentages()
})

One alternative is to use Javascript's querySelectorAll with enumeration. Also, many other approaches. In the example below I provide alternative ways to iterate over the HTML elements. I comment where the respected logic should go

The bottom example uses the querySelectorAll to match partially matching id string name values.

The below selector example means to locate an element where the attribute id that does begin with the string "ingredient_".

Implementations Documentation

Note

  • ^ matches the start
  • * matches any position
  • $ matches the end

Edits: Comparison element.value == "" may cause unexpected type coercion. That is why you may notice the if statement logic changed a little from your initial code provided.

  
function verify() {
  elements = document.querySelectorAll(`[id ^= "ingredient_`);
  Array.prototype.forEach.call(elements, callback);

  function callback(element, i) {
    if ((((i > 1) && (i < 5)) || (i === 11) || (i === 13)) && (element.value === "")) {
      // Logic
    }
    if ((i > 6) && (i < 9) && (element.value === "")) {
      // Logic
    }
    if ((i > 8) && (i < 11) && (element.value >= 1)) {
      // Logic
    }
    if ((i > 14) && (i < 17) && (element.value >= 1)) {
      // Logic
    }

    // Debug
    console.log('i:', i, 'id:', element.id, 'value:', element.value)

  }


}

verify();
<td><input id="ingredient_percentage_1" type="text" name=" " value="1" form="form1" />%</td>
<td><input id="ingredient_percentage_2" type="text" name=" " value="2" form="form2" />%</td>

Related