jQuery Multiple Accordions | Only One Tab Expanded - javascript

As this is my first post here,
I would like to thank all of you very much for your great support.
Now to the point...
I have 2 accordions in one page.
How can I prevent having 2 accordion tabs expanded?
I mean, if a tab from the first accordion is expanded, I want this tab to be collapsed, when click a tab from the second accordion.
Spent many hours searching over the net and Stack Overflow, but found nothing.
Example Code:
Javascript:
$(function() {
$( ".myAccordion" ).accordion({
collapsible: true,
active: -1
});
});
Html:
<div>Category One</div>
<div class="myAccordion">
<h3>Title1</h3>
<div>Text1</text>
<h3>Title2</h3>
<div>Text2</text>
</div>
<div>Category Two</div>
<div class="myAccordion">
<h3>Title1</h3>
<div>Text1</text>
<h3>Title2</h3>
<div>Text2</text>
</div>
I tried adding a changestart option:
changestart: function(event, ui) {
$('h3.ui-accordion-header').removeClass('ui-state-active ui-corner-top').addClass('ui-state-default ui-corner-all');
$('div.ui-accordion-content').slideUp();
$('div.ui-accordion-content').removeClass('ui-accordion-content-active ui-corner-top').addClass('ui-corner-all');
$('span.ui-icon').removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
}
This does the trick, but only for the first time, a tab is clicked.
When you click that tab for a second time, it doesn't change at all. You have to click it for a third time to get it expand again.
Any help will be very appreciated.
Thanks again...

After I played a little and didn't find any solution, I decided to leave ui-accordion and make my own one! I believe that was the best solution to my problem!
As I didn't need fancy styling I used this code to achieve the result I needed:
<body>
<h1>Category 1</h1>
<div class="accTabs">
<a class="accLink" href="#">
<div class="tab-title">Tab Title</div>
<div class="tab-slide" style="display:none;">Tab Content to Slide</div>
</a>
</div>
<div class="accTabs">
<a class="accLink" href="#">
<div class="tab-title">Tab Title</div>
<div class="tab-slide" style="display:none;">Tab Content to Slide</div>
</a>
</div>
<h1>Category 2</h1>
<div class="accTabs">
<a class="accLink" href="#">
<div class="tab-title">Tab Title</div>
<div class="tab-slide" style="display:none;">Tab Content to Slide</div>
</a>
</div>
<div class="accTabs">
<a class="accLink" href="#">
<div class="tab-title">Tab Title</div>
<div class="tab-slide" style="display:none;">Tab Content to Slide</div>
</a>
</div>
<script>
$("a.accLink").click(function () {
var $that = $(this),
$children = $that.children('div.tab-slide');
// If expanded tab was clicked, collapse it.
// >> FIXED LOGIC ERROR >> if ($children.hasClass("slided")) {
if ($that.hasClass("slided")) {
$children.slideUp("slow", function () {
$that.removeClass("slided");
});
} else {
// Collapse all expanded tabs
// FIXED LOGIC ERROR >> $("div.slided").slideUp("slow", function() {
$(".slided").find("div.tab-slide").slideUp("slow", function () {
$(".slided").removeClass("slided");
});
// Expand clicked tab
$children.slideDown("slow", function () {
$that.addClass("slided");
});
}
});
</script>
</body>
UPDATED SCRIPT: FIXED LOGIC ERRORS TO MAKE 100% FUNCTIONAL

You want to attach your accordion() to a container element, not the actual divs.
For example:
<div id='accordion'>
<h3><a href='#'>Category One</a></h3>
<div class="myAccordion">
<h3>Title1</h3>
<div>Text1</text>
<h3>Title2</h3>
<div>Text2</text>
</div>
<h3><a href='#'>Category Two</a></h3>
<div class="myAccordion">
<h3>Title1</h3>
<div>Text1</text>
<h3>Title2</h3>
<div>Text2</text>
</div>
</div>
And then your script:
$(function() {
$( "#accordion" ).accordion({
collapsible: true,
active: false
});
});

Related

Is this a stable way to show/hide a div and a certain "id" using jQuery or could I use a better approach?

I have two containers, one is a page of link blocks and a have another container hidden. In the hidden container there is articles that link to the main pages link blocks. So user "clicks" LINK ONE in the main container which then hides the main container, shows the originally hidden container and ONLY displays the id article it is linked to. There is then a "back to library" button which will take you back to the main container and set everything back to square one. I have it working at the moment but I'm not sure if it is the right way to achieve this? I know there is no right or wrong and if it works, it works but just wondering for peace of mind. Thanks :)
CODEPEN: https://codepen.io/mDDDD/pen/ZEObRdR
HTML:
<div class="container--article-blocks" id="articleBlocks">
<div class="article-block">
<a class="show-article" href="#articleOne">LINK ONE</a>
</div>
<div class="article-block">
<a class="show-article" href="#articleTwo">LINK TWO</a>
</div>
<div class="article-block">
<a class="show-article" href="#articleThree">LINK THREE</a>
</div>
</div>
<!-- articles -->
<div class="container--articles" id="articles" style="display: none;">
back to Library
<div id="articleOne" class="article-block-articles">One</div>
<div id="articleTwo" class="article-block-articles">Two</div>
<div id="articleThree" class="article-block-articles">Three</div>
</div>
jQuery:
$('.show-article').on('click', function (e) {
e.preventDefault();
var id = $(this).attr('href');
$(id).show().siblings('div').hide();
$('#articleBlocks').fadeOut();
setTimeout(function () {
$('#articles').fadeIn();
}, 500);
});
$('.back-to-library').on('click', function (e) {
e.preventDefault();
$('#articles').fadeOut();
setTimeout(function () {
$('#articleBlocks').fadeIn();
}, 500);
});
Consider using the callback for .fadeOut() to then call .fadeIn(). Nothing wrong with that you did, this will just ensure the item is faded out before executing further code.
$(function() {
$('.show-article').on('click', function(e) {
e.preventDefault();
var id = $(this).attr('href');
$(id).show().siblings('div').hide();
$('#articleBlocks').fadeOut(500, function() {
$('#articles').fadeIn();
});
});
$('.back-to-library').on('click', function(e) {
e.preventDefault();
$('#articles').fadeOut(500, function() {
$('#articleBlocks').fadeIn();
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container--article-blocks" id="articleBlocks">
<div class="article-block">
<a class="show-article" href="#articleOne">LINK ONE</a>
</div>
<div class="article-block">
<a class="show-article" href="#articleTwo">LINK TWO</a>
</div>
<div class="article-block">
<a class="show-article" href="#articleThree">LINK THREE</a>
</div>
</div>
<!-- articles -->
<div class="container--articles" id="articles" style="display: none;">
back to Library
<div id="articleOne" class="article-block-articles">One</div>
<div id="articleTwo" class="article-block-articles">Two</div>
<div id="articleThree" class="article-block-articles">Three</div>
</div>
You can make the visibility: hidden; after an event!
Actual example
document.getElementById("XXX").style.visibility = "hidden";
But actually, your project is just fine!
For more info, go here https://www.w3schools.com/jsref/prop_style_visibility.asp
This explains the HTML DOM visibility property!

reducing the javascript with multiple hide/show divs

I'm hoping that someone would be kind enough to help me.
I have patched together a script to create a set of thumbnails that when hovered over display a link that will show further information in a slide up div.
I need multiple instances of this which I have managed to create but whenever I would like to add a new project (which is what these thumbnails will be) I have to add to the javascript every time I add an instance. I need this to work with a CMS so adding to the javascript is out of the question.
My understanding of javascript is not good enough to work out how to reduce the JS and not have to add $("#projectX").slideDown(500); even time I add a new project. The code I have so far is below. I basically don't want to have to write a piece of javascript every time I input another thumbnail and slide up div pairing.
HTML:
<div class="row">
<div class="col-xs-12">
<div class="hidden-work">
<div id="project1" class="hidden">
<div class="callbacks_container">
<button class="hide">X</button>
<ul class="rslides" id="slider2">
<li>
<div class="row">
<div class="col-md-8 col-xs-12">
<img src="img/eejits/fleur.jpg" alt="">
</div>
<div class="col-md-4 col-xs-12">
<div class="caption">
<h3>Slide 1</h3>
<p>Lorem ipsum</p>
</div><!--caption-->
</div><!--col-->
</div><!--row-->
</li>
</ul>
</div><!--callbacks_container-->
</div><!--eejits-->
<div id="project2" class="hidden">
<div class="callbacks_container">
<button class="hide">X</button>
<ul class="rslides" id="slider1">
<li>
<div class="row">
<div class="col-md-8 col-xs-12">
<img src="img/eejits/fleur.jpg" alt="">
</div>
<div class="col-md-4 col-xs-12">
<div class="caption">
<h3>Slide 2</h3>
<p>Lorem ipsum</p>
</div><!--caption-->
</div><!--col-->
</div><!--row-->
</li>
</ul>
</div>
</div><!--project2 (reach)-->
<div id="project3" class="hidden">
<div class="callbacks_container">
<button class="hide">X</button>
<ul class="rslides" id="slider3">
<li>
<div class="row">
<div class="col-md-8 col-xs-12">
<img src="img/eejits/fleur.jpg" alt="">
</div>
<div class="col-md-4 col-xs-12">
<div class="caption">
<h3>Slide 3</h3>
<p>Lorem ipsum</p>
</div><!--caption-->
</div><!--col-->
</div><!--row-->
</li>
</ul>
</div>
</div><!--project3-->
</div><!--work-->
</div>
</div><!--row-->
<div class="row">
<div class="col-sm-4 col-xs-12">
<div class="thumb-bg">
<div class="thumb no1">
<div class="content">
<h3>Thumb 1</h3>
<p>Lorem ipsum.</p>
<button class="project1 link">VIEW MORE</button>
</div>
</div>
</div>
</div><!--col-->
<div class="col-sm-4 col-xs-12">
<div class="thumb-bg">
<div class="thumb no2">
<div class="content">
<h3>Thumb 2</h3>
<p>Lorem ipsum.</p>
<button class="project2 link">VIEW MORE</button>
</div>
</div>
</div>
</div><!--col-->
<div class="col-sm-4 col-xs-12">
<div class="thumb-bg">
<div class="thumb no3">
<div class="content">
<h3>Thumb 3</h3>
<p>Lorem ipsum.</p>
<button class="project3 link">VIEW MORE</button>
</div>
</div>
</div>
</div><!--col-->
</div><!--row-->
JS:
$(function () {
$("#slider1").responsiveSlides({
auto: false,
pager: false,
nav: true,
speed: 500,
namespace: "callbacks",
before: function () {
$('.events').append("<li>before event fired.</li>");
},
after: function () {
$('.events').append("<li>after event fired.</li>");
}
});
});
$(function () {
$("#slider2").responsiveSlides({
auto: false,
pager: false,
nav: true,
speed: 500,
namespace: "callbacks",
before: function () {
$('.events').append("<li>before event fired.</li>");
},
after: function () {
$('.events').append("<li>after event fired.</li>");
}
});
});
$(function () {
$("#slider3").responsiveSlides({
auto: false,
pager: false,
nav: true,
speed: 500,
namespace: "callbacks",
before: function () {
$('.events').append("<li>before event fired.</li>");
},
after: function () {
$('.events').append("<li>after event fired.</li>");
}
});
});
$(document).ready(function(){
$(".project2").click(function(){
$("#project2").slideDown(500);
$("#project1").slideUp(500);
$("#project3").slideUp(500);
});
$(".project1").click(function(){
$("#project1").slideDown(500);
$("#project2").slideUp(500);
$("#project3").slideUp(500);
});
$(".project3").click(function(){
$("#project3").slideDown(500);
$("#project1").slideUp(500);
$("#project2").slideUp(500);
});
$(".hide").click(function(){
$("#project1").slideUp(500);
$("#project2").slideUp(500);
$("#project3").slideUp(500);
});
});
I really hope that makes sense and any help with this would be brilliant.
Thanks
You need to look into the different selector type. http://api.jquery.com/category/selectors/ Anything prefaced with a # is referencing an element by id (which should be unique and thus only return 1 element) anything prefaced with a . refers to elements by class
EDIT:
Just realised you need to manipulate a separate element to the one that is clicked. OK so to make sure this works universally, you need to make sure the order is the same for the "buttons" and the "slides". We're going to find the index of the button clicked and then use that same logic to slide the appropriate divs.
You can give your buttons a class of "project-button" and your projects a class of "project"
So to make your code universally applicable with one listener you could give all your projects a class of project and then do something like this:
// Attach the same click listener to all elements which have class `project-button`
$('.project-button').on('click', function () {
// Get the index of this clicked button
var myIndex = $(this).index();
// Now get the corresponding `slide`
var mySlide = $('.project').get(myIndex);
// Get all `.project`'s then exclude `mySlide`and slide up
$('.project').not(mySlide).slideUp(500);
// Now slide down just `mySlide`
$(mySlide).slideDown(500);
});
Demo: http://jsfiddle.net/robschmuecker/jPyk6/
You can try below code.
$(".hidden").click(function(){;
$(this).slideDown(500);
($(this).siblings()).each(function( index ) {
$( this ).slideUp(500);
});
});
I saw that you use class="link" for every buttons, you can use class instead of id. Then add id to the button for selecting the right div, like this:
HTML
<button id="project1" class="project1 link">VIEW MORE</button>
jQuery
$('.link').click(function(){
//slideUp all div with class hidden
$('div.hidden').slideUp(500);
//slideDown div with id equals the clicked button
$('div#'+$(this).attr('id')).slideDown(500);
});
I think the same goes for your slider, use the class instead of the id, like this:
$(function () {
$(".rslides").responsiveSlides({
auto: false,
pager: false,
nav: true,
speed: 500,
namespace: "callbacks",
before: function () {
$('.events').append("<li>before event fired.</li>");
},
after: function () {
$('.events').append("<li>after event fired.</li>");
}
});
});
Note: I don't see any element with class events, so I assume its a global element..

How to make infinite flip out of the code below?

How to tweak the flip javascript in this link http://desandro.github.io/3dtransforms/docs/card-flip.html so that it will flip to the third content or won't referse flip to the first content
var init = function() {
var card = document.getElementById('card');
document.getElementById('flip').addEventListener( 'click', function(){
card.toggleClassName('flipped');
}, false);
};
window.addEventListener('DOMContentLoaded', init, false);
The contents of each element should be stored separately in the HTML, and retrieved when needed.
<div class="container">
<div class="card">
<div class="face face1"></div>
<div class="face face2"></div>
</div>
<ul class="store">
<li>
<div class="content content1">1</div>
</li>
<li>
<div class="content content2">2</div>
</li>
<li>
<div class="content content3">3</div>
</li>
<li>
<div class="content content4">4</div>
</li>
</ul>
</div>
Answer copied and edited from
If I understand your question correctly, you only want the click event to happen once. If that's the case, and you're alright using jQuery, the jQuery 'one' function should be what you're looking for.
$( "#flip" ).one( "click", function() {
card.toggleClassName('flipped');
});

Show specific content for each div using Fancybox,

I am trying to load a specific sibling for each div using fancybox.
E.g:
<div id ="content">
<div class="item1">
<div class="pop-ups"><span>click</span></div>
<div class="hidden"><span>content for item 1</span></div>
</div>
<div class="item2">
<div class="pop-ups"><span>click</span></div>
<div class="hidden"><span>content for item 2</span></div>
</div>
<div class="item3">
<div class="pop-ups"><span>click</span></div>
<div class="hidden"><span>content for item 3</span></div>
</div>
<div class="item4">
<div class="pop-ups"><span>click</span></div>
<div class="hidden"><span>content for item 4</span></div>
</div>
</div>
I tried to do the config using the property Content, but not got it, is it possible to get each hidden for each specific item ?
You can use below code:
$(function(){
$("div.pop-ups span").click(function(){
$.fancybox({ content: $(this).parent().next().html() });
});
});
This will show the content of relevant div in fancybox.
You can call this function to open some specific div content in a fancybox.
function OpenDiv(divIDtoopen) //eg. divIDtoopen= #divID //# is must to be prepended to divID for selection
{
$(document).ready(function ()
{
$.fancybox.open(
{
href: divtoopen
}
);
}
);
}

Javascript - jquery,accordion

<div id="wrapper">
<div class="accordionButton">Personal Information</div>
<div class="accordionContent">
Personal text
</div>
<div class="accordionButton">Experience</div>
<div class="accordionContent">
Experience information
</div>
<div class="accordionButton">Training</div>
<div class="accordionContent">
No skills
<div class="accordionButton">Career</div>
<div class="accordionContent">
Never had a job
</div>
<div class="accordionButton">Referers</div>
<div class="accordionContent">
None.
</div>
</div>
This code works how i want it to. It is a horizontal accordion. However, when it is loaded on my webpage, they content divs have to be hidden for my jquery to work.
Jquery:
$(document).ready(function() {
// When div is clicked, hidden content divs will slide out
$('div.accordionButton').click(function() {
$('div.accordionContent').slideUp('normal');
$(this).next().slideDown('normal');
});
// Close all divs on load page
$("div.accordionContent").hide();
});
If i don't hide the divs, all the divs display. Is there any way to display the 1st page without changing too much of my jquery or would i have to set different class names for the button and the content so that when a specified button is clicked, the affiliated content will slide out for that button div?
You can use jquery selector for first div and set it as show(). Something like :
$('div.accordionContent:first').show();
I think you have to try this:-
<script type="text/javascript">
$.fn.accordion = function(settings) {
accordion = $(this);
}
$(document).ready(function($) {
$('div.accordionContent').click(function() {
if($(this).next().is(":visible")) {
$(this).next().slideDown();
}
$('div.accordionContent').filter(':visible').slideUp();
$(this).next().slideDown();
return false;
});
});
</script>
Why not use slideToggle() instead of IF statements....
Try this very simple solution
HTML
<div class="accordion-container">
<div class="accordion-content">
<div class="accordion-title">Title</div>
<div class="accordion-toggle">Toggle content</div>
</div>
<div class="accordion-content">
<div class="accordion-title">Title</div>
<div class="accordion-toggle">Toggle content</div>
</div>
<div class="accordion-content">
<div class="accordion-title">Title</div>
<div class="accordion-toggle">Toggle content</div>
</div>
</div>
jQuery
$('.accordion-content .accordion-title').on('click', function(){
$(this).toggleClass('active');
$('.accordion-title').not($(this)).removeClass('active');
$(this).next().slideToggle();
$(".accordion-toggle").not($(this).next()).slideUp();
});

Categories