Peter Peter - 2 months ago 8
Javascript Question

Why removing a child element like this doesn't work?

There is a problem with the last line inside

txtAgeBlur
function. Why I can't remove the child node like this?



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Forms</title>
</head>
<body>
<form action="" name="form1">
<p>
Name
<input type="text" name="txtName">
</p>
<p>
Age
<input type="text" name="txtAge" size="3" maxlength="3">
</p>
<p>
<input type="button" value="Check details" name="btnCheckForm">
</p>
</form>

<script>
var myForm = document.form1;

function btnCheckFormClick(e) {
var name = myForm.txtName.value;
var age = myForm.txtAge.value;

if (name === "" || age === "") {
alert("Please complete all of the form");

if (name === "")
myForm.txtName.focus();
else
myForm.txtAge.focus();
}
else
alert("Thanks for completing the form " + name);
}

var messageInserted = false;

function txtAgeBlur(e) {
//console.log(e.type);
var target = e.target;
var msg = document.createElement("span");
msg.id = "msg";
msg.appendChild(document.createTextNode("Please enter a valid age"));

if (isNaN(target.value)) {
if (!messageInserted) {
messageInserted = true;
target.parentElement.appendChild(msg);
}
target.focus();
target.select();
}
else if (messageInserted === true)
document.getElementsByTagName("p")[1].removeChild(msg); //problem
}

myForm.btnCheckForm.addEventListener("click", btnCheckFormClick);
myForm.txtAge.addEventListener("blur", txtAgeBlur);
</script>
</body>
</html>





However, this deletes the child element without any problem. What's the difference between this and the example above?



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Forms</title>
</head>
<body>
<script>
var msg = document.createElement("span");
msg.appendChild(document.createTextNode("Please enter a valid age"));
document.body.appendChild(msg);

var msg2 = document.querySelector("span");
console.log(msg === msg2);
document.body.removeChild(msg);
</script>
</body>
</html>




Answer

Each time txtAgeBlur is called, you create an new <span> which you reference with msg. When you are trying to remove the currently showing message, msg references a new <span> that has not yet been inserted. You need to get a reference to the currently showing message to remove it.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Forms</title>
</head>
<body>
  <form action="" name="form1">
    <p>
      Name
      <input type="text" name="txtName">
    </p>
    <p>
      Age
      <input type="text" name="txtAge" size="3" maxlength="3">	
    </p>
    <p>
      <input type="button" value="Check details" name="btnCheckForm">
    </p>
  </form>

  <script>
    var myForm = document.form1;

    function btnCheckFormClick(e) {
      var name = myForm.txtName.value;
      var age = myForm.txtAge.value;

      if (name === "" || age === "") {
        alert("Please complete all of the form");

        if (name === "")
          myForm.txtName.focus();
        else
          myForm.txtAge.focus();
      }
      else
        alert("Thanks for completing the form " + name);
    }

    var messageInserted = false;

    function txtAgeBlur(e) {
      //console.log(e.type);
      var target = e.target;
      if (isNaN(target.value)) {
        if (!messageInserted) {
          //There is no reason to do the work of creating the <span> if you are not
          //  going to be inserting it.  Thus, you should create it here, not
          //  every time you call txtAgeBlur.
          var msg = document.createElement("span");
          msg.id = "msg";
          msg.appendChild(document.createTextNode("Please enter a valid age"));

          messageInserted = true;
          target.parentElement.appendChild(msg);
        }
        target.focus();
        target.select();
      } else if (messageInserted === true){
        //When you get here, msg is a NEW span that has not been inserted.  Thus,
        //  you do not remove the span that has never been inserted.
        //document.getElementsByTagName("p")[1].removeChild(msg); //problem
        //You need to get a reference to the span you have already inserted.
        var currentMessage = document.getElementById('msg');
        currentMessage.parentNode.removeChild(currentMessage);
    
      }
    }

    myForm.btnCheckForm.addEventListener("click", btnCheckFormClick);
    myForm.txtAge.addEventListener("blur", txtAgeBlur);
  </script>
</body>
</html>

Comments