jQuery accordian arrow toggle - javascript

I have got an accordian toggle working great - but I have noticed that the arrow is not toggling when a link other than the 'active link' is selected. Does anyone have any suggestions on how to do this?
$(document).ready(function(){
$('.q').on(action, function(){
$(this).next().slideToggle(speed)
.siblings('.a').slideUp();
var i = $(this).children('.q i');
i.toggleClass("fa-chevron-up fa-chevron-down");
});
});
.faq {
margin-bottom:1em;
}
.faq h4.q,
.faq div {
margin:0;
padding: 1.25em;
position:relative;
}
.faq h4.q {
border-bottom: 1px #cdd4d9 solid;
color: #eb9532;
cursor: pointer;
padding-right:3.1em;
}
.faq div.a {
border-bottom: 1px #cdd4d9 solid;
display: none;
padding-bottom:0;
}
.faq h4.q i {
color: #bdc4c9;
position:absolute;
right:1.25em;
top:1.25em;
}
<div class="faq">
<h4 class="q">Question 1<i class="fa fa-chevron-down"></i></h4>
<div class="a">
<p>Answer 1</p>
</div>
<h4 class="q">Question 2<i class="fa fa-chevron-down"></i></h4>
<div class="a">
<p>Answer 2</p>
</div>
<h4 class="q">Question 3<i class="fa fa-chevron-down"></i></h4>
<div class="a">
<p>Answer 3</p>
</div>
</div>

You should remove .q from this .children('.q i'):
var i = $(this).children('i');
because $(this) is the .q element itself.

Related

Insert place holder between two div element using javascript Drag and Drop

I am trying to make my own custom drag and drop with html and Javascript drag and drop I have prepared a snippet:
/* draggable element */
var tempParentContainer = '';
var placeholder = document.createElement('div');
placeholder.className = 'drag-state-placeholder';
function enableDragDrop(containerClass, draggableClass) {
let tempElem = document.querySelectorAll(draggableClass);
tempElem.forEach(item => {
item.addEventListener('dragstart', dragStart);
});
let tempContainer = document.querySelectorAll(containerClass);
tempContainer.forEach(box => {
box.addEventListener('dragenter', dragEnter)
box.addEventListener('dragover', dragOver);
box.addEventListener('dragleave', dragLeave);
box.addEventListener('drop', drop);
});
}
function dragStart(e) {
tempParentContainer = e.target.parentNode;
e.dataTransfer.setData('text/plain', e.target.id);
setTimeout(() => {
e.target.classList.add('hide');
placeholder.style.height = e.target.clientHeight + 'px';
tempParentContainer.appendChild(placeholder);
}, 0);
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
}
function dragEnter(e) {
e.preventDefault();
}
function dragOver(e) {
e.preventDefault();
e.currentTarget.appendChild(placeholder);
}
function dragLeave(e) {
e.preventDefault();
}
function drop(e) {
placeholder.remove();
// get the draggable element
const id = e.dataTransfer.getData('text/plain');
const draggable = document.getElementById(id);
// add it to the drop target
e.currentTarget.appendChild(draggable);
// display the draggable element
draggable.classList.remove('hide');
}
.view_container {
width: 100%;
}
.data-container {
transform: scale(1);
width: fit-content;
background: rgb(255, 255, 255);
display: flex;
flex: 0 0 100%;
height: 100%;
min-width: 1px;
overflow: auto;
position: relative;
margin: 0 10px;
transform-origin: left top;
transition: 0.3s;
}
.table-main {
position: relative;
border-collapse: separate;
display: table;
white-space: normal;
width: 100%;
}
.table-head {
display: table-header-group;
vertical-align: middle;
}
.table-tr {
display: table-row;
vertical-align: inherit;
height: 100%;
}
.table-body {
display: table-row-group;
vertical-align: middle;
}
.table-th {
min-width: 330px;
background-color: #607d8b;
color: #fff;
border-right: 2px solid rgb(255, 255, 255);
border-bottom: 0px solid rgb(255, 255, 255);
z-index: 3;
padding: 0;
height: 30px;
line-height: 30px;
vertical-align: top;
display: table-cell;
padding: 10px;
}
.table-td {
display: table-cell;
vertical-align: top;
border-bottom: 4px solid rgb(255, 255, 255);
border-right: 4px solid rgb(255, 255, 255);
padding: 10px;
min-height: 153px;
background-color: rgb(243, 243, 243);
min-width: 301px;
max-width: 301px;
}
.drag-state-placeholder {
background-color: #fbf9ed;
border: 1px dashed rgb(177, 147, 59) !important;
}
.resourceDropLi {
border: 1px solid #e7e7e7;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<div class="view_container">
<div class="data-container" id="board-container">
<div class="table-main h-100">
<div class="table-head">
<div class="table-tr" id="laneContainer">
<div class="table-th">
<label>first</label>
</div>
<div class="table-th">
<label>Second</label>
</div>
<div class="table-th">
<label>third</label>
</div>
<div class="table-th">
<label>fourth</label>
</div>
<div class="table-th">
<label>fifth</label>
</div>
<div class="table-th">
<label>sixth</label>
</div>
<div class="table-th">
<label>seventh</label>
</div>
<div class="table-th">
<label>eirght</label>
</div>
</div>
</div>
<div class="table-body" id="storyContainer">
<div class="table-td ui-sortable">
<div class="resourceDragDrop" draggable="true">
<p>
item f1
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item f2
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item f3
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item f4
</p>
</div>
</div>
<div class="table-td ui-sortable">
<div class="resourceDragDrop" draggable="true">
<p>
item s1
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item s2
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item s3
</p>
</div>
</div>
<div class="table-td ui-sortable">
<div class="resourceDragDrop" draggable="true">
<p>
item t1
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item t2
</p>
</div>
</div>
<div class="table-td ui-sortable">
<div class="resourceDragDrop" draggable="true">
<p>
item f1
</p>
</div>
</div>
<div class="table-td ui-sortable">
<div class="resourceDragDrop" draggable="true">
<p>
item fi1
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item fi2
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item fi3
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item fi4
</p>
</div>
<div class="resourceDragDrop" draggable="true">
<p>
item fi5
</p>
</div>
</div>
<div class="table-td ui-sortable">
<div class="resourceDragDrop" draggable="true">
<p>
item s1
</p>
</div>
</div>
<div class="table-td ui-sortable">
<div class="resourceDragDrop" draggable="true">
<p>
item sev1
</p>
</div>
</div>
<div class="table-td ui-sortable">
<div class="resourceDragDrop" draggable="true">
<p>
item e1
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
$(document).ready(function() {
enableDragDrop('.table-td', '.resourceDragDrop');
});
</script>
</html>
I want drag an item from one container to another and in the same container as well like jQuery sortable plugin.
when I drag an item from one container to another is working fine but I am able to drop it at the last position of the container.
Here I am facing an issue while I am dragging an item I want to place it any where I want, like between elements or the first position or between other elements.
I don't know how to make it work anyone please help me
Thanks
I think the problem is that you only have 1 element with the ability to accept a drop: the container. That element cannot "tell" any more granular position than you've already done.
You should enable the singular items to handle dragover and/or drop, and create a rule, like: if the element is dropped on another element, then it goes before that element; if it's dropped on the container, then it goes at the end. This rule handles all positions in your list.
function dragStart({
originalEvent: e
}) {
e.dataTransfer.setData("text/plain", e.target.id)
e.dataTransfer.effectAllowed = 'move'
}
jQuery(document).ready(function($) {
$('.draggable').on('dragstart', dragStart);
$('.droppable').on('dragover', function(e) {
e.preventDefault()
$(this).css('background', 'rgba(0, 0, 0, 0.25)')
})
$('.droppable').on('dragenter', function(e) {
e.preventDefault()
$(this).css('background', 'rgba(0, 0, 0, 0.25)')
})
$('.droppable').on('dragleave', function(e) {
e.preventDefault()
$(this).css('background', 'white')
})
$('.droppable').on('drop', function(e) {
// stop propagation so you don't trigger drop more than once
// if the drop zone is inside another drop zone
e.stopPropagation()
const draggedId = e.originalEvent.dataTransfer.getData("text")
// here's the rule I wrote: if it's a column, then
// the dragged item is appended, if it's not a column
// then the dragged item is inserted before
// the item it's dropped on
if (!$(e.target).hasClass('column')) {
$(e.target).before($(`#${ draggedId }`))
$(this).parent().css('background', 'white')
} else {
$(e.target).append($(`#${ draggedId }`))
}
$(this).css('background', 'white')
})
});
#container {
width: 100%;
height: 100%;
display: flex;
justify-content: space-around;
background: white;
}
.column {
border: 1px solid black;
display: flex;
flex-direction: column;
padding: 8px 16px;
}
.draggable {
border: 1px solid black;
padding: 8px 16px;
display: block;
background: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div class="column droppable">
<div id="left-1" class="draggable droppable" draggable="true">
left 1
</div>
<div id="left-2" class="draggable droppable" draggable="true">
left 2
</div>
</div>
<div class="column droppable">
<div id="center-1" class="draggable droppable" draggable="true">
center 1
</div>
<div id="center-2" class="draggable droppable" draggable="true">
center 2
</div>
</div>
<div class="column droppable">
<div id="right-1" class="draggable droppable" draggable="true">
right 1
</div>
<div id="right-2" class="draggable droppable" draggable="true">
right 2
</div>
</div>
</div>

jQuery .toggleClass not working as expected

I have created a mini tab filter but it's not working as correctly. It only works when you click and unclick one tab at a time. Right now if you click on a tab and then another tab, the content from the previous clicked tab still shows also the previous clicked tab keeps the class "current" when it's not suppose too. I tried fixing this with the commented JS code but that makes the whole thing untoggleble. Thanks!
$(document).ready(function () {
$('.tab').click(function () {
var tabID = $(this).data('tabid');
// $('.iconsContainer').children().removeClass('current');
$(this).toggleClass('current');
// $('.iconContainerMore').removeClass('hideMoreText');
$('.iconContainerMore', this).toggleClass('hideMoreText');
// $('.tripctychContent-container').children().removeClass('showText');
$('.tripctychContent-container').find("[data-blockid=" + tabID + "]").toggleClass('showTopicContent');
});
});
.hideMoreText{
display: none;
}
.hideTopicContent{
display: none;
}
.showTopicContent{
display: block;
}
.tab{
cursor: pointer;
}
.iconsContainer{
display: flex;
justify-content: space-between;
}
.tab p:first-of-type{
padding: 30px;
background: blue;
color: white;
}
.current p:first-of-type{
background: black !important;
}
.tripctychContent-container p{
background: red;
color: white;
}
p{
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="iconsContainer">
<a class="tab" data-tabid="topic1">
<div>
<p>Topic 1 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
<a class="tab" data-tabid="topic2">
<div>
<p>Topic 2 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
<a class="tab" data-tabid="topic3">
<div>
<p>Topic 3 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
</div>
<div class="tripctychContent-container">
<div class="field--name-field-topic-1-content hideTopicContent" data-blockid="topic1">
<p>Topic 1 body</p>
</div>
<div class="field--name-field-topic-2-content hideTopicContent" data-blockid="topic2">
<p>Topic 2 body</p>
</div>
<div class="field--name-field-topic-3-content hideTopicContent" data-blockid="topic3">
<p>Topic 3 body</p>
</div>
</div>
Your code does not remove current from other "tab"s - nor does it remove hwoTopicContent from other tab contents .. it only toggles the tab you click
The following works
$(document).ready(function () {
$('.tab').click(function () {
var tabID = $(this).data('tabid');
var isCurrent = !$(this).hasClass('current');
$('.tab').removeClass('current');
$(this).toggleClass('current', isCurrent);
$('.iconContainerMore').removeClass('hideMoreText');
$('.iconContainerMore', this).toggleClass('hideMoreText', isCurrent);
// $('.tripctychContent-container').children().removeClass('showText');
$('.tripctychContent-container>div').removeClass('showTopicContent');
$('.tripctychContent-container').find("[data-blockid=" + tabID + "]").toggleClass('showTopicContent', isCurrent);
});
});
.hideMoreText{
display: none;
}
.hideTopicContent{
display: none;
}
.showTopicContent{
display: block;
}
.tab{
cursor: pointer;
}
.iconsContainer{
display: flex;
justify-content: space-between;
}
.tab p:first-of-type{
padding: 30px;
background: blue;
color: white;
}
.current p:first-of-type{
background: black !important;
}
.tripctychContent-container p{
background: red;
color: white;
}
p{
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="iconsContainer">
<a class="tab" data-tabid="topic1">
<div>
<p>Topic 1 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
<a class="tab" data-tabid="topic2">
<div>
<p>Topic 2 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
<a class="tab" data-tabid="topic3">
<div>
<p>Topic 3 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
</div>
<div class="tripctychContent-container">
<div class="field--name-field-topic-1-content hideTopicContent" data-blockid="topic1">
<p>Topic 1 body</p>
</div>
<div class="field--name-field-topic-2-content hideTopicContent" data-blockid="topic2">
<p>Topic 2 body</p>
</div>
<div class="field--name-field-topic-3-content hideTopicContent" data-blockid="topic3">
<p>Topic 3 body</p>
</div>
</div>
It is simple. Just remove all classes and set only to current.
$('.tab').click(function () {
var tabID = $(this).data('tabid');
// remove all already set classes
$('.iconContainerMore').removeClass('hideMoreText');
$('.tripctychContent-container').find("[data-blockid]").removeClass('showTopicContent');
// show current
$('.iconContainerMore', this).addClass('hideMoreText');
$('.tripctychContent-container').find("[data-blockid=" + tabID + "]").addClass('showTopicContent');
});

switch between 2 div's

I want to switch between 2 div's so that when I click on one of them its border and header became red and I want the other div goes off. so its be like a choice between them I don't know where I'm doing it wrong I add (IF) so I can make it happen but it is not working pls help me.
$(".container").on("click" , function(){
$(this).toggleClass("active");
$(".header", this).toggleClass("active2");
if ($(".box1").hasClass("active")) {
$(".box2").removeClass("active");
$("h2", ".box2").removeClass("active2");
}if ($(".box2").hasClass("active")) {
$(".box1").removeClass("active");
$("h2", ".box1").removeClass("active2");
}
});
body{
padding: 3em;
}
.box1, .box2{
padding: 2em;
border: 1px solid silver;
margin-top: 2em;
}
.active{
border-color: red;
}
.active2{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container box1">
<h2 class="header">Boys</h2>
<hr>
<p>Benjamin</p>
<p>David</p>
</div>
<div class="container box2">
<h2 class="header">Girls</h2>
<hr>
<p>Sara</p>
<p>Tania</p>
</div>
You don't need to many code to do this work. Add .active to clicked element and remove class from sibling of it.
$(".container").on("click", function() {
$(this).toggleClass("active").siblings().removeClass("active");
});
body{padding: 3em}
.box1, .box2{
padding: 2em;
border: 1px solid silver;
margin-top: 2em;
}
.active {border-color: red}
.active .header{color: red}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container box1">
<h2 class="header">Boys</h2>
<hr>
<p>Benjamin</p>
<p>David</p>
</div>
<div class="container box2">
<h2 class="header">Girls</h2>
<hr>
<p>Sara</p>
<p>Tania</p>
</div>

Open specific Accordion menu

I'd like to visit my site: http://testsite.com/#accordion2 and for it to anchor down & open the 2nd accordion. How do I achieve this? I'd also like this to happen for the first accordion if the url was #accordion1.
Here's my Fiddle: http://jsfiddle.net/jmjmotb3/
function close_accordion_section(source) {
$(source).parent().find('.accordion-section-title').removeClass('active');
$(source).parent().find('.accordion-section-content').slideUp(300).removeClass('open');
}
$('.accordion-section-title').click(function(e) {
if($(e.target).is('.active')) {
close_accordion_section(e.target);
}else {
$(this).addClass('active');
$(e.target).parent().find('.accordion-section-content').slideDown(300).addClass('open')
}
e.preventDefault();
});
.accordion {
overflow: hidden;
margin-bottom: 40px;
}
.accordion-section {
padding: 15px;
border: 1px solid #d8d8d8;
background: #fbfbfb;
}
.accordion-section-title {
width: 100%;
display: inline-block;
background: url("http://placehold.it/50x50") top right no-repeat;
}
.accordion-section-title.active, .accordion-section-title:hover {
text-decoration: none;
}
.accordion-section-content {
padding: 15px 0;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="accordion1" class="accordion">
<div class="accordion-section">
<a class="accordion-section-title" href="#accordion-1">More information</a>
<div id="accordion-1" class="accordion-section-content">
<p>Text.</p>
<p>
</div>
</div>
</div>
<div id="accordion2" class="accordion">
<div class="accordion-section">
<a class="accordion-section-title" href="#accordion-1">More information 2</a>
<div id="accordion-1" class="accordion-section-content">
<p>Text.</p>
<p>
</div>
</div>
</div>
Check the window.location.hash property and go from there.
document.addEventListener('DOMContentLoaded', function() {
if (window.location.hash === 'x') {
// do x
}
});

Spacing on elements added with Javascript is inconsistent

I am dynamically adding elements into another element and there are some inconsistencies with the spacing. The more elements I add, the less spacing there is.
Here is what it looks like:
After the third element, the spacing is like the above image (it doesn't go negative). My question is two fold: 1. Why is this happening; 2. How do I fix it?
As a note, the default layout has one element, and when you click on the "add new route" button, it adds another route (there are 2, there are 3). I have tried setting the spacing and margins to negative numbers. I've tried putting comments in after the spot I add the new element. I'm out of ideas.
Here is my HTML:
<div id="main">
<div id="calendar">
<div class="column" id="time_slots">
</div>
<div class="column" id="day1">
<div class="date"></div>
<button class="add_route" name="add_route" onclick="">Add New Route</button>
<div class = "truck" id="day1_route1">
<p>This is truck one</p>
</div>
</div>
<div class="column" id="day2">
<div class="date"></div>
<button class="add_route" name="add_route">Add New Route</button>
<div class = "truck" id="day2_route1">
<p>This is truck one</p>
</div>
</div>
<div class="column" id="day3">
<div class="date"></div>
<button class="add_route" name="add_route">Add New Route</button>
<div class = "truck" id="day3_route1">
<p>This is truck one</p>
</div>
</div>
<div class="column" id="day4">
<div class="date"></div>
<button class="add_route" name="add_route">Add New Route</button>
<div class = "truck" id="day4_route1">
<p>This is truck one</p>
</div>
</div>
<div class="column" id="day5">
<div class="date"></div>
<button class="add_route" name="add_route">Add New Route</button>
<div class = "truck" id="day5_route1">
<p>This is truck one</p>
</div>
</div>
<div class="column" id="day6">
<div class="date"></div>
<button class="add_route" name="add_route">Add New Route</button>
<div class = "truck" id="day6_route1">
<p>This is truck one</p>
</div>
</div>
<div class="column" id="day7">
<div class="date"></div>
<button class="add_route" name="add_route">Add New Route</button>
<div class = "truck" id="day7_route1">
<p>This is truck one</p>
</div>
</div>
<div class="column" id="time_slots">
</div>
</div>
</div>
Here is my CSS:
.label
{
width:20px;
}
.table
{
font-size: 1.2em;
}
#main
{
border-style: solid;
border-width: 1px;
border-color: black;
width:97%;
height:900px;
margin:auto;
overflow: auto;
white-space: nowrap;
}
#calendar
{
padding:1%;
}
.column
{
border-style: solid;
border-width: 1px;
border-color: black;
min-width:10%;
max-width:100%;
height:800px;
display: inline-block;
overflow: auto;
padding:10px;
}
.header
{
padding:0;
margin:0;
text-align: center;
font-style: bold;
}
.truck
{
width:200px;
border-style: solid;
border-width: 1px;
border-color: black;
display:inline-block;
margin:0px;
}
.column#time_slots
{
width:5%;
min-width:5%;
max-width: 10%;
}
.date
{
text-align: center;
width:100%;
}
.column button
{
display:block;
width:100%;
width:100%;
border-style: solid;
border-width: 1px;
border-color: black;
}
Here is the Javascript:
$(".add_route").click(function(){
var num = 8;
var truck = $(this).parent().find('.truck').length
truck += 1;
var w = $(this).parent().width();
$(this).parent().animate({width:(w+205)}, 1000);
$(this).parent().append('<div class = "truck" id="'+$(this).parent().attr('id')+'_route'+truck+'"><p>There are '+ truck +'</p></div>');
$('#'+$(this).parent().attr('id')+'_route'+truck).hide();
var route_num = $(this).parent().find('.truck').length;
var route_w = (100/route_num)-1;
$('#'+$(this).parent().attr('id')+'_route'+truck).fadeIn(200);
$(this).parent().css("padding", "10px");
});
Here is the demo: http://jsfiddle.net/pfdNy/

Categories

Resources