I have this "Accordion Type" Snippet right now. It opens the content below the button on click and closes it again. Now I am looking for a solution to make the state of the button visible to the user e.g if Button 2 is opened, I want to show a "-" indicating that it can be closed with a click. Same with the closed buttons to show a "+". Is this possible? Thanks in advance :)
This is my code right now:
jQuery(function() {
jQuery('.ss_button').on('click', function() {
jQuery('.ss_content').not(jQuery(this).next('.ss_content')).slideUp('fast');
jQuery(this).next('.ss_content').slideToggle('fast');
});
jQuery('.ss_content').eq(1).show();
});
#ss_menu {
width: auto;
}
.ss_button {
background-color: #049132;
border-bottom: 1px solid #FFFFFF;
cursor: pointer;
padding: 10px;
margin-bottom: 5px;
color: #FFFFFF;
}
.ss_content {
background-color: white;
display: none;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="ss_menu">
<div class="ss_button">Einsteiger</div>
<div class="ss_content">
<p>Test1</p>
</div>
<div class="ss_button">Mittelklasse</div>
<div class="ss_content">
<p>Test2</p>
</div>
<div class="ss_button">High-End</div>
<div class="ss_content">
<p>Test3</p>
</div>
</div>
I've added some changes to your css:
.ss_button:before {
content: "+ ";
}
.ss_button.active:before{
content: "- ";
}
Then we toogle the active class:
jQuery('.ss_button.active').not(jQuery(this)).removeClass('active')
jQuery(this).toggleClass('active');
This way you don't have to change your html.
Demo
jQuery(function() {
jQuery('.ss_button').on('click', function() {
jQuery('.ss_button.active').not(jQuery(this)).removeClass('active')
jQuery(this).toggleClass('active');
jQuery('.ss_content').not(jQuery(this).next('.ss_content')).slideUp('fast');
jQuery(this).next('.ss_content').slideToggle('fast');
});
jQuery('.ss_content').eq(1).show();
});
#ss_menu {
width: auto;
}
.ss_button {
background-color: #049132;
border-bottom: 1px solid #FFFFFF;
cursor: pointer;
padding: 10px;
margin-bottom: 5px;
color: #FFFFFF;
}
.ss_button:before {
content: "+ ";
}
.ss_button.active:before{
content: "- ";
}
.ss_content {
background-color: white;
display: none;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="ss_menu">
<div class="ss_button">Einsteiger</div>
<div class="ss_content">
<p>Test1</p>
</div>
<div class="ss_button active">Mittelklasse</div>
<div class="ss_content">
<p>Test2</p>
</div>
<div class="ss_button">High-End</div>
<div class="ss_content">
<p>Test3</p>
</div>
</div>
You can add an empty span in your buttons and change the content (+ or -) in the click functions.
Check lines #4 and #6, the same of the code is the same.
jQuery(function() {
jQuery('.ss_button').on('click', function() {
jQuery('.ss_content').not(jQuery(this).next('.ss_content')).slideUp('fast');
jQuery('.ss_button').find('span').text('+');
jQuery(this).next('.ss_content').slideToggle('fast');
jQuery(this).find('span').text('-');
});
jQuery('.ss_content').eq(1).show();
});
#ss_menu {
width: auto;
}
.ss_button {
background-color: #049132;
border-bottom: 1px solid #FFFFFF;
cursor: pointer;
padding: 10px;
margin-bottom: 5px;
color: #FFFFFF;
}
.ss_content {
background-color: white;
display: none;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="ss_menu">
<div class="ss_button">Einsteiger
<span>+</span></div>
<div class="ss_content">
<p>Test1</p>
</div>
<div class="ss_button">Mittelklasse
<span>+</span></div>
<div class="ss_content">
<p>Test2</p>
</div>
<div class="ss_button">High-End
<span>+</span></div>
<div class="ss_content">
<p>Test3</p>
</div>
</div>
When my card title is clicked, its content shows or hides with the show slide jquery animation .show('slide', {direction: 'up'}, 'slow') / .hide('slide', {direction: 'up'}, 'slow'. The problem is that during the animation the width of .content-annales decreases so there is a lack of continuity with the .title-annales div on the right side.
Here is an example of the problem: click here
jQuery(".title-annales").on("click", function() {
var element = jQuery(this);
if (jQuery(this).next().css('display') === 'none') {
element.css('border-radius', '20px 20px 0px 0px');
jQuery(this).next().show('slide', {
direction: 'up'
}, 'slow', function() {
element.find('.span-msg-mediadroit-annale').html('<i class="fas fa-chevron-circle-up"></i>');
});
} else {
jQuery(this).next().hide('slide', {
direction: 'up'
}, 'slow', function() {
element.css('border-radius', '20px');
element.find('.span-msg-mediadroit-annale').html('<i class="fas fa-chevron-circle-down"></i>');
});
}
});
<div class="card-annales">
<div class="title-annales">
<span class="span-msg-mediadroit-annale float-right"><i class="fas fa-chevron-circle-down"></i></span>
<h3 style="font-size: inherit; display: contents; font-weight: inherit;">Nom matière</h3>
</div>
<div class="content-annales">
[...]
</div>
</div>
EDIT : I've tried to replicate the issue on jsfiddle but it works perfectly here. I use a bootstrap based theme (Hestia for Wordpress) and when I remove from the bootstrap css file the property box-sizing: border-box;, it works like in the jsfiddle.
I wasn't able to reproduce the behavior that you mentioned, but have a possible solution for you. Add width: calc(100% - 20px); to .content-annales.
jQuery(".title-annales").on("click", function() {
var element = jQuery(this);
if (jQuery(this).next().css('display') === 'none') {
element.css('border-radius', '20px 20px 0px 0px');
jQuery(this).next().show('slide', {
direction: 'up'
}, 'slow', function() {
element.find('.span-msg-mediadroit-annale').html('<i class="fas fa-chevron-circle-up"></i>');
});
} else {
jQuery(this).next().hide('slide', {
direction: 'up'
}, 'slow', function() {
element.css('border-radius', '20px');
element.find('.span-msg-mediadroit-annale').html('<i class="fas fa-chevron-circle-down"></i>');
});
}
});
.card-annales {
display: block;
margin-bottom: 20px;
}
.title-annales {
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px 20px;
background-color: #012f51;
color: #ff6501;
font-size: 1.7em;
border: gray 1px solid;
padding: 10px 30px;
cursor: pointer;
}
.content-annales {
border-left: gray 1px solid;
border-right: gray 1px solid;
border-bottom: gray 1px solid;
padding: 10px;
border-radius: 0px 0px 20px 20px;
display: none;
width: calc(100% - 20px); /* added */
}
.float-right {
float: right;
}
.float-left {
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="card-annales">
<div class="title-annales">
<span class="span-msg-mediadroit-annale float-right"><i class="fas fa-chevron-circle-down"></i></span>
<h3 style="font-size: inherit; display: contents; font-weight: inherit;">Nom matière</h3>
</div>
<div class="content-annales">
[...]
</div>
</div>
I've finally fixed the issue.
1. Probable cause of the issue
When .show('slide', { direction: 'up'}, 'slow') is executed, jquery-ui sets a fixed width to the selected div which seems to not take into consideration the padding (padding: 10px for .content-annales). See what happened during the jquery animation:
I don't really understand why the padding is not taked into account as it works perfectly in the jsfiddle shared in my question. It could be link to box-sizing: border-box; which is set for all html according to my theme. In fact, when I disable it, the issue disappear.
2. My solution
It's quite simple : I've encapsulated .content-annales in a parent div called .content-annales-toggle which has no style except display: none;. My animation now shows/hides up .content-annales-toggle so there is no issue with the padding.
Here is the new code :
jQuery(".title-annales").on("click", function() {
var element = jQuery(this);
if (jQuery(this).next().css('display') === 'none') {
element.css('border-radius', '20px 20px 0px 0px');
jQuery(this).next().show('slide', {
direction: 'up'
}, 'slow', function() {
element.find('.span-msg-mediadroit-annale').html('<i class="fas fa-chevron-circle-up"></i>');
});
} else {
jQuery(this).next().hide('slide', {
direction: 'up'
}, 'slow', function() {
element.css('border-radius', '20px');
element.find('.span-msg-mediadroit-annale').html('<i class="fas fa-chevron-circle-down"></i>');
});
}
});
<style>
.card-annales {
display: block;
margin-bottom: 20px;
}
.title-annales {
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px 20px;
background-color: #012f51;
color: #ff6501;
font-size: 1.7em;
border: gray 1px solid;
padding: 10px 30px;
cursor: pointer;
}
.content-annales-toggle {
display: none; /* edited */
}
.content-annales {
border-left: gray 1px solid;
border-right: gray 1px solid;
border-bottom: gray 1px solid;
padding: 10px;
border-radius: 0px 0px 20px 20px;
display: block; /* edited */
}
.float-right {
float: right;
}
.float-left {
float: left;
}
</style>
<div class="card-annales">
<div class="title-annales">
<span class="span-msg-mediadroit-annale float-right"><i class="fas fa-chevron-circle-down"></i></span>
<h3 style="font-size: inherit; display: contents; font-weight: inherit;">Nom matière</h3>
</div>
<div class="content-annales-toggle">
<div class="content-annales">
[...]
</div>
</div>
</div>
I think this is related to overflow when the content is rendered. Consider the following:
https://jsfiddle.net/Twisty/zqk9johc/
JavaScript
jQuery(".title-annales").on("click", function() {
var element = jQuery(this);
var nextEl = element.next();
var parentEl = element.parent();
var iconUp = $("<i>", {
class: "fas fa-chevron-circle-up"
});
var iconDown = $("<i>", {
class: "fas fa-chevron-circle-up"
});
if (nextEl.css('display') === 'none') {
nextEl.show('slide', {
direction: 'up'
}, 'slow', function() {
element.css('border-radius', '20px 20px 0px 0px');
jQuery('.span-msg-mediadroit-annale', element).html(iconUp);
});
} else {
nextEl.hide('slide', {
direction: 'up'
}, 'slow', function() {
element.css('border-radius', '20px');
jQuery('.span-msg-mediadroit-annale', element).html(iconDown);
});
}
});
Nothing vastly different in the code, yet in the Fiddle I have added 5 paragraphs. When the content is shown, a scroll bar is rendered by the browser as the content extends beyond the current window height. The scroll bar being rendered seems to re-flow the content of the document.
If you add some CSS:
html {
overflow-y: scroll;
}
The Scroll Bar is already rendered and no re-flow is needed.
Example: https://jsfiddle.net/Twisty/zqk9johc/5/
Hope that helps.
Please remove the padding from the class "content-annales" and wrap inner content on div and adding padding to the same.
Please check the code below:-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="card-annales">
<div class="title-annales">
<span class="span-msg-mediadroit-annale float-right"><i class="fas fa-chevron-circle-down"></i></span>
<h3 style="font-size: inherit; display: contents; font-weight: inherit;">Nom matière</h3>
</div>
<div class="content-annales">
<div class="inner-section">
[...]
</div>
</div>
</div>
<style>
.card-annales {
display: block;
margin-bottom: 20px;
}
.title-annales {
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px 20px;
background-color: #012f51;
color: #ff6501;
font-size: 1.7em;
border: gray 1px solid;
padding: 10px 30px;
cursor: pointer;
}
.content-annales {
border-left: gray 1px solid;
border-right: gray 1px solid;
border-bottom: gray 1px solid;
border-radius: 0px 0px 20px 20px;
display: none;
}
.inner-section {
padding: 10px;
}
.float-right {
float: right;
}
.float-left {
float: left;
}
</style>
<script>
jQuery(".title-annales").on("click", function() {
var element = jQuery(this);
if (jQuery(this).next().css('display') === 'none') {
element.css('border-radius', '20px 20px 0px 0px');
jQuery(this).next().show('slide', {
direction: 'up'
}, 'slow', function() {
element.find('.span-msg-mediadroit-annale').html('<i class="fas fa-chevron-circle-up"></i>');
});
} else {
jQuery(this).next().hide('slide', {
direction: 'up'
}, 'slow', function() {
element.css('border-radius', '20px');
element.find('.span-msg-mediadroit-annale').html('<i class="fas fa-chevron-circle-down"></i>');
});
}
});
</script>
I have a small self made filter bar for a small agenda.
When i click on the filter button i want to hide the rows which are not in the category.
When i click Marketing, it will hide all other categories, and it's the same for the siblings. When i press ALL I want to show all rows again.
I bet there has to be a better way, i just can't figure it out
(function ($) {
$('#FilterBar a').click(function () {
if ($('#FilterBar a').is('.all')) {
$('.row').show();
}
else if ($('#FilterBar a').is('.pauses')) {
$('#Agenda .row:not(.pauses)').hide();
}
else if ($('#FilterBar a').is('.marketing')) {
$('#Agenda .row:not(.marketing)').hide();
}
else if ($('#FilterBar a').is('.sales')) {
$('#Agenda .row:not(.sales)').hide();
}
});
})(jQuery);
.wrapper {
padding: 20px;
}
#FilterBar a {
padding: 5px;
}
#Agenda {
padding: 15px 5px 5px;
}
#Agenda div {
padding: 20px;
background: #e7e7e7;
}
#Agenda div:nth-child(even) {
padding: 20px;
background: #f7f7f7;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="FilterBar">
All
Pauses
Marketing
Sales
</div>
<div id="Agenda">
<div class="row pauses"><b>Pause:</b> Break at 10:30</div>
<div class="row marketing"><b>Marketing:</b> This is marketing</div>
<div class="row sales"><b>Sales:</b> Sales is important</div>
</div>
</div>
You could do it like this:
(function ($) {
$('#FilterBar a').click(function () {
$('#Agenda .row').hide();
const className = $(this).attr('class');
$('#Agenda .' + (className === 'all' ? 'row' : className)).show();
});
})(jQuery);
.wrapper {
padding: 20px;
}
#FilterBar a {
padding: 5px;
}
#Agenda {
padding: 15px 5px 5px;
}
#Agenda div {
padding: 20px;
background: #e7e7e7;
}
#Agenda div:nth-child(even) {
padding: 20px;
background: #f7f7f7;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="FilterBar">
All
Pauses
Marketing
Sales
</div>
<div id="Agenda">
<div class="row pauses"><b>Pause:</b> Break at 10:30</div>
<div class="row marketing"><b>Marketing:</b> This is marketing</div>
<div class="row sales"><b>Sales:</b> Sales is important</div>
</div>
</div>
I have a function that copies the data attribute and gives it an active class. I need to be able to clear the active class from .copy-btn when either .close1 or .close2 is clicked.
$(document).ready(function() {
$(".copy-btn").click(function(event) {
event.preventDefault();
});
});
var clip = new Clipboard(".copy-btn");
$(".copy-btn").click(function(e) {
$.each($(".copy-btn"), function(index, value) {
if (
$(value).attr("data-text") ==
$(e.target).attr("data-text")
) {
$(value).addClass("active");
}
});
});
.btn {
width: 50px;
height: 20px;
border: 2px solid;
cursor: pointer;
}
.copy-btn {
outline: none;
cursor: pointer;
border: none;
background-color: white;
font-size: 21px;
}
.active {
border-bottom: 3px dotted green;
padding-bottom: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.12/clipboard.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="copy-btn" data-text="CODE1">CODE1</p>
<p class="copy-btn" data-text="CODE2">CODE2</p>
<p class="copy-btn" data-text="CODE3">CODE3</p>
<div class="btn close1">Close 1</div>
<div class="btn close2">Close 2</div>
Just using removeClass()
$('.close1, .close2').on('click', function() {
$('.copy-btn').removeClass('active');
})
I have the following code where I added a plus symbol to one of my service titles. I was informed by someone that when that service is clicked on I should have a minus sign take its place to show that it can be minimized. I am unsure of how to swap out the plus sign when the description has been expanded. Does anyone have any ideas of how I could do that?
Here is a snippet. Click on one of the service names to see the description expand.
$('.service_wrapper').click(function() {
var thisDescription = $('.service_description', $(this));
// Hide all other descriptions
$('.service_description').not(thisDescription).hide();
// Toggle (show or hide) this description
thisDescription.slideToggle(500);
});
.service_wrapper {
border: 1px solid black;
margin: 15px;
width: 20%;
}
.service_list {
margin-left: 20%;
}
.service_title {
padding: 15px 12px;
margin: 0;
font-weight: bold;
font-size: 1em;
}
.service_title:hover {
background-color: gray;
color: blue;
cursor: pointer;
}
.service_description {
display: none;
padding: 8px 14px;
width: 100%;
margin-top: 10px;
font-size: .9em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="service_list">
<div class="service_wrapper">
<div class="service_title">
<img src="http://realtorcatch.com/icons/plusSymbol.png" alt="Service" style="width:10px;height:10px;">Floors</div>
<div class="service_description">The best floors!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Roofs</div>
<div class="service_description">Your roof will be perfect!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Siding</div>
<div class="service_description">mmmm siding.</div>
</div>
<div class="service_wrapper">
<div class="service_title">Paint</div>
<div class="service_description">Fabulous paint!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Kitchen Remodels</div>
<div class="service_description">Pretty kitchen.</div>
</div>
</div>
Here is the working example, i change a little de html and Js
$('.service_wrapper').click(function() {
var thisDescription = $('.service_description', $(this));
var t = $(this);
if(t.hasClass('open'))
{
t.removeClass('open');
t.find('.status').html("+");
}else {
t.addClass('open');
t.find('.status').html("-");
}
// Hide all other descriptions
$('.service_description').not(thisDescription).hide();
// Toggle (show or hide) this description
thisDescription.slideToggle(500);
});
the working example
I'd suggest simply toggling a class to achieve this.
You can add the icon as a background image of a pseudo element inserted into the .service_title element. Then you can simply toggle a class in order to change the icon. Update the background image URLs accordingly. See the updated example for the modified jQuery; it's still only 5 lines.
The relevant CSS:
.service_title:before {
content: '';
background: url('http://i.stack.imgur.com/GC7i2.png') 0 0 / 10px 10px no-repeat;
width: 10px;
height: 10px;
display: inline-block;
vertical-align: middle;
}
.closed .service_title:before {
background-image: url('http://i.stack.imgur.com/ma4L4.png');
}
Updated Example:
$('.service_wrapper').click(function() {
var thisDescription = $('.service_description', $(this));
$('.service_description').not(thisDescription).hide().parent().removeClass('closed');
thisDescription.slideToggle(500).parent().toggleClass('closed');
});
.service_wrapper {
border: 1px solid black;
margin: 15px;
width: 20%;
}
.service_list {
margin-left: 20%;
}
.service_title {
padding: 15px 12px;
margin: 0;
font-weight: bold;
font-size: 1em;
}
.service_title:before {
content: '';
background: url('http://i.stack.imgur.com/GC7i2.png') 0 0 / 10px 10px no-repeat;
width: 10px;
height: 10px;
display: inline-block;
vertical-align: middle;
}
.closed .service_title:before {
background-image: url('http://i.stack.imgur.com/ma4L4.png');
}
.service_title:hover {
background-color: gray;
color: blue;
cursor: pointer;
}
.service_description {
display: none;
padding: 8px 14px;
width: 100%;
margin-top: 10px;
font-size: .9em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="service_list">
<div class="service_wrapper">
<div class="service_title">Floors</div>
<div class="service_description">The best floors!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Roofs</div>
<div class="service_description">Your roof will be perfect!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Siding</div>
<div class="service_description">mmmm siding.</div>
</div>
<div class="service_wrapper">
<div class="service_title">Paint</div>
<div class="service_description">Fabulous paint!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Kitchen Remodels</div>
<div class="service_description">Pretty kitchen.</div>
</div>
</div>
You could just change it within your click binding...
Let's say your using images, just add a data-attribute you can query when you need to, like this...
HTML
<div class="service_wrapper">
<img data-state="plus" class="state" src="plus.png" alt="More"/>
<div class="service_title">Paint</div>
<div class="service_description">Fabulous paint!</div>
</div>
JS
$('.service_wrapper').click(function() {
var state = $(this).find('.state');
if(state.data('state') == 'plus')
state.attr({ 'src': 'minus.png', 'alt': 'Less' }).data('state', 'minus');
else
state.attr({ 'src': 'plus.png', 'alt': 'More' }).data('state', 'plus');
});