Accordion inside a form auto submits - javascript

So disclaimer, I already found the answer to this but I'm posting it as a question in case it helps somebody else.
Scenario: Inside a form in the page you have a couple of accordions so that the user can collapse the parts they already looked at. If you follow most examples expanding the accordions will actually auto submit the form, no bueno.
<!DOCTYPE html>
<html>
<head>
<style>
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .accordion:hover {
background-color: #ccc;
}
.panel {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
</style>
</head>
<body>
<h2>Accordion</h2>
<form action="fail" method="post" enctype="multipart/form-data">
<button class="accordion">Section 1</button>
<div class="panel">
<input type="checkbox" name="checkbox1.1">Checkbox 1.1
<br>
<input type="checkbox" name="checkbox1.2">Checkbox 1.2
</div>
<button class="accordion">Section 2</button>
<div class="panel">
<input type="checkbox" name="checkbox2.1">Checkbox 1.1
<br>
<input type="checkbox" name="checkbox2.2">Checkbox 1.2
</div>
<input type="submit" value="Submit">
</form>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
</script>
</body>
</html>

Essentially the buttons for the accordion are being treated as submit buttons even though we already have a submit button. In order to override this behavior simply declare the button type as button:
<button type="button" class="accordion">Section 1</button>
<button type="button" class="accordion">Section 2</button>
This may be obvious to some but given that I rarely deal with web stuff this was a very frustrating side affect to find and work around so I hope it helps somebody else.

Related

HTML collapsible closed by default

I am currently working on a website and am currently up to adding collapsibles.
I am having some difficulty with collapsibles as shown:
body {
align-self: center;
}
h1, p , body > ul, ol{
text-align: center;
align-self: center;
background-color: rgba(255, 255, 255, 0.6);
width: 40%;
margin: 20px 29%;
padding: 5px 3%;
}
h1 {
font-family: 'Press Start 2P';
font-size: 40px;
}
p, ul, ol {
font-family: "Turret Road";
font-size: 20px;
}
.collapsible {
background-color: #eee;
color: #000;
cursor: pointer;
padding: 8px;
width: 90%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
margin: 10px 5%;
}
.active, .collapsible:hover {
background-color: rgba(255, 255, 255, 1);
}
<body>
<button type="button" class="collapsible"><h1>Basic Rundown</h1></button>
<div class="content">
<p>Vaporfest is inspired by internet music genres like vaporwave, future funk and eccojams.</p>
<p>At Vaporfest, several artists will be performing music that will take you back to a better time.</p>
</div>
<button type="button" class="collapsible"><h1>What to bring</h1></button>
<div class="content">
<ol>
<li>Enough clothes for 5 days</li>
<li>Recording equipment (if you want)</li>
<li>Basic toiletries</li>
<li>Anything else you think is neccesary</li>
</ol></div>
<button type="button" class="collapsible"><h1>Security measures</h1></button>
<div class="content">
<p>Attendees will be tested for COVID every day.</p>
<p>You have to be older than 18 to attend. </p>
</div>
<button type="button" class="collapsible"><h1>Rules about camping</h1></button>
<div class="content">
<ol>
<li>Be respectful at all times.</li>
</ol></div>
<button type="button" class="collapsible"><h1>Prohibited items</h1></button>
<div class="content">
<ol>
<li>Cutlery or hard plates</li>
<li>Metal blades</li>
<li>Gas tanks, gas cylinders, jerry cans</li>
<li>Glass</li>
<li>BBQ sets</li>
<li>Unperscribed stimulants</li>
</ol></div>
<button type="button" class="collapsible"><h1>Getting there</h1></button>
<div class="content">
<p>The festival site is roughly 1 hour away from Kansai International Airport.</p>
</div>
<script>
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.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}
</script>
</body>
When the page loads, the collapsibles are open by default, which isn't desired. I want it to be closed by default.
How do I make the collapsibles closed by default when the page is loaded?
Try using JavaScript and Jquery
<body onload=“$("#myModal").modal('hide');”>
add this CSS:
.content {
display: none;
}

In Blogger, Hide/Show Quiz Answers based on button click with javascript

I have a quiz blog/website on blogger. To show the answers of questions I have following html code:
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
And JavaScript like this:
<script type='text/javascript'>
//<![CDATA[
var acc = document.getElementsByClassName("acc");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var pnl = this.nextElementSibling;
if (pnl.style.display === "block") {
pnl.style.display = "none";
} else {
pnl.style.display = "block";
}
});
}
//]]>
</script>
And CSS like this:
.acc {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .acc:hover {
background-color: #ccc;
}
.pnl {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
If some one clicks on all of the buttons, the buttons are acting as toggles rather than, showing one answer, then when the next button is clicked, hiding the previous answer and showing the new one in its place. What needs to be changed to enable this?
Thanks
Remove the buttons.
Add the following over each .pnl
<!-- #ids must be unique so btn* = btn1, btn2, etc -->
<!-- [for] of label must match #id of input -->
<input id='btn*' class="acc" name='acc' type='radio' hidden>
<label for='btn*'>Show Answer</label>
Explination: A label and a form control (ex. <input>, <select>, etc) can be associated with each other if the form control has an #id and the label has a [for] that match. If one gets clicked, checked, etc then the other one does as well.
Add the following CSS:
.acc:checked+label+.pnl {
display: block
}
Explination: If an input is checked then the .pnl that is front of the label that is in front of the input. Note, when a group of radio buttons share a [name] only one may be checked at a time. Also, the radio buttons are hidden so it looks as if the label is the only tag interacting with the user.
.acc {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active,
.acc:hover {
background-color: #ccc;
}
.pnl {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
.acc:checked+label+.pnl {
display: block
}
label {
display: block
}
<input id='btn1' class="acc" name='acc' type='radio' hidden>
<label for='btn1'>Show Answer</label>
<div class="pnl">
<p>Correct Answer</p>
</div>
<input id='btn2' class="acc" name='acc' type='radio' hidden>
<label for='btn2'>Show Answer</label>
<div class="pnl">
<p>Correct Answer</p>
</div>
<input id='btn3' class="acc" name='acc' type='radio' hidden>
<label for='btn3'>Show Answer</label>
<div class="pnl">
<p>Correct Answer</p>
</div>
Try this one by using a forEach.
var acc = document.getElementsByClassName("acc");
let pn1 = document.getElementsByClassName("pnl");
for (let i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
[...acc].forEach((item,index) =>{
if(item == acc[i]){
pn1[index].style.display = "block";
}else{
pn1[index].style.display = "none";
}
})
})
}
.acc {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .acc:hover {
background-color: #ccc;
}
.pnl {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>

How do you put text under Tab header that links with the tab you press? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm new to HTML coding and I want to know how do I put another tab content below the tab header that links to what ever tab I press.
For example, I want to put this A TO B function or B TO A function below the tab header/Tab. I can do this by putting it in between but it doesn't link with the tabs I want it to.
<div id="ATOB" class="tabcontent">
</br></br>
<div id="ATOB_BOX" style="min-width: 500px;max-width: 760px;min-height: 200px;z-index: 999;background-color: #fff;top: 10px;padding: 15px;border-bottom: 1px solid #ccc;"
<div id="ATOB_CONTAINER">
<span id-"ATOB_DESCRIPTION"> Enter the code you want to ATOB </span></br>
<textarea id="ATOB_TEXT" rows= "15" style="width:99%"></textarea></br>
<input type= "button" style="padding: 5px;" id="ATOB_SUBSTRACTEXCESS" value="Remove Javaeval." onclick="ATOB_SUBSTRACTEXCESS()">
<input type= "button" style="padding: 5px;" id="ATOB_ONGOING" value="Change to B" onclick="ATOB_CHANGE()">
<input id="CLEAR_ATOB"style="padding: 5px;" type="button" onclick= "Clear(ATOB_TEXT)" value="Clear text box ">
</div>
<div id="ATOB_result">
<table id="ATOB_TABLE">
<tbody id="ATOB_body"></tbody>
</table>
</div>
<textarea id= "RESULTATOB_TEXT" rows= "15" style="width:50%"></textarea></br>
<input id="ATOB_BUTTON" type="button" onclick= "ATOBCopy()" value="Click to Copy all ">
<input id="CLEAR_BRESULT" type="button" onclick= "Clear(RESULTATOB_TEXT)" value="Clear text box ">
<br>
</div>
</div>
For example look at this pictureExample 1
Example 2
P.S. My friend was trolling me with the derp thing.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {font-family: "Lato", sans-serif;}
.tablink {
background-color: #555;
color: white;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
font-size: 17px;
width: 25%;
}
.tablink:hover {
background-color: #777;
}
/* Style the tab content */
.tabcontent {
color: white;
display: none;
padding: 50px;
text-align: center;
}
#DERP {background-color:red;}
#Paris {background-color:green;}
#Tokyo {background-color:blue;}
#Oslo {background-color:orange;}
</style>
</head>
<body>
<p>Click on the buttons inside the tabbed menu:</p>
<div id="DERP" class="tabcontent">
<h1>DERP</h1>
<p>DERP is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h1>Paris</h1>
<p>Paris is the capital of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h1>Tokyo</h1>
<p>Tokyo is the capital of Japan.</p>
</div>
<div id="Oslo" class="tabcontent">
<h1>Oslo</h1>
<p>Oslo is the capital of Norway.</p>
</div>
<button class="tablink" onclick="Bst('DERP', this, 'red')" id="defaultOpen">London</button>
<button class="tablink" onclick="Bst('Paris', this, 'green')">Paris</button>
<button class="tablink" onclick="Bst('Tokyo', this, 'blue')">Tokyo</button>
<button class="tablink" onclick="Bst('Oslo', this, 'orange')">Oslo</button>
<script>
function Bst(cityName,elmnt,color) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].style.backgroundColor = "";
}
document.getElementById(cityName).style.display = "block";
elmnt.style.backgroundColor = color;
}
// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
</script>
</body>
</html>
You've already created tabs, it means, you should have div-s: containers for tab-content. So, you can just add another container in your div, like this:
<div class="tabcontent"><div style="margin-left: --%;">Text under the tab-button</div>
Your Main Tab-content
</div>
If your tab-button's width is in perсents, for each tab you need to write there margin-left: 0%;, margin-left: 25%;, margin-left: 50%;, margin-left: 75%;
But if your tab-width's are in pixels, you just need to play with pixels, margin-left: 123px;
Margin sets the free field in the specified direction. It can be margin-right, margin-top, margin-bottom. And it's value can be negative: margin-top: -100px - will move the element to top.
In style, you can add position: absolute; and the div will be margined, independent from the other elements.
Saw your code...
Working code
I've added:
.bubu{position: absolute;
background-color: #800000;
margin-top: 100px;
padding: 20px;
}
<div class="bubu" style="margin-left: --%;">TEXT</div>
There is "more correct" way to reach this, but it's much more harder...
You can google: CSS :before and CSS :after

Collapside opening upwards

I am new to coding and I want to have like these panels on the bottom of the page that when pressed it opens some menu with buttons and stuff and I think the best choice would be collapside. But after reading the W3schools tutorial I didn´t find any reference on how to make them open pointing up. I hope it just don´t move the whole page and just opens a clickable window. If not I would like to know which other thing to use for that. Here is the code from W3schools
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 + "px";
}
});
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.active, .collapsible:hover {
background-color: #555;
}
.collapsible:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "\2212";
}
.content {
padding: 0 18px;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
background-color: #f1f1f1;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>Animated Collapsibles</h2>
<p>A Collapsible:</p>
<button class="collapsible">Open Collapsible</button>
<div class="content">
<p>upper one (only one is enought).</p>
</div>
<p>Collapsible Set:</p>
<button class="collapsible">Open Section 1</button>
<div class="content">
<p>1.</p>
</div>
<button class="collapsible">Open Section 2</button>
<div class="content">
<p>2.</p>
</div>
<button class="collapsible">Open Section 3</button>
<div class="content">
<p>3.</p>
</div>
</body>
</html>
You should set your content variable to previousElementSibling to get the element before.
var content = this.previousElementSibling;
Then, swap the order of the collapse button and content like so:
<div class="content">
<p>upper one (only one is enought).</p>
</div>
<button class="collapsible">Open Collapsible</button>
JSFiddle: https://jsfiddle.net/gf72yw8q/
The reason they open downwards is because the html structure and css is indicating for it to be that way, for example:
<p>A Collapsible:</p>
<button class="collapsible">Open Collapsible</button>
<div class="content">
<p>upper one (only one is enought).</p>
</div>
The <p> with the text "upper one" (in this case your content) appears after open <button>.
If you want it to open upwards, the content would thus need to appear (in the html) before the button (to avoid using additional css styles to reproduce the intended effect).
for example:
<ul class="magic-content">
<li>an example list item</li>
<li>another example item</li>
</ul>
<a class="magic-button" href="#">my magic button</a>
to make this work, you would then need something like this inside your js file. For the purpose of this example, I am using jquery:
//FILTERS RESET
$('.magic-button').click(function(event) {
event.preventDefault;
$('.magic-content').toggleClass('on');
});
And your css would need to have something such as:
.magic-content {display:none;}
.magic-content.on {display:block;}
So that the toggling of the class 'on' is what triggers the showing/hiding of the content.
ALTERNATIVELY, the example you are referring to can be found here:
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_toggle_class_crossbrowser
And all you need to do in their example to reverse the order is change the order of the html elements:
<div id="myDIV">
This is a DIV element.
</div>
<button onclick="myFunction()">Try it</button>
The button after the content. I hope this helps.
G

not open second menu of accordion menu

I am using this accordion menu.
JavaScript:
var acc = document.getElementsByClassName("accordion"), i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
}
Html:
<!DOCTYPE html>
<html>
<head>
<style>
button.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
button.accordion:after {
content: '\02795';
font-size: 13px;
color: #777;
float: right;
margin-left: 5px;
}
button.accordion.active:after {
content: "\2796";
}
div.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: 0.6s ease-in-out;
opacity: 0;
}
div.panel.show {
opacity: 1;
max-height: 500px;
}
</style>
</head>
<body>
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</p>
<button class="accordion">Section 3</button>
<div id="foo" class="panel">
<p>
<button class="accordion">Section 3</button>
<div id="foo" class="panel">
<p></p>
</div>
</p>
</div>
</body>
</html>
I need to use the second menu in section 3. I add in this accordion menu to another accordion menu but it does not open. Any ideas why? How can I solve this problem?
In the following HTML structure, I'm replacing P tag with DIV tag. The P element cannot contain block level elements like DIV.
Ref: How can I put DIV in P? and P tag
<body>
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</p>
<button class="accordion">Section 3</button>
<div id="foo" class="panel">
<div>
<button class="accordion">Section 3</button>
<div id="foo" class="panel">
<div>
test
</div>
</div>
</div>
</div>
</body>
The click event didn't work for your original HTML structure, as the browser altered the DOM elements and DIV element was removed from inside of P tag(explained the reason with the above reference links). This DOM change has resulted in an issue while we retrieve nextElementSibling.
Accept this answer if it solves your issue.

Categories

Resources