Jquery Open Accordion based on URL anchor hash - javascript

I have a FAQ accordion.
Each question has a class name of q with id of q1 or q2 or q3.
Each answer has a class name of a.
When the url has a anchor tag /faq#q2, I want the q2 to be triggered. I have the below code but its the not working.
I think the line that caused it not working is: if (hash) $(.q[id$="+hash+"]).trigger('click'); but i can't figure out whats wrong.
$(document).ready(function($) {
$(".a").hide().first().show();
$(".q:first").addClass("active");
$('#accordion').find('.q').click(function(){
//Expand or collapse this panel
$(this).next().slideToggle('fast');
//Hide the other panels
$(".a").not($(this).next()).slideUp('fast');
//Find anchor hash and open
var hash = $.trim( window.location.hash );
if (hash) $(.q[id$="+hash+"]).trigger('click');
});
});
.q {cursor: pointer;}
.a {display: none;}
.q.active + .accordion-content {
display: block;
}
<div id="accordion">
<h4 class="q" id="q1">Accordion 1</h4>
<div class="a">
<p>Cras malesuada ultrices augue Open Accordion 2 molestie risus.</p>
</div>
<h4 class="q" id="q2">Accordion 2</h4>
<div class="a">
<p>Lorem ipsum dolor sit amet mauris eu turpis.</p>
</div>
<h4 class="q" id="q3">Accordion 3</h4>
<div class="a">
<p>Vivamus facilisisnibh scelerisque laoreet.</p>
</div>
</div>

First of all - you've lost single or double quotes with your jQuery selector. And if I understand correctly - you want something like this?
if (hash) {
var element = $(hash);
if (element.length) {
element.trigger('click');
}
}
Update (http://jsfiddle.net/6hzby0aa/):
// Hide all panels
$(".a").hide();
// Show first panel by default
$(".q:eq(0)").next(".a").show();
// Get hash from query string. You can put there "#q1", "#q2" or something else for test
var hash = window.location.hash;
if (hash) {
// Get panel header element
var requestedPanel = $(hash);
if (requestedPanel.length) {
// Hide all panels
$(".a").hide();
// Show requested panel
requestedPanel.next(".a").show();
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="accordion">
<h4 class="q" id="q1">Accordion 1</h4>
<div class="a">
<p>Cras malesuada ultrices augue Open Accordion 2 molestie risus.</p>
</div>
<h4 class="q" id="q2">Accordion 2</h4>
<div class="a">
<p>Lorem ipsum dolor sit amet mauris eu turpis.</p>
</div>
<h4 class="q" id="q3">Accordion 3</h4>
<div class="a">
<p>Vivamus facilisisnibh scelerisque laoreet.</p>
</div>
</div>

This is my final Code. Thanks to #Andrew Orlov
<script type="text/javascript">
$(document).ready(function($) {
// Hide all panels
$(".a").hide();
// Show first panel by default
$(".q:eq(0)").next(".a").show();
$(".q:first").addClass("active");
// Get hash from query string
var hash = window.location.hash;
if (hash) {
// Get panel header element
var requestedPanel = $(hash);
if (requestedPanel.length) {
// Hide all panels
$(".a").hide();
$('.q').removeClass("active"); // remove active
// Show requested panel
requestedPanel.next(".a").show();
requestedPanel.addClass("active"); //add active
}
};
$('body').find('.q').click(function() {
//Expand or collapse this panel
$(this).next().slideToggle('600');
$('.q').removeClass("active"); // remove active
$(this).addClass("active"); // add active
//Hide the other panels
$(".a").not($(this).next()).slideUp('fast');
});
});
</script>

Related

how can I change child node css?

I am trying to enable view / hide feature in my faq questions, but however at the moment to trying to access to my child answers_body with children I got an error . children is not a function, how can I properly access to answers_body in order to change display:none to display:block
<section class="faqs">
<div class="accordion row">
<div class="__block col-lg-7 mx-auto py-3">
<div class="row justify-content-between align-items-start">
<div class="col-11">
<h3 class="__question">
demo
</h3>
</div>
<div class="col-1">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="12"><path fill="none" stroke="#5267DF" stroke-width="3" d="M1 1l8 8 8-8" /></svg>
</div>
</div>
<div class="answers_body"> I want to access to this node in order to display it
<div class="col">
<p class="answer">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce tincidunt justo eget ultricies fringilla. Phasellus blandit ipsum quis quam ornare mattis.
</p>
</div>
</div>
</div>
</section>
$('.__question').click(function(){
var $parent = $(this);
console.log($patern[0].InnerText)
});
If you are trying to do a toggle effect for your faq, then you can try the following.
$('.__question').click(function() {
var parent = $(this).parents('.accordion.row');
if (parent.find('.answers_body').hasClass('answers-active')) {
parent.find('.answers_body').removeClass('answers-active');
} else {
parent.find('.answers_body').addClass('answers-active');
}
});
Here you need to find the parent that is common to both the element you are clicking and the element you need show. Then using .find() method you can target the element and show. Refer the fiddle
UPDATE
Since you said this is not working, I think the parent class that is used for all faq is wrong. If you can update the code, I can help with that. Else you can use the following code.
$('.__question').click(function() {
var parent = $(this).closest('.row').siblings('.answers_body');
if (parent.hasClass('answers-active')) {
parent.removeClass('answers-active');
} else {
parent.addClass('answers-active');
}
});

I have 3 divs each with it's own topic, and now I would like for each div to open its modal

So far I manage to open one modal by clicking on any of the divs. How can I have one modal for one div element, that is I would like when I click on services to open services modal, and when I click on about to open about modal...and so on..I also have to close every modal when one is opend...I dont know how to connect each div with it's own modal. This is the code I have...
<div class="section">
<div class="container">
<div class="row">
<div class="col-md-4 sector">
<h3>Services</h3>
<i class="fa fa-gear"></i>
<div class="over">
<span class="tooltiptext">Show more...</span>
</div>
</div>
<div class="col-md-4 sector">
<h3>About me</h3>
<i class="fa fa-address-card-o"></i>
<div class="over">
<span class="tooltiptext">Show more...</span>
</div>
</div>
<div class="col-md-4 sector">
<h3>Contact</h3>
<i class="fa fa-phone"></i>
<div class="over">
<span class="tooltiptext">Show more...</span>
</div>
</div>
</div>
</div>
</div>
<div class="modal-container" id="myMod">
<div class="modal-content">
<span class="close">&times</span>
<h1>Heading</h1>
<p>Some text goes in here...</p>
</div>
</div>
<div class="showcase">
<div class="container">
<h1>Got Ideas?</h1>
<p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sed sem rhoncus urna iaculis faucibus. Pellentesque ultrices nibh ac imperdiet tincidunt. Donec hendrerit velit eros</p>
Read More
</div>
</div>
<script type="text/javascript">
// Get the button that opens the modal
var myOver = document.getElementsByClassName('over');
// Get modal to pass it to function
var modal = document.getElementById('myMod');
// get closing button
var span = document.getElementsByClassName('close')[0];
// Function to open the modal
for(var i = 0; i<myOver.length; i++){
myOver[i].addEventListener('click', function(){
modal.style.display = 'block';
});
}
// When the user clicks on <span> (x), close the modal
span.onclick = function(){
modal.style.display='none';
}
</script>
You could use a similar naming scheme and find the right text simply by by appending a suffix to the object that was clicked on's id, for instance have each span element have an id corresponding to the modal they go with. For instance contact then have the click event listener be
function(e) { //e is the event object event
document.getElementById(e.target.id + "-modal").style.display = 'block'
}
now id the contact modal as 'contact-modal' and it should find it easily
As for closing each element, just iterate through all elements with the class modal-contain and set their display to none before opening the
new one

Slide Toggle Won't Activate On Class

I looked up many questions on this topic and there are similar answers that should work, but it's not working for me. I admit DOM traversal is not my strong point, so if you have a solution and can give some context it would really help me understand why the other solutions weren't working.
I have a div with a button and on a button click (this button only appears on mobile) it should slide down only the current div content. I can get this to work, but the issue is it opens up ALL the divs content. I cannot however get it to only open the specific card even using solutions such as $(this), $(next), $(prev) or $(find).
The code I am posting below does not open it at all, and I am using this version of the code because it is most similar to answers on Stack Overflow.
$(document).ready(function(){
$('.mobile-icon').on('click', function(){
event.preventDefault();
$(this).next().find('.card-bottom').slideToggle();
console.log('hi there'); //this does print
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- FIRST CARD -->
<div class="card">
<div class="card-top">
<h1 class="card-title">Headline</h1>
<span class="glyphicon glyphicon-plus"></span>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</p>
</div>
<!-- END CARD-TOP -->
<div class="card-bottom">
<p>Content to be toggled</p>
</div>
<!-- END CARD BOTTOM -->
</div>
<!-- END CARD -->
<!-- SECOND CARD -->
<div class="card">
<div class="card-top">
<h1 class="card-title">Headline</h1>
<span class="glyphicon glyphicon-plus"></span>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</p>
</div>
<!-- END CARD-TOP -->
<div class="card-bottom">
<p>Content to be toggled</p>
</div>
<!-- END CARD BOTTOM -->
</div>
<!-- END CARD -->
The main issue is how you're using jQuery's .next() and .find(). Since $(this) is the <a> tag, .next(), which selects the next sibling, is the <p> tag. Then calling .find() on the <p> tag would check through all its descendants, for which there are none.
Therefore you need to select the parent of both the 'card-top' and 'card-bottom' divs before you traverse down with .find().
For example:
$(document).ready(function(){
$('.mobile-icon').on('click', function(event){
event.preventDefault();
$(this).parent().parent().find('.card-bottom').slideToggle();
});
});
The first call to .parent() will be the parent of the <a> tag, which is the 'card-top' div, and the .parent() of that will be the 'card' div. Then calling .find() will work.
http://www.bootply.com/UMwXaOILHv
Missing the closing " on class="card>
Add event to function() so it's function(event)
If you don't need to link anywhere use a div instead of an a tag and you won't need preventDefault.
$('.mobile-icon').on('click', function(event) {
event.preventDefault();
$(this).closest('.card').find('.card-bottom').slideToggle();
// .closest finds the nearest .card ancestor (it goes up)
// .find then finds .card-bottom within the closest .card
});
.mobile-icon {
background-color: black;
width: 100px; height: 40px;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- FIRST CARD -->
<div class="card">
<div class="card-top">
<h1 class="card-title">Headline</h1>
<div class="mobile-icon">click me</div>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</p>
</div>
<!-- END CARD-TOP -->
<div class="card-bottom">
<p>Content to be toggled</p>
</div>
<!-- END CARD BOTTOM -->
</div>
<!-- END CARD -->
<!-- SECOND CARD -->
<div class="card">
<div class="card-top">
<h1 class="card-title">Headline</h1>
click me
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</p>
</div>
<!-- END CARD-TOP -->
<div class="card-bottom">
<p>Content to be toggled</p>
</div>
<!-- END CARD BOTTOM -->
</div>
<!-- END CARD -->
fiddle
https://jsfiddle.net/Hastig/m2zaLfnz/

jquery - collapse a panel based on document width

I would like to shrink a panel if the document width is < 514. The script I have that is NOT working is:
jQuery(document).ready(function($){
if ($(document).width() < 514) {
if (!$('.panel-heading').hasClass('panel-collapsed')) {
// collapse the panel
$(this).parents('.panel').find('.panel-body').slideUp();
$(this).addClass('panel-collapsed');
$(this).find('i').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
}
};
});
and the script which is working and allows the user to manually collapse/expand the panel:
jQuery(function ($) {
$('.panel-heading span.clickable').on("click", function (e) {
if ($(this).hasClass('panel-collapsed')) {
// expand the panel
$(this).parents('.panel').find('.panel-body').slideDown();
$(this).removeClass('panel-collapsed');
$(this).find('i').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-up');
}
else {
// collapse the panel
$(this).parents('.panel').find('.panel-body').slideUp();
$(this).addClass('panel-collapsed');
$(this).find('i').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
}
});
});
and the HTML:
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Panel 1</h3>
<span class="pull-right clickable"><i class="glyphicon glyphicon-chevron-up"></i></span>
</div>
<div class="panel-body"> Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae.
</div>
</div>
</div>
Thanks,
Justin.
You should replace the this reference fot the selector you are using for the click event.
jQuery(document).ready(function($){
if ($(document).width() < 514) {
var tar = $('.panel-heading span.clickable');
if (!$('.panel-heading').hasClass('panel-collapsed')) {
// collapse the panel
tar.parents('.panel').find('.panel-body').slideUp();
tar.addClass('panel-collapsed');
tar.find('i').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
}
};
});

Auto-generated list-group-items not responding to active class

I have one div with bootstrap's class list-group and its populated with the basic example Bootstrap provides, and I have another one which I want to populate with list-group-items obtained from ajax get request. The populate is being right, but when trying to switch between the active element it doesn't switch the active element.
The first div (example of boostrap) switch the active element correctly, but the second div (my own) doesn't.
Here is the HTML:
<button id="boton1">TEST</button>
<div class="list-group col-md-3">
<a href="#" class="list-group-item active">
Cras justo odio
</a>
Dapibus ac facilisis in
Morbi leo risus
Porta ac consectetur ac
Vestibulum at eros
</div>
<div class="panel panel-default col-md-3">
<div class="panel-heading">Geolocation
<span class="pull-right"><span class="fa fa-globe"></span></span>
</div>
<div class="panel-body" style="height: 400px;">
<div class="list-group" id="ticker">
</div>
</div>
</div>
And here is the Javascript:
$(document).ready(function(){
var counter=0;
var alert;
$("#boton1").click(function() {
for(var i=0; i<5; i++){
counter++;
if (counter===1){
alert = "<a class='list-group-item active' ";
}else{
alert = "<a class='list-group-item' ";
}
alert+="href='#'>";
// Titulo de la alerta
alert+="<h4 class='list-group-item-heading'>";
alert+="Alerta #"+counter;
alert+="</h4>";
// Texto de la alerta
alert+="<p class='list-group-item-text'>";
alert+="HOLIIISSS";
alert+="</p>";
alert+="</a>";
$("#ticker").append(alert);
}
});
$('.list-group-item').on('click',function(e){
var previous = $(this).closest(".list-group").children(".active");
previous.removeClass('active');
$(e.target).addClass('active');
});
});
Here is the fiddle:
http://jsfiddle.net/txfjjzsm/
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). You need to attach an event handler for all elements which match the current selector, now and in the future.
$('.list-group').on('click', '.list-group-item', function (event) {
event.preventDefault();
$(this).addClass('active').siblings().removeClass('active');
});
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.
See live example here: http://jsfiddle.net/cdog/en1ucfj6/.
Another one:
$(".list-group").click(function (e) {
$(".list-group .active").removeClass("active");
$(e.target).addClass("active");
});

Categories

Resources