Search code examples
javascripthtmlcssappendchild

The dynamically added template div doesn't persist and disappears within seconds


I am new to web development and am trying to make a chat interface as a mini project. So, I am testing whether the messages can be displayed in the chat history window. I wrote the code in such a way that when I click the send button(even without typing anything in textbox) , the chat history must add a message for itself.

To do this, I have put a template for every new message. And when send is clicked, I am trying to add it through appendChild(). But, when I am clicking the send button, the new message stays for a fraction of second and disappears. You can say, it blinks. But I want it to be visible completely. Is my way of doing it wrong or is there a better and easy way to do it.

I have read that using innerHTML will have some side-effects and I have no knowledge about jQuery. So, please answer with that perspective.

Other suggestions regarding my coding style are also appreciated.

<html>

<head>
  <style>
    #message {
      -webkit-border-radius: 15px;
      float: bottom;
      position: fixed;
      max-width: 400px;
      background: blue;
      word-wrap: break-word;
    }
    
    #sender {
      text-align: left;
      padding-left: 20px;
      padding-top: 5px;
      font-family: Arial;
      font-weight: bold;
      color: white;
    }
    
    #text {
      text-align: left;
      font-size: 18px;
      padding-left: 20px;
      padding-right: 20px;
    }
    
    #time {
      text-align: right;
      padding-right: 15px;
      font-size: 15px;
    }
    
    #nav {
      height: 10%;
      margin: 0px;
      padding: 0px;
      background: blue;
    }
    
    body {
      margin: 0px;
      padding: 0px;
      overflow: hidden;
    }
    
    #nextwhole {
      -webkit-orient: horizontal;
    }
    
    #navbar {
      width: 25%;
      background: green;
      height: 90%;
      float: left;
    }
    
    #msgchat {
      width: 75%;
      height: 100%;
      position: relative;
      float: right;
    }
    
    #messages {
      background: orange;
      height: 80%;
      width: 100%;
    }
    
    #chatint {
      background: red;
      height: 10%;
      width: 100%;
    }
    
    #chattext {
      width: 90%;
      height: 90%;
    }
    
    #send {
      width: 9.5%;
      height: 90%;
    }
  </style>


  <script>
    function submitfun() {

      if ('content' in document.createElement('template')) {


        var t = document.querySelector('#msgtemplate');
        var td = t.content.querySelectorAll("p");
        td[0].textContent = "user";
        td[1].textContent = "this is message";
        td[2].textContent = "time";


        var tb = document.querySelector("#messages");
        var clone = document.importNode(t.content, true);
        tb.appendChild(clone);



      }

    }
  </script>



</head>

<body>
  <div id="nav">
  </div>

  <div id="nextwhole">
    <div id="navbar"></div>
    <div id="msgchat">
      <div id="messages">
      </div>
      <div id="chatint">
        <form onsubmit="submitfun()">
          <input type="text" id="chattext">
          <input type="submit" id="send" value="SEND">
        </form>
      </div>
    </div>


  </div>
  <template id="msgtemplate">
<div id="message">
<p id="sender"></p>
<p id="text"></p>
<p id="time"></p>
</div>
</template>


</body>

</html>


Solution

  • Because you're making use of a <form>, it attempts to submit the form by default.

    To prevent this, you need to update your onsubmit to also pass the event:

    <form onsubmit="submitfun(event)">
    

    And prevent the default behaviour with:

    function submitfun(e) {
      e.preventDefault();
      ...
    

    This can be seen in the following:

    function submitfun(e) {
      e.preventDefault();
      if ('content' in document.createElement('template')) {
        var t = document.querySelector('#msgtemplate');
        var td = t.content.querySelectorAll("p");
        td[0].textContent = "user";
        td[1].textContent = "this is message";
        td[2].textContent = "time";
        var tb = document.querySelector("#messages");
        var clone = document.importNode(t.content, true);
        tb.appendChild(clone);
      }
    }
    #message {
      -webkit-border-radius: 15px;
      float: bottom;
      position: fixed;
      max-width: 400px;
      background: blue;
      word-wrap: break-word;
    }
    
    #sender {
      text-align: left;
      padding-left: 20px;
      padding-top: 5px;
      font-family: Arial;
      font-weight: bold;
      color: white;
    }
    
    #text {
      text-align: left;
      font-size: 18px;
      padding-left: 20px;
      padding-right: 20px;
    }
    
    #time {
      text-align: right;
      padding-right: 15px;
      font-size: 15px;
    }
    
    #nav {
      height: 10%;
      margin: 0px;
      padding: 0px;
      background: blue;
    }
    
    body {
      margin: 0px;
      padding: 0px;
      overflow: hidden;
    }
    
    #nextwhole {
      -webkit-orient: horizontal;
    }
    
    #navbar {
      width: 25%;
      background: green;
      height: 90%;
      float: left;
    }
    
    #msgchat {
      width: 75%;
      height: 100%;
      position: relative;
      float: right;
    }
    
    #messages {
      background: orange;
      height: 80%;
      width: 100%;
    }
    
    #chatint {
      background: red;
      height: 10%;
      width: 100%;
    }
    
    #chattext {
      width: 90%;
      height: 90%;
    }
    
    #send {
      width: 9.5%;
      height: 90%;
    }
    <body>
      <div id="nav"></div>
      <div id="nextwhole">
        <div id="navbar"></div>
        <div id="msgchat">
          <div id="messages">
          </div>
          <div id="chatint">
            <form onsubmit="submitfun(event)">
              <input type="text" id="chattext">
              <input type="submit" id="send" value="SEND">
            </form>
          </div>
        </div>
      </div>
      <template id="msgtemplate">
        <div id="message">
          <p id="sender"></p>
          <p id="text"></p>
          <p id="time"></p>
        </div>
      </template>
    </body>