Javascript find the content of a button (1 content per button) - javascript

I have a button
<button class="collapsible"></button>
whose content is
<div class="content"></div>
On a single page there might be multiple buttons, but every button is linked to a single content, so if there are 7 buttons in a page there are 7 contents too.
The content might be placed far away from its button, in fact between them there might be text, images, paragraphs, lists, or even another button, but in this last case the content of the second button is placed after the content of the first one.
So these are the typical cases
• button is simply followed by text
The <button class="collapsible">sky</button> is blue.
<div class="content">it is above our heads</div>
• button is followed by an image and they are both inside a paragraph
<p>I saw a <button class="collapsible">cat</button> like this <img ...></p>
<div class="content">The cat is the most beautiful thing in the universe</div>
• buttons is outside a ul list while content is inside it
The following is a <button class="collapsible">list</button> structure.
<ul>
<li>first item</li>
<li>second item <div class="content">it contains items</div></li>
<li>third item</li>
</ul>
• 2 buttons followed by their contents
There are 2 <button class="collapsible">buttons</button> in this <button class="collapsible">line</button> as you can see.
First <div class="content">are clickable things</div> and second <div class="content">is a straight thing</div>
Initially I was using the following javascript
( function() {
var list = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < list.length; i++) {
list[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.parentElement.nextElementSibling;
if (content.style.maxHeight){
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
} )();
Notice how this variable is defined
var content = this.parentElement.nextElementSibling
The parentElement was necessary since wordpress usually adds <p> tags. But later I found out that in some cases the <p> tags were not automatically added, and so I edited the JS content variable to be
var content = this.nextElementSibling;
if (!content) {
content = this.parentElement.nextElementSibling;
}
Now I'd like to place images or another button between a certain button and its content, but its difficult to handle all the cases using if's.
Since every button is linked to a unique content, is it possibile to write a JS which given the button number n it finds the content number n?
I was thinking about defining the variables
var coll = document.getElementsByClassName("collapsible");
var cont = document.getElementsByClassName("content");
(so coll.length == cont.length) and then for a given i associate coll[i] with cont[i]. So I edited the definition of content to be
var content = cont[i];
but I found out that this doesn't work since at that point i is equal to coll.length, that is i is out of range. This is the full JS I was thinking about
( function() {
var coll = document.getElementsByClassName("collapsible");
var cont = document.getElementsByClassName("content");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = cont[i];
console.log(content)
if (content.style.maxHeight){
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
} )();

This seems to work in all cases
<script type="text/javascript">
( function() {
coll = document.getElementsByClassName("collapsible");
cont = document.getElementsByClassName("content");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].setAttribute('data-id', 'con' + i);
cont[i].setAttribute('id', 'con' + i);
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = document.getElementById(this.getAttribute('data-id'));
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
} )();
</script>

Related

how can i create div using loop. i found this code in a book but it isnt working

This code is not creating a single div in the webpage which i linked the js below. how can i makes changes in the js or html for the code to be executed as expected
var div,
container = document.getElementById("container");
for (var i = 0; i < 5; i++) {
div = document.createElement("div");
div.onclick = function () {
alert("This is box #" + i);
};
container.appendChild(div);
}
1) To show a div you have to include some text inside divtag
2) You should use let instead of var to get the correct number when user click on div
var div,
container = document.getElementById("container");
for (let i = 0; i < 5; i++) { // change -> let instead of var
div = document.createElement("div");
div.textContent = `div${i}` // change -> add some text
div.onclick = function() {
alert("This is box #" + i);
};
container.appendChild(div);
}
<div id="container"></div>

wkhtmltopdf unnecessary white space in header

I have created pdf with header and footer. I want to hide header and footer from 1st and 2nd page in pdf.
So I have written below javascript code:
<script>
/* page counter */
function subst() {
var vars={};
var x=document.location.search.substring(1).split('&');
for (var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
for (var i in x) {
var y = document.getElementsByClassName(x[i]);
for (var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
if(vars['page'] == 1 || vars['page'] == 2){
// document.getElementById("header_content").innerHTML = "";
document.getElementById("header_content").style.border = '1px solid';
var element = document.getElementById("header_content");
element.classList.add("hidden");
}
}
}
</script>
Contents are hidden but it covers white space.
So how can I remove that white space from 1st and 2nd page?
What does the CSS class 'hidden' do?
You need to set display: none in there.
Sounds like you are using visibility: hidden instead.

Making cards with javascript and html

I am supposed to make 9 cards. Use a for loop to create t.
When it says it is number 1, that should increment by the number that it is in the loop.
Add the number of the loop to a data attribute.
Create a CSS class for the card that gives it the styling of the image above.
Every odd card should have a background color of #52ce90.
The color of the text should change to white.
I have tried, but i cant figure out how to do it.
Here is my code:
var div = document.createElement("div");
var newCard = "test";
var i;
for (let i = 1; i <= 9; i++) {
newCard += "Box number" + i "<br>";
}
<div class="container" id="Container">
<div class="card" id="card">
<div class="card--header">
<h1 class="card--number--text">
Card number
</h1>
</div>
<div class="card--by">
By
</div>
<div class="card--time">
43 minutes ago
</div>
<button class="card--button"> View on site</button>
And how to style in css, what class or id should i use, and how to get the boxes up?
Here you have code that will append card-odd class to odd values. Know you can style it as you wish
let container = document.querySelector('.container');
for (let i = 1; i <= 9; i++) {
let myDiv = document.createElement("div");
if (i%2 === 0) {
myDiv.innerHTML = "<div class=\"card\">"+ i +"</div>"
}
else {
myDiv.innerHTML = "<div class=\"card card-odd\">"+ i +"</div>"
}
container.appendChild(myDiv);
}
here you have a fiddle:
https://jsfiddle.net/06Lnghvw/
Also you can simply style odd and even card using pure CSS. Please read: https://www.w3schools.com/cssref/sel_nth-child.asp
I have created a snippet that match your requirements. See it here:
var container = document.getElementById("container");
for( var i=1;i <=9; i++)
{
var el = document.createElement("div");
el.className ="card";
el.id = "card" + i;
el.innerHTML = "ok";
container.append(el);
}
.card:nth-child(odd) {
background: #52ce90;
color: #fff;
}
<div id="container">
</div>

JS collapse isn't displaying my content correctly

I've been trying to get this to work but sadly I lack the knowledge in JS.
The content gets behind the collapsible div most of the time
is anyone able to help me fix this?
This is my js file :
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight){
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + 50 + "px";
}
});
}
https://codepen.io/FGamerNL/pen/qYJOxx
I think you need set maxHeight for parentElement has "content" class when click to children.
The max-height of your outer <div class="content"></div> is not recalculated, when you toggle one of it’s children.

How can I modify my function to hide the body of the messages as default and to show the body when clicked?

Here is my html with the JS within. The function "toggleMessage()" is the function I am using to hide and show messages when clicked. The problems I am running into include:
Messages showing by default, when they should hide by default (until clicked).
When clicked, all messages show at once - I want only the messages clicked on to show.
The new messages that populate the page every 3 seconds are not affected by the click event - I want them to be effected.
function newMessage() {
// Loop goes through emails and creats divs for subject, date, sender, and body
var i = 0;
while (i < window.geemails.length) {
//email container
var div = document.createElement("div");
//date
var dateField = document.createElement("h1");
dateField.className = "date";
dateField.innerHTML = window.geemails[i].date;
div.appendChild(dateField);
//subject
var subjectField = document.createElement("h1");
subjectField.className = "subject";
subjectField.innerHTML = window.geemails[i].subject;
div.appendChild(subjectField);
//sender
var senderField = document.createElement("h1");
senderField.className = "sender";
senderField.innerHTML = window.geemails[i].sender;
div.appendChild(senderField);
//body
var bodyField = document.createElement("p");
bodyField.className = "body";
bodyField.innerHTML = window.geemails[i].body;
div.appendChild(bodyField);
//Separate message content into containers
document.getElementById("main").appendChild(div);
//inbox counter
document.getElementById('counter').innerHTML = "You have " + document.getElementsByClassName("date").length + " messages";
window.geemails.shift();
}
}
newMessage();
//interval for loading new messages
function addNewMessage() {
setInterval(function() {
window.geemails.push(getNewMessage());
newMessage();
}, 3000);
}
addNewMessage();
//hiding and showing body message upon click
var messageBox = document.getElementsByClassName("subject");
for (var i = 0; i < messageBox.length; i++) {
messageBox[i].addEventListener("click", toggleMessage);
}
function toggleMessage() {
var showMessage = document.getElementsByClassName('body');
for (var i = 0; i < showMessage.length; i++) {
if (showMessage[i].style.display === 'none') {
showMessage[i].style.display = "block";
} else {
showMessage[i].style.display = "none";
}
}
}
You need a class for your messages and possiblt for their bodies.
Suppose you have a message div with a message body like this
<div class="message">
<div class="message-header">
</div>
<div class="message-body" style="display:none;">
</div>
</div>
if you want the body to be hidden by default use css display:none
then in your javascript do
$('.message').click(function(){
$(this).children('.message-body').show();
});

Categories