Having to click Twice to get one response - javascript

I have made a dropdown that appears on click on a button. Pretty simple, except for how I have to click twice to get the js function to execute. After I click it the first, it appears and disappears like it should - taking only one click. I have no clue why it would require this and have searched for fixes, but none of them seem to work.
Here is my HTML:
<ul class="resources-menu">
<li>
<button onclick="res()" id="resbut" onblur="setTimeout('reshide()', 175)">Resources</button>
<ul id="resblock">
<li style="padding-bottom: 20px; text-align:center;padding-top:25px">
<button onclick="dirlnk()">Directory</button>
</li>
</ul>
</li>
</ul>
CSS:
.resources-menu {
width:88px;
float:left;
}
#resbut {
font-weight:700;
height:30px;
text-decoration:underline;
border-radius:3px;
border-color: black;
}
ul.resources-menu, ul.resources-menu ul {
list-style:none;
margin:0;
padding:0;
position: relative;
}
#resblock {
width: 90px;
background-color: lightblue;
display: none;
position: absolute;
border-bottom-left-radius: 15px;
border-bottom-right-radius:15px;
border-top-right-radius:10px;
border:solid;
border-color:black;
}
JavaScript
function res() {
if (document.getElementById('resblock').style.display == 'none') {
document.getElementById('resblock').style.display = 'block';
document.getElementById('resbut').style.background = "lightblue";
document.getElementById('resbut').style.borderBottomRightRadius = "0px";
document.getElementById('resbut').style.borderBottomLeftRadius = "0px";
document.getElementById('resbut').style.borderBottom = "none";
document.getElementById('resbut').style.textDecoration = "none";
} else {
document.getElementById('resblock').style.display = 'none';
document.getElementById('resbut').style.background = "";
document.getElementById('resbut').style.borderBottomRightRadius = "";
document.getElementById('resbut').style.borderBottomLeftRadius = "";
document.getElementById('resbut').style.borderBottom = "";
document.getElementById('resbut').style.textDecoration = "";
}
}
function reshide() {
document.getElementById('resblock').style.display = 'none';
document.getElementById('resbut').style.background = "";
document.getElementById('resbut').style.borderBottomRightRadius = "";
document.getElementById('resbut').style.borderBottomLeftRadius = "";
document.getElementById('resbut').style.borderBottom = "";
document.getElementById('resbut').style.textDecoration = "";
}
function dirlnk() {
window.location = "/Portal/directory";
}

You're looking at the style property when it's in the CSS files, not a style attribute. Use getComputedStyle instead:
function res() {
var resblock = document.getElementById('resblock');
var resblockStyle = resblock.style;
var resbutStyle = document.getElementById('resbut').style;
if (getComputedStyle(resblock).display === 'none') {
resblockStyle.display = 'block';
resblockStyle.background = "lightblue";
resbutStyle.borderBottomRightRadius = "0px";
resbutStyle.borderBottomLeftRadius = "0px";
resbutStyle.borderBottom = "none";
resbutStyle.textDecoration = "none";
} else {
reshide();
}
}
function reshide() {
var resblockStyle = document.getElementById('resblock').style;
var resbutStyle = document.getElementById('resbut').style;
resblockStyle.display = 'none';
resbutStyle.background = "";
resbutStyle.borderBottomRightRadius = "";
resbutStyle.borderBottomLeftRadius = "";
resbutStyle.borderBottom = "";
resbutStyle.textDecoration = "";
}
function dirlnk() {
window.location.href = "/Portal/directory";
}
It's also a good idea to cache your variables so you don't need to query the DOM for each style addition. Your reshide function does the same thing as the else in your res function -- you should avoid duplicating code where practicable.
Compatibility issues
As #garromark correctly notes, this solution won't work if you need to support older browsers (i.e. IE8 and below). Alternatively, you can add a class called .no-display and check whether that class is present or not:
.no-display {
display: none !important;
}
Then your JavaScript check:
if (/\bno\-display\b/.test(resblock.className)) {

Related

Is there a way to optimise this?

I'm not very good with HTML and but I'm trying to make a website that will load Discord servers the user is in. I got the servers in map format, but loading them is very slow. Is there a way the time could be reduced? Any help is greatly appreciated!
My HTML
<!DOCTYPE html>
<head>
<title>NULL MUCH?</title>
<style>
.server {
width:200px;
height:200px;
object-fit:cover;
border-radius:50%;
}
.serverImgIn {
width:100px;
height:100px;
object-fit:cover;
border-radius:50%;
border-color: rgb(0, 89, 190);
}
.serverImgOut {
width:100px;
height:100px;
object-fit:cover;
border-radius:50%;
cursor: pointer;
filter: grayscale(100%);
}
.serverRow {
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
</style>
</head>
<body>
<div id="wrapper">
<!-- PLACEHOLDER TEXT HERE -->
</div>
<script>
window.onload = () => {
const guilds = {the guilds in JSON format}
var wrapper = document.getElementById('wrapper');
var row = document.createElement("servers_row");
row.innerHTML = ""; // clear images
row.classList.add('serverRow');
for (let i = 0; i < guilds.length; i++) {
//New row every 10 servers
if (i % 10 == 0) {
wrapper.appendChild(row);
row.innerHTML = "";
row.classList.add('serverRow');
}
var div = document.createElement("div");
var imagem = document.createElement("img");
var name = document.createElement("p");
name.innerText = guilds[i].name;
if (guilds[i].icon) {
imagem.src = `https://cdn.discordapp.com/icons/${guilds[i].id}/${guilds[i].icon}.png`;
} else {
imagem.src = 'http://purepng.com/public/uploads/large/purepng.com-white-cloudnaturestylenaturalbeautifulgreen-5415211264555x7ih.png';
}
if (guilds[i].inServer) {
//OPEN A NEW WINDOW FOR SERVER EDITING
imagem.onclick = function() {
imagem.classList.add('serverImgIn');
var xhr = new XMLHttpRequest();
xhr.open('post', 'http://localhost:53134/getServer/', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhr.setRequestHeader('guilds', JSON.stringify(owned));
xhr.onloadend = (e) => { window.localStorage.setItem('serverInfo', (JSON.stringify(xhr.response))); window.location = 'http://localhost:53134/dashboard.html'; }
xhr.send(JSON.stringify(owned));
}
} else {
imagem.classList.add('serverImgOut');
imagem.onclick = function() {
window.open('DISCORD INVITE LINK HERE');
}//OPEN A NEW WINDOW WITH SERVER INVITE
}
div.appendChild(imagem);
div.appendChild(name);
div.classList.add('server');
row.appendChild(div);
}
wrapper.appendChild(row);
}
</script>
</body>
As a note I'm not sure if adding the onclick function in the loop increases the time, because It's not actually being called.
This is what it looks like on my end but to test it I think you'll have to pass in dummy data (I use the Discord API to get my data)

Background toggle JS only works once

So I have a button on my website that looks like this:
<button id = "bgb">Toggle Background</button>
And I want this button to turn on and off the background in a box. Therefore I made a script in JavaScript to do this.
var bg = true;
document.querySelector("#bgb").onclick = function(){
const mb = document.querySelector(".Main-Box");
if (bg == true)
{
mb.style.background = "white";
bgb = false;
}
if (bg == false)
{
mb.style.background = "linear-gradient(45deg,#F17C58, #E94584, #24AADB , #27DBB1,#FFDC18, #FF3706)";
bgb = true;
}
}
However, when I click on the button, It tuns it off fine but when I want to turn it back on it doesn't work; any suggestions?
bg is always set true.
why you change "bgb"?
try
<script>
var bg = true;
document.querySelector("#bgb").onclick = function () {
const mb = document.querySelector(".Main-Box");
if (bg) {
mb.style.background = "red";
bg = false;
} else {
mb.style.background = "linear-gradient(45deg,#F17C58, #E94584, #24AADB , #27DBB1,#FFDC18, #FF3706)";
bg = true;
}
}
</script>
Here is a demo of what you want:
let bg = true;
document.querySelector("#bgb").onclick = function(){
const mb = document.querySelector(".Main-Box");
if (bg == true)
{
mb.style.background = "white";
bg = false;
}
else if (bg == false)
{
mb.style.background = "linear-gradient(45deg,#F17C58, #E94584, #24AADB , #27DBB1,#FFDC18, #FF3706)";
bg = true;
}
}
.Main-Box {
width: 100vw;
height: 100vh;
background: linear-gradient(45deg,#F17C58, #E94584, #24AADB , #27DBB1,#FFDC18, #FF3706);
}
<div class='Main-Box'>
<button id="bgb">Click Me!</button>
</div>
#cSharp already gave you a solution to your issue. However to make your entire code shorter and easier you could simply use: classList.toggle() and apply the changes by toggeling a CSS-Class on and off:
document.querySelector('#bgb').addEventListener("click", function() {
document.querySelector('.Main-Box').classList.toggle('class-name');
});
.Main-Box {
width: 100vw;
height: 100vh;
background: linear-gradient(45deg, #F17C58, #E94584, #24AADB, #27DBB1, #FFDC18, #FF3706);
}
.class-name {
background: white;
}
/* for visualisation only */
body {
margin: 0;
}
<div class='Main-Box'>
<button id="bgb">Click Me!</button>
</div>
If it is not necessary, I will not use global variables to control the state.
In addition, you can also create a new class attribute, and you only need to control the class when switching.
Below are examples of both approaches for your reference.
document.querySelector('input[type=button]').onclick = function() {
switchLinearGradientBackground('.main-box', 'linear-gradient');
}
function switchLinearGradientBackground(selector, switchClassName) {
const elems = document.querySelectorAll(selector);
for (let index = 0; index < elems.length; index++) {
elems[index].classList.toggle(switchClassName);
}
}
body {
display: flex;
}
.main-box {
flex-direction: column;
display: flex;
width: 200px;
height: 200px;
}
.linear-gradient {
background: linear-gradient(45deg, #F17C58, #E94584, #24AADB, #27DBB1, #FFDC18, #FF3706) !important;
}
<div class='main-box' />
<input type='button' value="switch background">
document.querySelector('input[type=button]').onclick = function() {
switchLinearGradientBackground('.main-box');
}
function switchLinearGradientBackground(selector) {
const elems = document.querySelectorAll(selector);
const grad = 'linear-gradient(45deg, #F17C58, #E94584, #24AADB, #27DBB1, #FFDC18, #FF3706)';
for (let index = 0; index < elems.length; index++) {
const style = elems[index].style;
style.background = style.background.length > 0 ? '' : grad;
}
}
body {
display: flex;
}
.main-box {
flex-direction: column;
display: flex;
width: 200px;
height: 200px;
}
<div class='main-box' />
<input type='button' value="switch background">

Simple click event not firing, console returns impossible or no error at all

document.addEventListener("load", function()
{
var firstGal = document.querySelector("containsNext");
var nextB = document.querySelector("nondynamic");
nextB.addEventListener('click', function(){ firstGal.style.opacity = 0;});
});
This is the function causing the issues, all else runs fine.
I am just testing something before i go on to final layout idea, and want to test if the nondynamic next button works and animates the pic in containsNext on click. Just animating the opacity for test purposes.
If i try to run this without the onload, i get many reference errors and all kinds of undefined elements. Oddly, codepen even gave me errors on some lines which I have deleted hours ago:-)
Ok, so by adding the on load property, there are no errors thrown, but the code does not run.
Am i overlooking the proverbial elephant in the room here?
Both concerned elements are not dynamically created(unlike most of the page).
Thank you guys for the heads up.
Link to the pen:
http://codepen.io/damianocel/pen/gPggLB
Zefiryn is right, you should use . as the selectors are CSS classes and it is more reliable to add the event listener to the object window. Please, try this:
window.addEventListener( "load", function()
{
var firstGal = document.querySelector( ".containsNext" );
var nextB = document.querySelector( ".nondynamic" );
nextB.addEventListener( 'click', function()
{
firstGal.style.opacity = 0;
} );
} );
Check this link also https://developer.mozilla.org/en-US/docs/Web/Events/load and see the note below the example provided.
Good luck!
My proposal is:
var arrayIndex = ['url("http://www.croatiaweek.com/wp-content/uploads/2013/02/photo_twitter_chris_hadfield1.jpg")','url("http://i.dailymail.co.uk/i/pix/2014/03/07/article-2575552-1C1A7B9400000578-567_964x673.jpg")', 'url("http://www.thegoldenscope.com/wp-content/uploads/2015/10/vicogargano-1a.jpg")'];
window.addEventListener("load", function()
{
var firstGal = document.getElementsByClassName("containsNext");
var nextB = document.getElementsByClassName("nondynamic");
nextB[0].addEventListener('click', function(){
firstGal[0].style.opacity = 0;});
});
var closingButtons = document.getElementsByClassName("closingButton");
var index = 0, length = closingButtons.length;
for ( ; index < length; index++) {
closingButtons[index].addEventListener("click",
function () {
hidePic(this);
}
);
}
function addImageInto(arrayIndex, container) {
var displayArea = document.querySelector('.displayArea');
if (displayArea.querySelector('.' + container.id)) {
return;
}
displayArea.innerHTML = '';
var previous = document.createElement("div");
previous.textContent = "Previous";
previous.style.width = "100px";
previous.style.height = "20px";
previous.style.background = "violet";
previous.className = "prevPic";
displayArea.appendChild(previous);
var span = document.createElement("div");
span.textContent = "Close";
// could also be firstChild.nodeValue = "Some new label text!";
span.style.width = "60px";
span.style.height = "20px";
span.style.background = "red";
span.className = "closingButton";
displayArea.appendChild(span);
var div = document.createElement("div");
div.style.width = "500px";
div.style.height = "200px";
div.style.backgroundImage = arrayIndex;
div.style.backgroundRepeat = "no-repeat";
div.style.backgroundSize = "contain";
div.style.backgroundSize = "100% 100%";
div.style.boxShadow = "3px 3px 4px blue";
div.style.margin = "5px auto";
div.className = "images";
displayArea.appendChild(div);
div.style.opacity = 0;
setTimeout(function() {
div.style.opacity = 1;
}, 500);
span.addEventListener("click", function(event){
event.stopPropagation();
var finalTarget = this.parentNode.getElementsByClassName('images')[0];
var finalTarget4 = this.parentNode.getElementsByClassName('closingButton')[0];
setTimeout(function(){
var obj1 = finalTarget.style;
obj1.height = 0;
obj1.opacity = 0;
// obj1.width = 0;
var obj4 = finalTarget4.style;
obj4.height = 0;
obj4.opacity = 0;
obj4.width = 0;
},1000);
});
}
function createFunctionClickListener(arrayIndex) {
// This returns a listener / callback function.
return function(event) {
var container = event.currentTarget;
addImageInto(arrayIndex, container);
};
}
// Croatia
document.getElementById("newDom").addEventListener("click", createFunctionClickListener(arrayIndex[0]));
// Spain
document.getElementById("newDom2").addEventListener("click",
createFunctionClickListener(arrayIndex[1]));
// Italy
document.getElementById("newDom3").addEventListener("click",
createFunctionClickListener(arrayIndex[2]));
body{width:100%;
height:100%;
background-image: url('http://eoimages.gsfc.nasa.gov/images/imagerecords/55000/55167/earth_lights_lrg.jpg');
background-size:100% 100%;
z-index:-1;
background-repeat:no-repeat;
background-position: right top;
background-attachment: fixed;
}
h2{text-align:center;
color:#fff;
text-shadow:2px 1px 2px silver;}
button{border: #000 solid 1px;
box-shadow:2px 2px 2px blue;
background:transparent;
color:white;
font-size:1em;
font-weight:400;
text-shadow:1px 1px 1px #fff;
padding:2px 7px;}
.images{transition:1s;!important;}
.images:hover{
transform: translate(0px,-30px)scale(1.1);!important;
}
.closingButton{font-size:1em;
color:white;
padding-top:3px;
box-shadow:2px 2px 1px purple;
margin:2px auto;
text-align:center;}
.prevPic{font-size:1em;
color:white;
padding-top:3px;
box-shadow:2px 2px 1px purple;
position:relative;
top:27px;
text-align:center;}
.nondynamic{width:100px;
font-size:1em;
color:white;
padding-top:3px;
box-shadow:2px 2px 1px white;
position:relative;
top:50px;left:70%;text-align:center;cursor:pointer;}
.displayArea{width:500px;
margin:10px auto;}
.containsNext{
border:2px white solid;
width:500px;
height:200px;
z-index:100;position:relative;top:-190px;
transform:rotateX(10deg);
margin:10px auto;
background:url(http://www.pxleyes.com/images/contests/croatia%20beach/fullsize/croatia%20beach_4c51a7c40c71c_hires.jpg);
background-size:100% 100%;}
<h2 id="header">Creating elements with native JS and prototype/inheritance practice</h2>
<div class="nondynamic">Next</div>
<button id="newDom">Croatia</button>
<button id="newDom2">Spain</button>
<button id="newDom3">Italia</button>
<button id="newDom4">Sweden</button>
<button id="newDom31">France</button>
<button id="newDom32">France</button>
<button id="newDom33">France</button>
<button id="newDom34">France</button>
<button id="newDom35">France</button>
<button id="newDom36">France</button>
<button id="newDom37">France</button>
<button id="newDom38">France</button>
<div class="displayArea"></div>
<div class="containsNext"></div>
window.addEventListener works better than document.addEventListener based on
this answer
Also, to select your "nondynamic" css selector you need a dot for the class selector:
var nextB = document.querySelector(".nondynamic");
Finally, querySelector will only return the first element with that class so make sure it's the first one on your page...or provide a unique id for the "Next" element and select based on the id instead like:
<div id="yourIdHere" class="nondynamic">Next</div>
var nextB = document.querySelector("#yourIdHere");

eventlistener javascript problems

I'm trying to learn Javascript and at the moment and I am working on AddEventListener.
What I'm trying to do is to add a new row and so far it works.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
.colorOrange {
background-color: orange;
}
.colorBlue {
background-color: blue;
}
.colorYellow {
background-color: yellow;
}
.colorGray {
background-color: gray;
}
.colorRed {
background-color: red;
}
.colorGreen {
background-color: green;
}
.colorWhite {
background-color: white;
}
#main {
margin: 0 auto;
width: 325px;
text-align: center;
background-color: gray;
}
.row {
width: 300px;
padding: 10px;
border: 1px solid black;
display: block;
}
.hideButton, .mainText, .deleteButton {
margin: 0 auto;
padding: 10px;
border: 1px solid black;
display: inline;
}
.btn {
}
</style>
</head>
<body>
<div id="main">
<div class="AddBtn btn">Add</div>
<input type="text" id="txtBox" name="text till ruta" />
</div>
<script>
var rownr = 0;
function addListeners() {
var addButton = document.getElementsByClassName('AddBtn');
for (var i = 0; i < addButton.length; i++) {
var addBtn = addButton[i];
addBtn.addEventListener('click', function () {
var elBtn = event.srcElement;
var valueBtn = elBtn.textContent;
alert(valueBtn);
hideOrShow();
addRow();
function addRow() {
switch (valueBtn) {
case "Add":
var input = document.getElementById('txtBox').value;
rownr++;
var div = document.createElement('div');
div.className = "row";
document.getElementById("main").appendChild(div);
var div2 = document.createElement('div');
div2.className = "hideButton colorGreen";
var tx = document.createTextNode("<");
div2.appendChild(tx);
div2.addEventListener('click', hideOrShow, false);
div.appendChild(div2);
var div3 = document.createElement("div");
if (input.toLowerCase() == "red") {
div3.className = "mainText colorRed";
}
else if (input.toLowerCase() == "orange") {
div3.className = "mainText colorOrange";
}
else if (input.toLowerCase() == "blue") {
div3.className = "mainText colorBlue";
}
else if (input.toLowerCase() == "yellow") {
div3.className = "mainText colorYellow";
}
else if (input.toLowerCase() == "gray") {
div3.className = "mainText colorGray";
} else {
div3.className = "mainText colorWhite";
}
tx = document.createTextNode(rownr + " " + input);
div3.appendChild(tx);
div.appendChild(div3);
var div4 = document.createElement("div");
div4.className = "deleteButton colorRed";
tx = document.createTextNode("X");
div4.appendChild(tx);
//div4.addEventListener('click', deleBtn, false);
div.appendChild(div4);
var linebreak = document.createElement("br");
div.appendChild(linebreak);
default:
}
}
So far everything works as I want it to do. But when I click on "<" it will go in to this function and find all tags with the hideButton class in it.
The first click it won't find anything, but the second time it will find the "<" value and an alert window will popup and show the value. Here is where I
get lost and can't get it to work. When you click the the third time it will
loop or whatever to call it - anyway it will show the alert window 2 times and
then if you repeat the same click it will do the same thing 3 times and so it goes.
function hideOrShow() {
var hideButton = document.getElementsByClassName('hideButton');
for (var j = 0; j < hideButton.length; j++) {
hideBtn = hideButton[j];
hideBtn.addEventListener('click', function () {
var hideElBtn = event.srcElement;
var valueHideBtn = hideElBtn.textContent;
alert(valueHideBtn);
}, false);
}
}
}, false);
}
}
window.onload = addListeners;
</script>
</body>
</html>
The goal with this exercise is that
when you click add button add the text from the input field and add that text to the new row.
and "<" shall hide the row and change it to ">" to show it again
and "X" shall just delete the row.
But what I need help with is finding the value part that I mentioned above.
Here is my rework of your javascript. I explained my solution in your comment, but it may be a bit more clear if illustrated.
In the addListeners function, I removed the hideOrShow call as it shouldn't be called in the add button.
Next, I removed the for loop in the hideOrShow method as you really are only after the caller. I also removed the addEventListener call in the same method as you already have an event listener on that element, so there's no need to add one again.
var rownr = 0;
function addListeners() {
var addButton = document.getElementsByClassName('AddBtn');
for (var i = 0; i < addButton.length; i++) {
var addBtn = addButton[i];
addBtn.addEventListener('click', function () {
var elBtn = event.srcElement;
var valueBtn = elBtn.textContent;
alert(valueBtn);
//hideOrShow();
addRow();
function addRow() {
switch (valueBtn) {
case "Add":
var input = document.getElementById('txtBox').value;
rownr++;
var div = document.createElement('div');
div.className = "row";
document.getElementById("main").appendChild(div);
var div2 = document.createElement('div');
div2.className = "hideButton colorGreen";
var tx = document.createTextNode("<");
div2.appendChild(tx);
div2.addEventListener('click', hideOrShow, false);
div.appendChild(div2);
var div3 = document.createElement("div");
if (input.toLowerCase() == "red") {
div3.className = "mainText colorRed";
}
else if (input.toLowerCase() == "orange") {
div3.className = "mainText colorOrange";
}
else if (input.toLowerCase() == "blue") {
div3.className = "mainText colorBlue";
}
else if (input.toLowerCase() == "yellow") {
div3.className = "mainText colorYellow";
}
else if (input.toLowerCase() == "gray") {
div3.className = "mainText colorGray";
} else {
div3.className = "mainText colorWhite";
}
tx = document.createTextNode(rownr + " " + input);
div3.appendChild(tx);
div.appendChild(div3);
var div4 = document.createElement("div");
div4.className = "deleteButton colorRed";
tx = document.createTextNode("X");
div4.appendChild(tx);
//div4.addEventListener('click', deleBtn, false);
div.appendChild(div4);
var linebreak = document.createElement("br");
div.appendChild(linebreak);
default:
}
}
function hideOrShow() {
var hideButton = document.getElementsByClassName('hideButton');
var hideElBtn = event.srcElement;
var valueHideBtn = hideElBtn.textContent;
alert(valueHideBtn);
}
}, false);
}
}
window.onload = addListeners;

Set onclick event in loop while creating elements

I don't want to use jQuery, or any other 3rd party library!
Not working proof of concept:
<div id="Wrapper"></div>
<script>
function Build()
{
for (var i = 0 ; i < 10 ; i++)
{
var elem = document.createElement("div");
elem.setAttribute("onclick", "OnClickEvent(" + i + ")");
elem.textContent = "Hi";
document.getElementById("Wrapper").appendChild(elem);
}
}
function OnClickEvent(elementNum)
{
alert("Hi! I am " + elementNum);
}
Build();
</script>
fiddle: http://jsfiddle.net/qyzrQ/
In real life:
I'm dynamically creating a table based on ajax callback, each row contains an image button and another table. This image button should be able to hide or show corresponding inner table.
Frustrating. I was able to solve it myself.
It is enough to add (even before inserrting it into DOM):
element.setAttribute("onclick","functionName("+param+")");
Here is what i wanted to get: http://jsfiddle.net/YhY4Q/6/
And prototype (in case fiddle got deleted):
html:
<section id="Table" class="table">
<header class="row">
<div class="cell">header</div>
</header>
<script>
function ToggleShow(id) {
var elem = document.getElementById(id);
if (elem.classList.contains("invisible")) {
elem.classList.remove("invisible");
} else {
elem.classList.add("invisible");
}
}
</script>
<section id="TableWrapper">
</section>
</section>
javascript:
function ToggleShow(id) {
var elem = document.getElementById(id);
if (elem.classList.contains("invisible")) {
elem.classList.remove("invisible");
} else {
elem.classList.add("invisible");
}
}
function Build() {
var parent = document.getElementById("TableWrapper");
for (var id = 0; id < 10; id++) {
var row = document.createElement("div");
row.appendChild(HeaderRowBuilder(id));
row.appendChild(InnerTableBuilder(id));
parent.appendChild(row);
}
}
function HeaderRowBuilder(id) {
var header = document.createElement("header");
header.classList.add("row");
header.appendChild(HeaderCellBuilder(id));
var strongEle = document.createElement("strong");
strongEle.classList.add("cell");
strongEle.classList.add("cell2");
strongEle.textContent = "Something else";
header.appendChild(strongEle);
return header;
}
function HeaderCellBuilder(id) {
var div = document.createElement("div");
div.classList.add("cell");
div.appendChild(HeaderImageBuilder(id));
return div;
}
function HeaderImageBuilder(id) {
var img = document.createElement("img");
img.setAttribute("alt", "extended");
img.setAttribute("onclick", "ToggleShow('InnerTable_" + id + "')");
return img;
}
function InnerTableBuilder(id) {
var div = document.createElement("div");
div.setAttribute("id", "InnerTable_" + id);
div.textContent = "More rows, I don't care about them right now";
return div;
}
Build();
and css:
.table {
display: table;
}
.table .cell {
display: table-cell;
}
.table .cell2 {
border: 1px solid black;
width: 100%;
}
.table .spacer {
min-width: 40px;
max-width: 40px;
}
.table .cell3 {
min-width: 50px;
max-width: 50px;
}
.table .row {
display: table-row;
}
.invisible {
display: none;
}

Categories

Resources