Reputation: 47
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
Reputation: 1308
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
Reputation: 3738
You were almost there, there are 2 problems in your js making it to fail :
var tabbar = document.getElementsByClassName("tab");
document.tabbar.appendChild(btn);
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
.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);
id
s instead of class
in jsI personnaly prefer using id
s 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
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"
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
Reputation: 67
Try Jquery! For example:
this.$OuterDiv = $('<div></div>')
.hide()
.append($('<table></table>')
.attr({ id : tabname })
.addClass("tabcontent")
);
Upvotes: -1