I have created a javascript accordion, which works when one accordion is always open, I was wondering how I might modify my code so that the accordion, can also be closed when clicked again - so that all are collapsed?
$('.accordion-bottom').hide();
$('.accordion-link').on('click', global.toggleAccordian);
};
global.toggleAccordian = function(e){
var $Arrow = $(this).find('.arrow');
var $parentDiv = $(this).parent();
var $bottomAccordion = $parentDiv.siblings('.accordion-bottom');
var $accordionLi = $parentDiv.parents().eq('1');
var $siblingLis = $accordionLi.siblings('li');
var $siblingBotAccordions = $siblingLis.find('.accordion-bottom');
var $siblingArrows = $siblingLis.find('.arrow');
$siblingArrows.addClass('arrow-down');
if (!$accordionLi.hasClass('active')){
$bottomAccordion.slideDown('slow');
$Arrow.removeClass('arrow-down');
$siblingBotAccordions.stop().slideUp('slow');
}
e.preventDefault();
return false;
}
html:
<ul class="accordion">
<li>
<div class="item-inner-padding accordion-item">
<div class="accordion-top">
Title<span class="arrow arrow-down">Down</span>
</div>
<div class="accordion-bottom">
</div>
</div>
</li>
</ul>
Related
I need get "perma" value to button when is selected option in dropdown menu.
I have this HTML:
<div class="dropdown-list">
<div></div>
<div></div>
<div></div>
<div>
When is selected some div, perma attribute should somehow write into this :
button
Dropdown list Jquery:
//.input-dropdown
jQuery('.input-dropdown input, .input-dropdown > i').on('click',function(){
var elThis = jQuery(this);
var elParent = elThis.parents('.input-dropdown');
var elDropdownList = elParent.find('.dropdown-list');
if( elDropdownList.is(':visible') ){
elDropdownList.stop(true, true).slideUp(300);
}else{
elDropdownList.stop(true, true).slideDown(300);
}
});
jQuery('.input-dropdown .dropdown-list a').on('click',function(e){
e.preventDefault();
var elThis = jQuery(this);
var elParent = elThis.parents('.input-dropdown');
var elDropdownList = elParent.find('.dropdown-list');
var elInput = elParent.find('input');
elInput.val(elThis.data('value'));
elDropdownList.stop(true, true).slideUp(300);
});
jQuery(document).click(function(event) {
if(!jQuery(event.target).closest('.input-dropdown').length) {
if(jQuery('.input-dropdown .dropdown-list').is(":visible")) {
jQuery('.input-dropdown .dropdown-list').stop(true,true).slideUp(300);
}
}
});
What i tried:
<script>function gotosite() {
window.location = document.getAttribute("perma").perma;
}</script> <button id="go" onclick="gotosite()">Go</button>
button
With your dropdown list and button
<div class="dropdown-list">
<div>Link 1</div>
<div>Link 2</div>
<div>Link 3</div>
</div>
<a id="myButton" href="http://test.com/default/">button</a>
You can use Jquery to set href value of your button
$('.dropdown-list div a').click(function () {
//console.log($(this).attr('perma'));
//console.log($(this).attr('href'));
$("#myButton").attr("href", $(this).attr('perma'))
});
Need help with using js script.
<ul class="producers-links">
<li class="section_All active-producer">A-Z</li>
<li class="section_0-9">0-9</li>
<li class="section_A">A</li>
<li class="section_B">B</li>
<li class="section_C">C</li>
</ul>
And
<div class="producers-list">
<div class="producers-container" id="producers-0-9">
<div class="break-producers">0-9</div>
</div>
<div class="producers-container" id="producers-A">
<div class="break-producers">A</div>
Producer 1
</div>
<div class="producers-container" id="producers-B">
<div class="break-producers">B</div>
Producer 2
</div>
<div class="producers-container" id="producers-C">
<div class="break-producers">C</div>
Producer 3
</div>
</div>
How to make js script that will allow user click on list element then all divs from producers-list will get display:none without this one which was clicked at list.
var producersList = document.querySelectorAll('ul.producers-links>li');
var producersLists = document.querySelectorAll('div.producers-list>div.producers-container');
for (var i = 0; i < producersList.length; i++) {
producersList[i].addEventListener('click', function () {
document.querySelector('.active-producer').classList.remove('active-producer');
this.classList.add('active-producer');
var index = 0,
length = producersList.length;
for (; index < length; index++) {
producersLists[index].style.display = "none";
}
});
}
This allow me to hide all elements from producers-container but i don't know how to show only one element clicked before at list.
First of all you should use classes instead of id in the second list in order to have the ability to add more procedures in the future
try this:
<ul class="producers-links">
<li id="section_All" class="active-producer">A-Z</li>
<li id="section_0-9">0-9</li>
<li id="section_A">A</li>
<li id="section_B">B</li>
<li id="section_C">C</li>
</ul>
<div class="producers-list">
<div class="producers-container section_0-9 section_All">
<div class="break-producers">0-9</div>
</div>
<div class="producers-container section_A section_All">
<div class="break-producers">A</div>
Producer 1
</div>
<div class="producers-container section_B section_All">
<div class="break-producers">B</div>
Producer 2
</div>
<div class="producers-container section_C section_All">
<div class="break-producers">C</div>
Producer 3
</div>
</div>
var producersList = document.querySelectorAll('ul.producers-links > li');
var producersLists = document.querySelectorAll('.producers-container');
for (var i = 0; i < producersList.length; i++) {
producersList[i].addEventListener('click', function () {
document.querySelector('.active-producer').classList.remove('active-producer');
this.classList.add('active-producer');
for (var index = 0; index < producersLists.length ; index++) {
var currElement = producersLists[index];
var hide = !currElement.classList.contains(this.id);
producersLists[index].style.display = hide? "none" : "block";
}
});
}
On click, you can sequentially:
- hide all
- select the one having the same end of id than the textContent of the clicked item (or select all if text is A-Z)
var producersList = document.querySelectorAll('ul.producers-links>li');
var producersLists = document.querySelectorAll('div.producers-list>div.producers-container');
// add eventlistener...
producersList.forEach(x => {
x.addEventListener("click", x => {
hideAll();
document.querySelector('.active-producer').classList.remove('active-producer');
x.target.classList.add('active-producer');
const txt = x.target.textContent;
selectForText(txt);
});
});
// hide/show all...
function hideAll(bShow) {
const cl = bShow === true?"block":"none";
producersLists.forEach(x => x.style.display = cl);
}
// select for text...
function selectForText(txt) {
if(txt === "A-Z") {
// select all...
hideAll(true);
return;
}
// the [...nodelist] part allows to 'cast' to proper array, and to have access to find() function...
const found = [...producersLists].find(q => q.id.split("producers-")[1] === txt);
if(found) {
found.style.display = "block";
}
else {
// ???
}
}
.active-producer {
color: #19f;
}
<ul class="producers-links">
<li class="section_All active-producer">A-Z</li>
<li class="section_0-9">0-9</li>
<li class="section_A">A</li>
<li class="section_B">B</li>
<li class="section_C">C</li>
</ul>
And
<div class="producers-list">
<div class="producers-container" id="producers-0-9">
<div class="break-producers">0-9</div>
</div>
<div class="producers-container" id="producers-A">
<div class="break-producers">A</div>
Producer 1
</div>
<div class="producers-container" id="producers-B">
<div class="break-producers">B</div>
Producer 2
</div>
<div class="producers-container" id="producers-C">
<div class="break-producers">C</div>
Producer 3
</div>
</div>
Basically, I'm working with three tabs called 'Monday', 'Tuesday' and 'Favorites'. I have a toggle icon which is an empty heart at start => ('.favorite i') within each box. If I'm in Monday and click on the icon the empty heart turns to be filled out and the parent is cloned and added to the '#fav' tab.
When clicking in the heart within the cloned div the whole box gets removed from '#fav' tab but the icon within the original div doesn't get empty and keeps filled out.
So I thought the only way to do this was to grab the id from the original and cloned div which is the same and change the toggle class from there.
Any help is appreciated!
I've created this fiddle to give a better overview of the issue:
https://fiddle.jshell.net/itsfranhere/nbLLc3L0/44/
HTML:
<div class="container">
<div class="tabs_main">
<div class="col-md-5"><a data-target="#mon" class="btn active" data-toggle="tab">Monday</a></div>
<div class="col-md-5"><a data-target="#tue" class="btn active" data-toggle="tab">Tuesday</a></div>
<div class="col-md-2"><a data-target="#fav" class="btn active" data-toggle="tab"><i class="fa fa-heart" aria-hidden="true"></i></a></div>
</div>
<div class="tab-content">
<div class="tab-pane active" id="mon">
<br>
<div class="spaces">
<div class="box-container">
<div class="box not-selected" id="box1">
<i class="fa fa-heart-o" aria-hidden="true"></i>
</div>
<div class="box-container">
<div class="box not-selected" id="box1">
<i class="fa fa-heart-o" aria-hidden="true"></i>
</div>
</div>
</div>
<div class="tab-pane" id="tue">
<br>
<div class="spaces">
</div>
</div>
<div class="tab-pane" id="fav">
<br>
</div>
</div>
</div>
JS:
// Clones
$('div.tab-pane').on('click', '.favorite', function(e) {
e.preventDefault();
var par = $(this).parents('.box');
var id = $(this).parents('.parent');
var idFind = id.attr("id");
var idComplete = ('#' + idFind);
console.log(idComplete);
//TOGGLE FONT AWESOME ON CLICK
if ($(par).hasClass('selected')) {
par.find('.favorite i').toggleClass('fa-heart fa-heart-o');
} else {
par.find('.favorite i').toggleClass('fa-heart-o fa-heart');
};
if ($(par.hasClass('selected')) && ($('i').hasClass('fa-heart-o'))) {
par.closest('.selected').remove();
var getIcon = $(this).find('.favorite i').toggleClass('fa-heart-o fa-heart');
}
// Clone div
var add = $(this).parent().parent().parent();
add.each(function(){
if ($(add.find('.not-selected .favorite i').hasClass('fa-heart'))) {
var boxContent = $(add).clone(true, true);
var showHide = $(boxContent).find(".session").addClass('selected').removeClass('not-selected');
var get = $(boxContent).html();
var temp = localStorage.getItem('sessions');
var tempArray = [];
tempArray.push(get);
var myJSONString = JSON.stringify(tempArray);
var parseString = $.parseJSON(myJSONString);
var finalString = myJSONString.replace(/\r?\\n/g, '').replace(/\\/g, '').replace(/^\[(.+)\]$/,'$1').replace (/(^")|("$)/g, '');
var myJSONString = localStorage.setItem('sessions', finalString);
$("#fav").append(tempArray);
};
});
});
What I've tried..
var id = $(this).parents('.parent');
var idFind = id.attr("id");
var idComplete = ('#' + idFind);
if ($(par.hasClass('selected')) && ($('i').hasClass('fa-heart-o'))) {
par.closest('.selected').remove();
var getIcon = $(idComplete).find('.favorite i').toggleClass('fa-heart-o fa-heart');
}
Let's say I open an accordion tab with one click, and I want to close it with the second click.
This is the JS/jQuery I have so far:
var APP = window.APP = window.APP || {};
APP.accordion = (function () {
var $accordionHeader = $('.accordion__header');
var $accordionContent = $('.accordion__content');
var showAccordionContent = function(e) {
var $t = $(this);
$accordionHeader.removeClass('accordion__header--active');
$t.addClass('accordion__header--active');
$accordionContent.removeClass('accordion__content--expanded');
$t.next().addClass('accordion__content--expanded');
$('html, body').animate({
scrollTop: $t.offset().top - 60
}, 500);
e.preventDefault();
};
var bindEventsToUI = function () {
$accordionHeader.on('click', showAccordionContent);
};
var init = function () {
bindEventsToUI();
};
return {
init: init
};
}());
HTML:
<div class="accordion__tab">
<a href="#" class="accordion__header accordion__header--active">
Setting alerts
<span class="accordion__arrow"></span>
</a>
<div class="accordion__content">
<p>
{{!-- things --}}
</p>
<ul class="cf">
<li>
{{!-- more things --}}
</li>
</ul>
</div>
</div>
<div class="accordion__tab">
<a href="#" class="accordion__header">
Setting alerts
<span class="accordion__arrow"></span>
</a>
<div class="accordion__content">
<p>
{{!-- things --}}
</p>
<ul class="cf">
<li>
{{!-- more things --}}
</li>
</ul>
</div>
</div>
Suggestions?
I would do it like this, just some pseudos
var bindEventsToUI = function () {
$accordionHeader.on('click', toggleAccordionContent);
};
var toggleAccordionContent = function (e) {
var accordionIsOpen = $(this).classList.indexOf('accordion__header--active') >= 0; // may need to use another selector base on `this`
return accordionIsOpen ? hideAccordionContent.call(this) : showAccordionContent.call(this);
}
I guess you are looking for this. Modified showAccordionContent method logic a bit.
Hope this is what you are looking for.
This change will now close already open accordion on clicking it. And once you click on inactive accordion-header that will open. There might be a condition where user closes all the accordion after this code change.
var showAccordionContent = function(e) {
var $t = $(this);
/*Modified block logic*/
if($t.hasClass('accordion__header--active')){
$t.removeClass('accordion__header--active');
$t.next().removeClass('accordion__content--expanded');
}else{
$accordionHeader.removeClass('accordion__header--active');
$accordionContent.removeClass('accordion__content--expanded');
$t.addClass('accordion__header--active');
$t.next().addClass('accordion__content--expanded');
}
$('html, body').animate({
scrollTop: $t.offset().top - 60
}, 500);
e.preventDefault();
};
I'm using the following code to create a sliding card effect where each "card" is a list element and they slide across the screen. They are only visible within the "stage" I've set with specific height and width. It's working great -- except that, while the cards slide out nicely to the left, they don't perform the same sliding function inwards from the right. Instead, it simply jumps onto the page and looks a bit startling.
Does anyone know how I could get the next list item to slide in from the right instead of simply appearing?
Thanks!
JS:
window.addEvent('domready', function () {
var totIncrement = 0;
var increment = 968;
var maxRightIncrement = increment * (-303); //this is -303 because there are 303 cards, but the example below only has 3
var fx = new Fx.Style('slider-list', 'margin-left', {
duration: 300,
//transition: Fx.Transitions.Back.easeInOut,
wait: true
});
// EVENTS for the button "previous"
var pbuttons = document.getElementsByClassName('prevButton');
for(i = 0; i < pbuttons.length; i++) {
$(pbuttons[i]).addEvents({
'click': function (event) {
if(totIncrement > maxRightIncrement) {
totIncrement = totIncrement + increment;
fx.stop()
fx.start(totIncrement);
}
}
});
}
//-------------------------------------
// EVENTS for the button "next"
// var buttons = $('.nextButton');
var buttons = document.getElementsByClassName('nextButton');
for(i = 0; i < buttons.length; i++) {
$(buttons[i]).addEvents({
'click': function (event) {
if(totIncrement > maxRightIncrement) {
totIncrement = totIncrement - increment;
fx.stop()
fx.start(totIncrement);
}
}
});
}
});
HTML:
<div id="slider-stage">
<ul id="slider-list">
<li id="l1">
<!-- previous button -->
<div class="prev"><a class="prevButton" href="#">Previous</a></div>
<div>
<!-- content goes here -->
<!-- next button -->
<div class="slider-buttons">
<a class="nextButton" href="#">Next</a>
</div>
</div>
</li>
<li id="l2">
<!-- previous button -->
<div class="prev"><a class="prevButton" href="#">Previous</a></div>
<div>
<!-- content goes here -->
<!-- next button -->
<div class="slider-buttons">
<a class="nextButton" href="#">Next</a>
</div>
</div>
</li>
<li id="l3">
<!-- previous button -->
<div class="prev"><a class="prevButton" href="#">Previous</a></div>
<div>
<!-- content goes here -->
<!-- next button -->
<div class="slider-buttons">
<a class="nextButton" href="#">Next</a>
</div>
</div>
</li>
</ul>
</div>