Spacing on elements added with Javascript is inconsistent - javascript

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/

Related

Dragged div not being dropped correctly

I am using javascript drag and drop API to recreate a similar board from this website: http://en.battleship-game.org/
The below code shows how I tried implementing it
const ship = document.querySelector('.ship');
const cells = document.querySelectorAll('.cell');
ship.addEventListener("dragstart",(e)=>{
e.dataTransfer.setData('text/plain',e.target.id);
});
cells.forEach((cell)=>{
cell.addEventListener('dragenter',dragEnter);
cell.addEventListener('dragover',dragOver);
cell.addEventListener('dragleave',dragLeave);
cell.addEventListener('drop',drop);
});
function dragEnter(e){
e.preventDefault();
e.target.classList.add('drag-over');
console.log('drag enter');
}
function dragOver(e) {
e.preventDefault();
e.target.classList.add('drag-over');
}
function dragLeave(e) {
e.target.classList.remove('drag-over');
}
function drop(e) {
e.target.classList.remove('drag-over');
// get the draggable element
const id = e.dataTransfer.getData('text/plain');
const draggable = document.getElementById(id);
// add it to the drop target
e.target.appendChild(draggable);
}
.row{
display: flex;
}
.cell{
background-color: lightblue;
width: 32px;
height: 32px;
border: 1px solid black;
user-select: none;
position: relative;
}
.ship{
z-index: 2;
display: flex;
position: absolute;
top: 0;
left: 0;
cursor: move;
}
.ship>div{
background-color: rgb(255, 221, 226);
border: 1px solid black;
width: 32px;
height: 32px;
}
.drag-over {
border: dashed 3px red;
}
<div class="row">
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell"> </div>
</div>
<div class="row">
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell">
<div class="ship" draggable="true" id="ship">
<div> </div>
<div> </div>
<div> </div>
</div>
</div>
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell"> </div>
</div>
<div class="row">
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell"> </div>
<div class="cell"> </div>
</div>
When I drag and drop the 3rd pink box I want it to not drop with respect to the first pink box. How can this be done?
Dashed red border shows wrt to which box the pink div will be placed

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>

How to hide previous div in javascript?

I have 4 div. When I click on one of the divs the green shown will expand. Then I click on another diva and a green background with subtitles will also be shown. I mean, I want only one div to be expanded. For example, if I click the 3 div it expands me the content of the 3 diva. Then I click the 2 div and it expands me the content of the 2 diva and automatically hides the content of the previous div that was expanded. I hope that everone understand what I want to do.
<script>
function showHide(obj)
{
var nextObj=obj.nextSibling;
while(!nextObj.tagName) nextObj=nextObj.nextSibling;
nextObj.style.display = nextObj.style.display != 'block' ? 'block' : 'none';
}
</script>
.iptv{
width:200px;
height:50px;
background-color:blue;
margin-bottom:10px;
color:white;
margin-left:auto;
margin-right:auto;
}
.drop{
background-color:green;
width:200px;
height:50px;
margin-left:auto;
margin-right:auto;
}
a{
text-decoration: none;
color:white;
}
<body>
<div class="down">
<div onclick="showHide(this)" class="iptv">Button1</div>
<div class="drop" style="display:none">
Home
About
Contact
</div>
</div>
<div class="down">
<div onclick="showHide(this)" class="iptv">Button2</div>
<div class="drop" style="display:none">
Home
About
Contact
</div>
</div>
<div class="down">
<div onclick="showHide(this)" class="iptv">Button3</div>
<div class="drop" style="display:none">
Home
About
Contact
</div>
</div>
<div class="down">
<div onclick="showHide(this)" class="iptv">Button4</div>
<div class="drop" style="display:none">
Home
About
Contact
</div>
</div>
</body>
There are a couple of errors in your code:
The divs weren't "closed"
It's not obj.nextSibling, but obj.nextElementSibling (there's a difference: What is the difference between node.nextSibling and ChildNode.nextElementSibling?)
After correcting these errors and adding the code for closing the other divs, the snippet works:
function showHide(obj) {
const nextObj = obj.nextElementSibling;
const dropDowns = document.querySelectorAll('.drop')
dropDowns.forEach(e => {
e.style.display = 'none'
})
nextObj.style.display = 'block'
}
.iptv {
width: 200px;
height: 50px;
background-color: blue;
margin-bottom: 10px;
color: white;
margin-left: auto;
margin-right: auto;
}
.drop {
background-color: green;
width: 200px;
height: 50px;
margin-left: auto;
margin-right: auto;
}
a {
text-decoration: none;
color: white;
}
<div class="down">
<div onclick="showHide(this)" class="iptv">Button1</div>
<div class="drop" style="display:none">
Home
About
Contact
</div>
</div>
<div class="down">
<div onclick="showHide(this)" class="iptv">Button2</div>
<div class="drop" style="display:none">
Home
About
Contact
</div>
</div>
<div class="down">
<div onclick="showHide(this)" class="iptv">Button3</div>
<div class="drop" style="display:none">
Home
About
Contact
</div>
</div>
<div class="down">
<div onclick="showHide(this)" class="iptv">Button4</div>
<div class="drop" style="display:none">
Home
About
Contact
</div>
</div>

jQuery accordian arrow toggle

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.

Auto-scroll to a div when clicking on another div

When I click on one of the smaller divs on the left (inside of the div with the class "smallitems", I want for the div on the right (with the class "items") to auto-scroll to the appropriate larger div.
HTML:
<div class="smallitems">
<div class="col">1</div>
<div class="col"> 2 </div>
<div class="col"> 3</div>
<div class="col">4</div>
<div class="col"> 5 </div>
<div class="col">6 </div>
<div class="col"> 7</div>
<div class="col">8</div>
</div>
<div class="items">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">5</div>
</div>
JavaScript (with JQuery):
$('.smallitems .col').on("click", function(){
//how use scroll items show
});
Example:
This is before I click on a div in the left div ("smallitems").
I've now clicked on the number 5 (<div class="col">5</div>) in the left div. As you can see the right div has scrolled to the 5th div (<div class="item">5</div>).
Similar to the above, I've clicked on the number 4, and subsequently have had the right div auto-scroll to the 4th div.
see jfiddle http://jsfiddle.net/h7bLK/
This can be done with anchors. If you replace your div.cols with anchor tags and add an ID to your div.items like this:
<div class="smallitems">
<a class="col" href="#item1">1</a>
<a class="col" href="#item2">2</a>
. . .
</div>
<div class="items">
<div class="item" id="item1">1</div>
<div class="item" id="item2">2</div>
. . .
</div>
Fiddle link
BONUS: You'll be able to link externally to the correct item.
CONS: If the content is smaller than the frame it is rendered in, the whole frame will scroll.
According to requirement, no-need to use javascript or jquery. Its done only using css.
<div class="main-container">
<div class="smallitems">
<div class="col">1</div>
<div class="col"> 2 </div>
<div class="col last-child">3</div>
<div class="col">4</div>
<div class="col">5 </div>
<div class="col last-child">6 </div>
<div class="col"> 7</div>
<div class="col">8</div>
</div>
<div class="items">
<div class="scroll">
<div class="item" id="one">1</div>
<div class="item" id="two">2</div>
<div class="item" id="three">3</div>
<div class="item" id="four">4</div>
<div class="item" id="five">5</div>
<div class="item" id="six">6</div>
<div class="item" id="seven">7</div>
<div class="item" id="eight">8</div>
</div>
</div>
</div>
**Css** :
.main-container{
margin: 20px auto;
width:960px;
overflow: hidden;
border: 1px solid #bababa;
padding: 5px;
}
.smallitems{
overflow: hidden;
float: left;
width:330px;
border: 1px solid #bababa;
display: table;
padding: 10px;
}
.col a{
display: block;
padding: 41px 0;
text-decoration: none;
}
.col{
float:left;
display: table-cell;
vertical-align: middle;
text-align: center;
font-size: 14px;
font-weight: 700;
cursor: pointer;
border: 1px solid #bababa;
height: 100px;
width: 100px;
margin: 0 10px 10px 0;
}
.items{
float: right;
width:580px;
border: 1px solid #bababa;
overflow-y: hidden;
white-space: nowrap;
padding: 10px;
}
.col:nth-child(3),.last-child{
margin-right: 0;
}
.item{
display: inline-block;
text-align: center;
position:relative;
font-size: 14px;
font-weight: 700;
border: 1px solid #bababa;
height: 440px;
width: 180px;
margin: 0 10px 10px 0;
}
$('.smallitems .col').on("click", function(){
var index = $(this).index();
var items = $('.items');
var item = items.children().eq(index);
items.scrollLeft((item.width() - 50) * index);
});
When you add a new div to the items play around with the value of 50.
<div class="container">
<div class="smallitems">
<div class="col">1</div>
<div class="col"> 2 </div>
<div class="col"> 3</div>
<div class="col">4</div>
<div class="col"> 5 </div>
<div class="col">6 </div>
<div class="col"> 7</div>
<div class="col">8</div>
</div>
<div class="items" id="maindiv"> // set id
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">5</div>
</div>
</div>
$('.smallitems').on("click", function(e){
// get click element text and calculate scrollLeft
var scrollLeft = (parseInt($(e.target).text())-1) * 200;
// use jquery animation function
$('#maindiv').animate({scrollLeft :scrollLeft},1100)
});

Categories

Resources