First accordion active - javascript

I have this html accordion code:
<div class="accordion_container">
<div class="container">
<div class="accordion">
<button class="header">
Úvod
<i class="icon"></i>
</button>
<div class="body">
Lorem Ipsum
</div>
</div>
<div class="accordion">
<button class="header">
Závěr
<i class="icon"></i>
</button>
<div class="body">
Lorem Ipsum
</div>
</div>
</div>
and this script:
<script>
let accordion_btns = document.querySelectorAll('.accordion_container .accordion .header'),
accordion_bodys = document.querySelectorAll('.accordion_container .accordion .body');
if(accordion_btns && accordion_bodys)
{
accordion_btns = Array.isArray(accordion_btns) ? accordion_btns : Object.values(accordion_btns);
accordion_btns.forEach(accordion_btn=>{
accordion_btn.addEventListener('click', function(){
process_accordion(this);
});
});
function process_accordion(x) {
set_height_0();
let next_sibling = x.nextElementSibling;
if(next_sibling.offsetHeight>0)
{
next_sibling.style.height = '0px';
x.closest('.accordion').classList.remove('active');
} else {
next_sibling.style.height = next_sibling.scrollHeight+30+'px';
x.closest('.accordion').classList.add('active');
}
}
function set_height_0() {
accordion_bodys = Array.isArray(accordion_bodys) ? accordion_bodys : Object.values(accordion_bodys);
accordion_bodys.forEach(accordion_body=>{
accordion_body.style.height = '0px';
accordion_body.closest('.accordion').classList.remove('active');
});
}
}
</script>
I was trying from all my strengh and using all my beginner brain power, but I can't figure out, how to modify this code so the first accordion is active when I load the page. I tried adding the active class to into the html but the only part of the accordion is open when i load the page.

The best way to do this is using the details / summary, where you do not need to use javascript. See MDN documentation here.
You can then assign an attribute open="true" to the that you want
<div class="accordion_container">
<div class="container">
<details class="accordion" open="true">
<summary class="header">
Úvod
<i class="icon"></i>
</summary>
<div class="body">
Lorem Ipsum
</div>
</details
</div>
<div class="container">
<details class="accordion">
<summary class="header">
Závěr
<i class="icon"></i>
</summary>
<div class="body">
Lorem Ipsum
</div>
</details
</div>
</div>

Related

Click event won't process

I am trying to do a question page where when you click on the plus at the end of a question the answer appears. I have the answer hidden and try adding class show-text with display of block instead of none and switching the plus button to a minus, however on click it does nothing! any help would be greatly appreciated!
const questions2 = document.querySelectorAll(".question")
questions2.forEach(function(info) {
const btn = info.querySelector(".question-btn")
btn.addEventListener("click", function() {
questions2.forEach(function(item) {
if (item !== info) {
item.classList.remove("show-text")
}
})
info.classList.toggle("show-text")
})
})
.question-text {
display: none
}
.show-text .question-text {
display: block
}
.minus-icon {
display: none
}
.show-text .minus-icon {
display: inline
}
.show-text .plus-icon {
display: none
}
<section class="questions">
<!-- Title -->
<div class="title">
<h2 class="heading">Questions</h2>
<div class="underline"></div>
</div>
<!-- Questions -->
<div class="section-center">
<article class="question">
<div class="question-title">
<p>Question here</p>
<button type="button" class="question-btn">
<span class="plus-icon"><i class="far fa-plus-square"></i></span>
<span class="minus-icon"><i class="far fa-minus-square"></i></span>
</button>
</div>
<div class="question-text">
<p>Answer here</p>
</div>
</article>
</div>
</section>
You could try letting your button keeps track of which answer it controls with the aria-controls attribute and use the aria-hidden attribute to toggle the display property of the answer.
const questions = document.querySelectorAll(".question");
questions.forEach(question => {
const questionBtn = question.querySelector("button");
const btnControls = questionBtn.getAttribute("aria-controls");
const answer = document.getElementById(btnControls);
questionBtn.addEventListener("click", () => {
if(answer.getAttribute("aria-hidden") == "true") {
answer.setAttribute("aria-hidden", "false")
} else {
answer.setAttribute("aria-hidden", "true")
}
})
})
div[aria-hidden="true"] {
display: none;
}
<section class="questions">
<!-- Title -->
<div class="title">
<h2 class="heading">Questions</h2>
<div class="underline"></div>
</div>
<!-- Questions -->
<div class="section-center">
<article class="question">
<div class="question-title">
<p>Question here</p>
<button type="button" class="question-btn" aria-controls="answer1">
<span class="plus-icon"><i class="far fa-plus-square"></i></span>
<span class="minus-icon"><i class="far fa-minus-square"></i></span>
</button>
</div>
<div id="answer1" class="question-text" aria-hidden="true">
<p>Answer here</p>
</div>
</article>
</div>
</section>

Change "selected" on scroll in page

I've been trying to get the automatic update on my navbar but i cant get it to work.
Here is my code: http://pastebin.com/YTHaBD0i
<div id="header">
<ul class="nav-list">
<li class="download selected">Download</li>
<li class="features">Features</li>
<li class="method">Method</li>
<li class="purchase">Purchase</li>
</ul>
</div>
<div id="footer">yey productions © 2016</div>
<div id="fullpage">
<div class="section " id="section0">
<div class="intro">
<h1>Download</h1>
<p>Lorem Ipsum</p>
</div>
</div>
<div class="section" id="section1">
<div class="slide" id="slide1">
<div class="intro">
<h1>Features</h1>
<p>Cheese.</p>
</div>
</div>
<div class="slide" id="slide2">
<h1>Cheese2</h1>
</div>
</div>
<div class="section" id="section2">
<div class="intro">
<h1>Yey</h1>
</div>
</div>
<div class="section" id="section3">
<div class="intro">
<h1>Yey2</h1>
</div>
</div>
</div>
Help would be much appreciated!
Greetz,
Assuming you are using jQuery, you will need a function that fires every time you scroll.
From there, you need to detect which elements are in view.
Once you know which elements are in view, clear any currently active elements with the .selected class, then choose which one you want to be .selected and add the .selected class.
Edit for more detail:
Below is a pure JavaScript solution, which I found here. This should be close to a drop-in solution!:
(function() {
'use strict';
var section = document.querySelectorAll(".section");
var sections = {};
var i = 0;
Array.prototype.forEach.call(section, function(e) {
sections[e.id] = e.offsetTop;
});
window.onscroll = function() {
var scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
for (i in sections) {
if (sections[i] <= scrollPosition) {
document.querySelector('.selected').setAttribute('class', ' ');
document.querySelector('a[href*=' + i + ']').setAttribute('class', 'selected');
}
}
};
})();

How To Hide And Display Multiple Divs using JavaScript

How would I go about hiding and showing multiple divs using JavaScript? I don't want to use JQuery. I can make it work for hiding and showing one div but not multiple divs. The problem originates because I'm using PHP to display multiple records. These records are included in divs which have the same ID.
document.getElementById( 'history-slider' ).addEventListener( 'click', function() {
document.getElementById('edit-slider').style.display = 'block';
document.getElementById('history-slider').style.display = 'none';
}, false );
document.getElementById( 'edit-slider' ).addEventListener( 'click', function() {
document.getElementById('history-slider').style.display = 'block';
document..getElementById('edit-slider').style.display = 'none';
}, false );
.edit-slider {
display: none;
}
<div class="panel-body panel-strip" id="history-slider">
<h3>Title</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p>
<img src="img/time_icon.png" class="time-icon"> <span class="hour-text">4.00 hrs</span>
</p>
</div>
<hr class="calendar-divider">
<div class="panel-body panel-strip edit-slider">
<div class="row pull-right">
<a href="add.php">
<div class="col-xs-4 delete-panel">
<img src="img/delete_icon.png" class="edit-images center-block"><span class="text-center edit-texts">Delete</span>
</div>
</a>
<a href="http://google.com/">
<div class="col-xs-4 edit-panel">
<img src="img/edit_icon.png" class="edit-images center-block"><span class="text-center edit-texts edit-text">Edit</span>
</div>
</a>
<a href="http://google.com/">
<div class="col-xs-4 record-panel">
<img src="img/record_icon.png" class="edit-images center-block"><span class="text-center edit-texts">Record</span>
</div>
</a>
</div>
</div>
HTML;
<div class="panel-body panel-strip" id="history-slider">
<h3>Title</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p>
<img src="img/time_icon.png" class="time-icon"> <span class="hour-text">4.00 hrs</span>
</p>
</div>
<hr class="calendar-divider">
<div class="panel-body panel-strip edit-slider">
<div class="row pull-right">
<a href="add.php">
<div class="col-xs-4 delete-panel">
<img src="img/delete_icon.png" class="edit-images center-block"><span class="text-center edit-texts">Delete</span>
</div>
</a>
<a href="http://google.com/">
<div class="col-xs-4 edit-panel">
<img src="img/edit_icon.png" class="edit-images center-block"><span class="text-center edit-texts edit-text">Edit</span>
</div>
</a>
<a href="http://google.com/">
<div class="col-xs-4 record-panel">
<img src="img/record_icon.png" class="edit-images center-block"><span class="text-center edit-texts">Record</span>
</div>
</a>
</div>
</div>
JavaScript;
document.getElementById( 'history-slider' ).addEventListener( 'click', function() {
document.getElementById('edit-slider').style.display = 'block';
document.getElementById('history-slider').style.display = 'none';
}, false );
document.getElementById( 'edit-slider' ).addEventListener( 'click', function() {
document.getElementById('history-slider').style.display = 'block';
document..getElementById('edit-slider').style.display = 'none';
}, false );
I have also set in the CSS to hide the "edit-slider" div on page load.
.edit-slider {
display: none;
}
The HTML is echoed out in a loop for every record in the database. Information is also added in replace of the placeholder text.
How should I best go about making it so that if a div if clicked it is hidden and the corresponding div is shown in it's place?
I was thinking about doing something about individually giving the divs separate ID's in PHP and than passing those ID's to JavaScript and creating some sort of a loop? My knowledge of JavaScript isn't massive so I don't really know how easy or difficult this method would be. Or is there a much easier method?
This is my first stack overflow post,so sorry if I'm doing anything wrong or missed something.
If you use classes instead of IDs you can use document.QuerySelectorAll() to get all the divs with that class and then show or hide as necessary.
Something like below would hide all divs with an edit-slider class and reveal (assuming they were already hidden) all divs with a history-slider class.
(function() {
var editSliders = document.querySelectorAll('div.edit-slider');
for(var i=0;i<editSliders.length;i++){
editSliders[i].style.display = 'none';
}
var historySliders = document.querySelectorAll('div.history-slider');
for(var i=0;i<historySliders.length;i++){
historySliders[i].style.display = 'block';
}
})();
First, consider using class instead of id to set multiple elements with the same attribute and value. Then, use the following script:
<script type="text/javascript">
document.querySelectorAll('div.history-slider').forEach(item => {
item.addEventListener("click", myFunction);
});
function myFunction() {
this.hide;
}
</script>

JS Accordion open first tab by default

I want to open first tab by default on my accordion. I have been trying different solutions, but nothing worked for me.
Here is my JS and HTML:
$('.accordion').each(function () {
var $accordian = $(this);
$accordian.find('.accordion-head').on('click', function () {
$(this).parent().find(".accordion-head").removeClass('open close');
$(this).removeClass('open').addClass('close');
$accordian.find('.accordion-body').slideUp();
if (!$(this).next().is(':visible')) {
$(this).removeClass('close').addClass('open');
$(this).next().slideDown();
}
});
});
<div class="accordion">
<div class="accordion-head">
Title here <div class="arrow down"></div>
</div>
<div class="accordion-body">
copy goes here
</div>
<div class="accordion-head">
Title here <div class="arrow down"></div>
</div>
<div class="accordion-body">
copy goes here
</div>
<div class="accordion-head">
Title here <div class="arrow down"></div>
</div>
<div class="accordion-body">
copy goes here
</div>
</div>
Please help.

Generate link based on data attributes

I am trying to write a little jQuery script that checks a set of div's to see if they have a data-name attribute. For the ones that have a data-name, it will create a link. The href of that link should be the name of the data-value plus contain the file extension (eg. .txt).
Everything seems to work OK except when I try to add the data value onto the link. The ultimate result of this script is to output something like this for each of those div's:
<p class="data-link">Edit
Below is my script. I have identified that area that I am having issue with.
var dataNameWrappers = $("div#desktopSidebar div[data-name]");
dataNameWrappers.each(function() {
var dataNameWrappers_action = "" + $(this).attr("data-name");
$(this).prepend("<p class='edit-link'><a>Edit</a></p>");
var dataNameWrapperEditLink = $("div#desktopSidebar p.edit-link a");
dataNameWrapperEditLink.each(function() {
$(this).attr('href', <<stuck_here>>);
});
});
Any help will be great.
Thanks
As requested, here is my sidebar HTMl structure
<div id="desktopSidebar">
<div class="sidebar userbox">
<h3 class="sidebarheader"> Welcome {{username}}}</h3>
</div>
<div data-name="social_media_sitewide" class="sidebar socialmedia">
<h3 class="sidebarheader">Follow Tennis-Chat</h3>
</div>
<div data-name="site_promotions" class="sidebar promotions">
<h3 class="sidebarheader">Current Promotions</h3>
</div>
<div data-name="livescores" class="sidebar Livescores">
<h3 class="sidebarheader">Live Scores</h3>
</div>
<div class="sidebar tournaments">
<h3 class="sidebarheader">Tournaments</h3>
</div>
<div data-name="featured-profiles" class="sidebar profiles">
<h3 class="sidebarheader">Today's Profile: {{featured_profile_name}}</h3>
</div>
<div data-name="side_advertisment" class="sidebar Advertisement">
<h3 class="sidebarheader">Advertisement</h3>
</div>
<div class="sidebar Headlines">
<h3 class="sidebarheader">Tennis-Chat Headlines</h3>
</div>
<div class="sidebar mostrecent" id="mostRecentTopics">
<h3 class="sidebarheader">Most Recent Posts</h3>
</div>
</div>
I don't know why you are using a second loop to add the HREFs when you already have everything you need.
Working fiddle here: http://jsfiddle.net/Q4j8S/.
HTML:
<div id="desktopSidebar">
<div class="sidebar userbox">
<h3 class="sidebarheader"> Welcome {{username}}}</h3>
</div>
<div data-name="social_media_sitewide" class="sidebar socialmedia">
<h3 class="sidebarheader">Follow Tennis-Chat</h3>
</div>
<div data-name="site_promotions" class="sidebar promotions">
<h3 class="sidebarheader">Current Promotions</h3>
</div>
<div data-name="livescores" class="sidebar Livescores">
<h3 class="sidebarheader">Live Scores</h3>
</div>
<div class="sidebar tournaments">
<h3 class="sidebarheader">Tournaments</h3>
</div>
<div data-name="featured-profiles" class="sidebar profiles">
<h3 class="sidebarheader">Today's Profile: {{featured_profile_name}}</h3>
</div>
<div data-name="side_advertisment" class="sidebar Advertisement">
<h3 class="sidebarheader">Advertisement</h3>
</div>
<div class="sidebar Headlines">
<h3 class="sidebarheader">Tennis-Chat Headlines</h3>
</div>
<div class="sidebar mostrecent" id="mostRecentTopics">
<h3 class="sidebarheader">Most Recent Posts</h3>
</div>
</div>
JavaScript:
var dataNameWrappers = $("div#desktopSidebar div[data-name]");
dataNameWrappers.each(function() {
var dataNameWrappers_action = $(this).attr("data-name");
console.log('data-name ' + dataNameWrappers_action);
$(this).prepend('<p class="edit-link">Edit</p>');
/* Don't need this
var dataNameWrapperEditLink = $("div#desktopSidebar p.edit-link a");
dataNameWrapperEditLink.each(function() {
$(this).attr('href', dataNameWrappers_action);
});
*/
});
Instead of iterating through the a tags after you do the prepend, it may be better to make the HTML fragment with the desired href attribute.
Here is the code that accomplishes that:
$('#desktopSidebar .sidebar[data-name]').each(function(index, el){
var href = $(el).attr('data-name') + ".txt";
$(el).prepend('<p class="edit-link">Edit');
});

Categories

Resources