0

I have an HTML form that will contain predefined values that the user will have to confirm by editing their contents, if needed. I would like to perform a constant check so that the color background of every cell changes accordingly to its content. For example, if the cell is empty, its background should be red. Later on I will add more check, for example if it contains the string "MISSING VALUE" it should be yellow and so on.

This is an example of my form and the code I'm trying to execute:

<!DOCTYPE html>
<html>
<style type="text/css">
  table.first {
    display: table;
    table-layout: auto;
    float: none margin-left: auto;
    margin-right: auto;
  }
  
  .table_element {
    display: table-cell;
  }
</style>

<table class="first">
  <div class="table_element">
    <p style="text-align: center;">First Name:<br><input name="import_date_visit" id="subEmail" type="text" required size="25" onchange="checkFilled();" value="Claudio"></p>
  </div>
  <div class="table_element">
    <p style="text-align: center;">Last name:<br><input name="import_date_visit" type="text" required size="25" onchange="checkFilled();" value="MISSING VALUE"></p>
  </div>
</table>

<script type="text/javascript">
  function checkFilled() {
    var inputVal = document.getElementsByClassName("table_element");
    for (var i = 0; i < inputVal.length; i++) {
      document.writeln((i + 1) + ": " + inputVal[i].value);
    }
    for (var i = 0; i < inputVal.length; i++) {
      if (inputVal[i].value == "") {
        inputVal[i].style.backgroundColor = "red";
      } else {
        inputVal[i].style.backgroundColor = "white";
      }
    }
  }
  checkFilled();
</script>

</html>

What I don't understand is how to get the value of the string inside the div element. As you can see, I'm trying to print it as a debug, and I'm expecting to get the values Claudio and MISSING VALUE, but all I get is undefined. I suppose it should be pretty straightforward to get the content of a cell, so I assume I'm missing something very obvious. Thanks for the help.

3
  • 1
    Don't use document.write() or .writeln() for debugging. There are better options, e.g. console.log() Commented May 12, 2021 at 8:53
  • 1
    The structure of a html document is: <html><head></head><body></body></html> and in your case the <body> element is not optional Commented May 12, 2021 at 8:56
  • 1
    A <div> element has no .value property. Either query the DOM for the <input>s and then traverse up the DOM for the styling, or find the <input>s in the <div>s Commented May 12, 2021 at 8:57

2 Answers 2

2

First find input element inside your div element and then use value property on it.

    function checkFilled() {
        const divEle = document.getElementsByClassName("table_element");
       
        for(let i = 0; i < divEle.length; i++) {
            const inputVal = divEle[i].children[0].children[1];
            if (inputVal.value == "") {
              inputVal.style.backgroundColor = "red";
            } else if (inputVal.value == "MISSING VALUE") {
              inputVal.style.backgroundColor = "green";
            }
        }
    }
checkFilled();
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
    table.first{
        display: table;
        table-layout: auto;
        float:none
        margin-left: auto; 
        margin-right: auto;
    }
    .table_element{
        display: table-cell;
    }
</style>
</head>
<body>

<table class="first">
    <div class="table_element">
        <p style="text-align: center;">First Name:<br>
        <input name="import_date_visit" id="subEmail" type="text" required size="25" onchange="checkFilled();" value="Claudio" />
        </p>
    </div>
    <div class="table_element">
        <p style="text-align: center;">Last name:<br><input name="import_date_visit" type="text" required size="25" onchange="checkFilled();" value="MISSING VALUE" /></p>
    </div>
</table>

</body>

</html>

Sign up to request clarification or add additional context in comments.

5 Comments

"divEle[i].children[0].children[1];" - sorry, but this is not modern JavaScript …
What do you mean by modern JavaScript, How do you write it other way, please let me know.
Are you talking about to use childNodes instead of children?
I mean, that you should not access children of an element by using indexes, but rather by giving the childs classes / id's and using document.querySelector or document.querySelectorAll
I understand your concern you are talking about best practices
1

Firstly, you should always have a body element. Whenever you create anew HTML document, you should first paste in the following:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
    </body>
</html>

Scripts and stylesheets should go into the head section, and any content that should be visible to the user in to the body section. <meta charset="utf-8"> should be always present - else non-ASCII characters will not be rendered correctly. Change utf-8 to whatever encoding you use in your editor.

Secondly, inputVal[i].value tries to access the value property of the p element in side .table_element - but paragraphs don't have a value, so you get undefined.

Thirdly, document.write and document.writeln should not be used - if you want to show something to the user, write it into a HTML element, and if you want to print something for debugging purposes, use console.log(...).

Lastly, div's are not valid children of a table - only thead, tbody and tr are.

To find the input elements, you can use document.querySelectorAll. Following the working, modern code:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <style type="text/css">
    table.first {
      display: table;
      table-layout: auto;
      float: none;
      margin-left: auto;
      margin-right: auto;
    }
    
    .table_element {
      display: table-cell;
    }
  </style>
  <script type="text/javascript">
    function checkFilled() {
      let inputElements = document.querySelectorAll(".table_element input");
      let outputElement = document.querySelector("#output");
      outputElement.innerHTML = "You entered : ";

      for (let [index, inputElement] of inputElements.entries()) {
        outputElement.innerHTML += " " + (index + 1) + " " + inputElement.value;
        if (inputElement.value == "") {
          inputElement.style = "background-color: red;";
        } else {
          inputElement.style = "background-color: green;";
        }
      }
    }
    window.addEventListener("load", checkFilled);
  </script>
</head>

<body>
  <div class="table_element">
    <p style="text-align: center;">First Name :</p>
    <input name="import_date_visit" id="subEmail" type="text" required size="25" oninput="checkFilled();" value="Claudio">
  </div>
  <div class="table_element">
    <p style="text-align: center;">Last name :</p>
    <input name="import_date_visit" type="text" required size="25" oninput="checkFilled();" value="MISSING VALUE">
  </div>
  <p id="output">You entered : nothing yet</p>
</body>

</html>

3 Comments

It's recommended to add your script under body in last, so that it improves the performance or load time.
"It's recommended to add your script under body in last" - can you provide a link where that's stated ?
betterexplained.com/articles/speed-up-your-javascript-load-time you can read the section Optimize Javascript Placement

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.