imrems
imrems

Reputation: 47

How to add dynamically HTML with JS?

I tried to add HTML code after clicking a button.

Here is the thing; you input the tab's name then click the button linked to the addTab function. Then I tried to write the code using createElement(), setAttribute() and appendChild() but nothing works.

function openTab(evt, tabName) {
  var i, tabcontent, tablinks;

  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }

  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }

  document.getElementById(tabName).style.display = "block";
  evt.currentTarget.className += " active";
}

function addTab() {
  var tabname = entree.value;
  var btn = document.createElement("BUTTON");
  btn.innerHTML = tabname;
  btn.setAttribute("class", "tablinks")
  btn.setAttribute("onlick", "openTab(event, ${tabname})");
  var tabbar = document.getElementsByClassName("tab");
  document.tabbar.appendChild(btn);

  var tabdiv = document.createElement("DIV");
  document.body.appendChild(tabdiv);
  tabdiv.setAttribute("id", tabname);
  tabdiv.setAttribute("class", "tabcontent")

  var tabp = document.createElement("P");
  var tabptxt = document.createTextNode("Réussite.");
  tabp.appendChild(tabptxt);
}
header {
  padding-bottom: 10px;
}

.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
}

.tab button:hover {
  background-color: #ddd;
}

.tab button.active {
  background-color: #ccc;
}

.tabcontent {
  display: none;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}
<header>
  <label>Enter tab's name : </label>
  <input type="text" id="entree" minlength="4" maxlength="12" size="12">
  <button onclick="addTab()">VALIDER</button>
</header>

<body>
  <div class="tab">
    <button class="tablinks" onclick="openTab(event, '12septembre')">12septembre</button>
    <button class="tablinks" onclick="openTab(event, '7octobre')">7octobre</button>
  </div>
  <div id="12septembre" class="tabcontent">
    <h3>12 septembre</h3>
  </div>
  <div id="7octobre" class="tabcontent">
    <h3>7 octobre</h3>
  </div>
</body>

As I'm not experimented using Js, i get lost easily! I also wondered, is this the best way to add tabs dynamically?

Thanks for your help.

Upvotes: 1

Views: 199

Answers (3)

Shakir Ahamed
Shakir Ahamed

Reputation: 1308

enter image description here

Like above you can add a debugger in browser console and check

var tabbar = document.getElementsByClassName("tab");

in here tabbar will return HTMLCollection so we have to get only the element from the Collection. we can get the element from the collection like below.

var tabbar = document.getElementsByClassName("tab");
tabbar[0].appendChild(btn);

function openTab(evt, tabName) {
    var i, tabcontent, tablinks;

    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }

    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }

    document.getElementById(tabName).style.display = "block";
    evt.currentTarget.className += " active";
}

function addTab() {
    var tabname = entree.value;
    var btn = document.createElement("BUTTON");
    btn.innerHTML = tabname;
    btn.setAttribute("class", "tablinks")
    btn.setAttribute("onlick", "openTab(event, ${tabname})");
    var tabbar = document.getElementsByClassName("tab");
    tabbar[0].appendChild(btn);

    var tabdiv = document.createElement("DIV");
    document.body.appendChild(tabdiv);
    tabdiv.setAttribute("id", tabname);
    tabdiv.setAttribute("class", "tabcontent")

    var tabp = document.createElement("P");
    var tabptxt = document.createTextNode("Réussite.");
    tabp.appendChild(tabptxt);
}
header {
    padding-bottom: 10px;
}

.tab {
    overflow: hidden;
    border: 1px solid #ccc;
    background-color: #f1f1f1;
}

.tab button {
    background-color: inherit;
    float: left;
    border: none;
    outline: none;
    cursor: pointer;
    padding: 14px 16px;
    transition: 0.3s;
}

.tab button:hover {
    background-color: #ddd;
}

.tab button.active {
    background-color: #ccc;
}

.tabcontent {
    display: none;
    padding: 6px 12px;
    border: 1px solid #ccc;
    border-top: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
    <label>Enter tab's name : </label>
    <input type="text" id="entree" minlength="4" maxlength="12" size="12">
    <button onclick="addTab()">VALIDER</button>
</header>

<body>
    <div class="tab">
        <button class="tablinks" onclick="openTab(event, '12septembre')">12septembre</button>
        <button class="tablinks" onclick="openTab(event, '7octobre')">7octobre</button>
    </div>
    <div id="12septembre" class="tabcontent">
        <h3>12 septembre</h3>
    </div>
    <div id="7octobre" class="tabcontent">
        <h3>7 octobre</h3>
    </div>
</body>

Upvotes: 0

jonatjano
jonatjano

Reputation: 3738

the problem

You were almost there, there are 2 problems in your js making it to fail :

var tabbar = document.getElementsByClassName("tab");
document.tabbar.appendChild(btn);
  • you called the variable tabbar but on next line try to call it with the name document.tabbar which is not the same thing, this can be seen in the browser console: it's telling document.tabbar is undefined.
  • you misused document.getElementsByClassName, you probably thought it return an HTMLElement but in fact it returns an HTMLCollection, a sort of array with less buitin method, so you need to get your element out of the collection.

here's a corrected version of these 2 lines :

var tabbar = document.getElementsByClassName("tab")[0];
tabbar.appendChild(btn);

use ids instead of class in js

I personnaly prefer using ids to get element with document.getElementById, since id MUST be unique so a good formed HTML will always have only one element with this id

also document.getElementById returns an HTMLElement so no need to look for the wanted Element in an a Collection

and finally since using class as a vulnerability, if you ever add another tag with the same class before the current one then your tabbar will become the second element of the HTMLCollection


another error you didn't see yet

as mentionned by epascarello in comments

btn.setAttribute("onlick", "openTab(event, ${tabname})");

should be written

btn.setAttribute("onlick", `openTab(event, '${tabname}')`);

with ` instead of " to use the expension of template litterals

as a note : it is considered bad practise to define event in the HTML, you should do it like this :

btn.addEventListener('click', openTab)

or you can also use

btn.onlick = function() { openTab(btn, tabname); } // or
btn.onlick = () => openTab(btn, tabname);

but these two ways to write it requires you to modify openTab replacing

evt.currentTarget.className += " active";

by

btn.className += " active"

a corrected version

and finally a corrected version of your snippets (I didn't touch anything except these 3 lines)

function openTab(evt, tabName) {
    var i, tabcontent, tablinks;

    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }

    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }

    document.getElementById(tabName).style.display = "block";
    evt.currentTarget.className += " active";
}

function addTab() {
    var tabname = entree.value;
    var btn = document.createElement("BUTTON");
    btn.innerHTML = tabname;
    btn.setAttribute("class", "tablinks")
    btn.setAttribute("onlick", `openTab(event, '${tabname}')`);
    var tabbar = document.getElementsByClassName("tab")[0];
    tabbar.appendChild(btn);

    var tabdiv = document.createElement("DIV");
    document.body.appendChild(tabdiv);
    tabdiv.setAttribute("id", tabname);
    tabdiv.setAttribute("class", "tabcontent")

    var tabp = document.createElement("P");
    var tabptxt = document.createTextNode("Réussite.");
    tabp.appendChild(tabptxt);
}
header {
    padding-bottom: 10px;
}

.tab {
    overflow: hidden;
    border: 1px solid #ccc;
    background-color: #f1f1f1;
}

.tab button {
    background-color: inherit;
    float: left;
    border: none;
    outline: none;
    cursor: pointer;
    padding: 14px 16px;
    transition: 0.3s;
}

.tab button:hover {
    background-color: #ddd;
}

.tab button.active {
    background-color: #ccc;
}

.tabcontent {
    display: none;
    padding: 6px 12px;
    border: 1px solid #ccc;
    border-top: none;
}
<header>
    <label>Enter tab's name : </label>
    <input type="text" id="entree" minlength="4" maxlength="12" size="12">
    <button onclick="addTab()">VALIDER</button>
</header>

<body>
    <div class="tab">
        <button class="tablinks" onclick="openTab(event, '12septembre')">12septembre</button>
        <button class="tablinks" onclick="openTab(event, '7octobre')">7octobre</button>
    </div>
    <div id="12septembre" class="tabcontent">
        <h3>12 septembre</h3>
    </div>
    <div id="7octobre" class="tabcontent">
        <h3>7 octobre</h3>
    </div>
</body>

there are also some other things to say on your code but it's mainly because you don't know JS native API enought yet.

Upvotes: 2

Ludovico Sidari
Ludovico Sidari

Reputation: 67

Try Jquery! For example:

this.$OuterDiv = $('<div></div>')
.hide()
.append($('<table></table>')
    .attr({ id : tabname })
    .addClass("tabcontent")
);

Upvotes: -1

Related Questions