When I add a Card in in-box list via button (Add a card), the card is sortable between the different lists. This works fine. The problem comes, when I try to drag an item from member list and drop it to the card. It doesn't work.
Here is the Demo
HTML:
<body>
<div id="wrapper">
<div id="inboxList" class="cellContainer">
<p style="display: inline;">Inbox</p>
<button id="AddCardBtn">
Add A Card...
</button>
<div id="userAddedDiv"></div>
</div>
<!--Member list-->
<div id="members" class="cellContainer">
<br style="line-height: 23px" />
<p>Members</p>
<div class="draggable">1</div>
<div class="draggable">2</div>
<div class="draggable">3</div>
</div>
<div id="onHoldList" class="cellContainer">
<p>On Hold</p>
</div>
<div id="Done" class="cellContainer">
<p>On Hold</p>
</div>
</div>
</body>
Jquery:
$(function () {
$('.cellContainer').sortable({
items: '.sortable-div',
containment: 'document',
cursor: 'crosshair',
opacity: '0.70',
connectWith: '.cellContainer',
hoverClass: '.border'
});
});
$(".draggable").draggable({ revert: "invalid", snap: "true", snapMode: "inner", helper: 'clone' });
$(".sortable-div").droppable({
accept: '.draggable',
drop: function (event, ui) {
ui.helper.css('top', '');
ui.helper.css('left', '');
$(this).find('.bottom').prepend(ui.helper);
}
});
CSS:
#members, #onHoldList, #Done {
width: 275px;
height: 230px;
background-color: #f0f0f0;
border: 1px solid black;
margin-left: 1%;
margin-top: 0.4%;
border-radius: 10px;
box-shadow: 7px 7px 7px #828282;
overflow: auto;
}
#inboxList {
width: 275px;
height: 230px;
background-color: #f0f0f0;
border: 1px solid black;
margin-left: 0.5%;
margin-top: 0.4%;
border-radius: 10px;
box-shadow: 7px 7px 7px #828282;
overflow: auto;
}
.cellContainer .sortable-div {
background: red;
width: 260px;
height: 150px;
margin-left: 2.3%;
border-radius: 10px;
border: 2px solid black;
box-shadow: 0px 7px 7px #828282;
margin-bottom: 1%;
}
.draggable {
display:inline-block;
border:1px solid blue;
height: 50px;
width: 50px;
margin-right: 1px;
text-align: center;
vertical-align: center;
}
.bottom {
position: absolute;
bottom: 0;
height:25px;
width:150px;
}
The problem is because your are creating items dynamically and they have not automatically the droppable enabled. To do so attach the droppable when you create the new element.
To handle the sortable feature of the board when you drop, clone the element anche change its position to relative.
Code:
$('#AddCardBtn').click(function () {
var numberOfDiv = [100];
with(document) {
var $newDiv = $('<div />').addClass('sortable-div');
$('#userAddedDiv').append($newDiv)
$newDiv.droppable({
accept: '.draggable',
drop: function (event, ui) {
$(this).append($(ui.helper).clone().css({position: 'relative', top: '0', left:'0'}));
}
});
for (var i = 0; i < numberOfDiv; i++) {
numberOfDiv[i] = $newDiv;
}
}
});
Demo: http://jsfiddle.net/IrvinDominin/zjBP2/
Related
Hi guys I've been working on this project that saves the position of the drag and drop and i was wondering if there is away to save is position to a text or excel file giving you the time of the move.
i.e DIV 1 was moved to A at 09:00, DIV 1 was moved from A to B at 09:15 if that makes sense.
Couldn't figure it out.
<html>
<head>
<\head>
<style>
#draggable1 {
position: fixed;
bottom: 0;
margin: 1px 0;
padding: 0 20px;
height: 20px;
width: 50px;
line-height: 20px;
border-radius: 1px;
background: #136a8a;
background: -webkit-linear-gradient(to right, #267871, #136a8a);
background: linear-gradient(to right, #267871, #136a8a);
color: #fff;
list-style: none;
}
.draggable {
width: 90px;
height: 90px;
padding: 0.5em;
float: left;
margin: 0 10px 10px 0;
}
#draggable,
#draggable2 {
margin-bottom: 20px;
}
#draggable {
cursor: n-resize;
}
#draggable3 {
cursor: move;
}
#containment-wrapper {
width: 700px;
height: 500px;
border: 1px solid #000;
padding: 5px;
}
h3 {
clear: left;
}
#box {
position: absolute;
width: 100px;
height: 100px;
background-color: #ccc;
}
<\style>
<body>
<ul class="drag-sort-enable">
<li0 id="draggable1" class="draggable ui-widget-content" input type="text" >659451</li0>
</body>`
<script>
var sPositions = localStorage.positions || "{}",
positions = JSON.parse(sPositions);
$.each(positions, function(id, pos) {
$("#" + id).css(pos)
})
$("#draggable1").draggable({
containment: "#containment-wrapper",
scroll: false,
stop: function(event, ui) {
positions[this.id] = ui.position
localStorage.positions = JSON.stringify(positions)
}
});
<\script>
I have a masonry layout (using the library from here), that when a user clicks a tile, only one tile should be able to expand at a time. If the user clicks another tile, the previously opened tile should close. How can I check for any previously opened tiles, close them, and then open the newly selected tile?
// external js: masonry.pkgd.js
var grid = document.querySelector('.grid');
var msnry = new Masonry( grid);
grid.addEventListener( 'click', function( event ) {
// don't proceed if item was not clicked on
if ( !matchesSelector( event.target, '.grid-item' ) ) {
return;
}
// change size of item via class
event.target.classList.toggle('grid-item--gigante');
// trigger layout
msnry.layout();
});
.grid {
background: #eee;
width: 1200px;
margin: 0 auto;
}
.grid-holder {
background: #fff;
margin: 0 auto;
display: block;
}
.grid-item {
width: 375px;
height: 375px;
margin-bottom: 4%;
float: left;
border: 1px solid #ddd;
margin-right: 10px;
background-color: #eee;
box-shadow: 2px 2px 2px 2px #eee;
}
.grid-item--gigante {
max-width: 600px;
min-width: 100px;
width: 63%;
min-height: 375px;
height: auto;
margin-left: 8px;
background-color: rgba(215, 210, 203, 0.3) !important;
color: #666;
border: 1px solid #ddd;
padding: 0.5% 8% 2.5% 5%;
z-index: 2; /* above other items */
}
.grid-item:hover {
background: #a2c;
border-color: white;
cursor: pointer;
}
<script src="https://masonry.desandro.com/masonry.pkgd.js"></script>
<div class="grid">
<div class="grid-holder">
<div class="grid-item">Jim</div>
<div class="grid-item">Joe</div>
<div class="grid-item">John</div>
<div class="grid-item">James</div>
<div class="grid-item">Jack</div>
<div class="grid-item">Joseph</div>
</div>
</div>
You need to keep a reference to previously enlarged grid item.
Whenever the click event occurs, check if current event target is equal to previously enlarged grid item or not. If it is not, remove .grid-item--gigante class from previously enlarged grid item and update the reference to previously enlarged grid item to now point to event.target.
P.S. removed some CSS to make the example code snippet easy to understand.
var grid = document.querySelector('.grid');
var msnry = new Masonry(grid);
var previouslyEnlarged;
grid.addEventListener('click', function(event) {
if ( !matchesSelector( event.target, '.grid-item' ) ) {
return;
}
if (previouslyEnlarged == event.target) {
return;
} else if (previouslyEnlarged) {
previouslyEnlarged.classList.remove('grid-item--gigante');
}
previouslyEnlarged = event.target;
event.target.classList.toggle('grid-item--gigante');
msnry.layout();
});
.grid-holder {
background: #fff;
margin: 0 auto;
display: block;
}
.grid-item {
width: 50px;
height: 50px;
margin-bottom: 4%;
float: left;
border: 1px solid #ddd;
margin-right: 10px;
background-color: #eee;
box-shadow: 2px 2px 2px 2px #eee;
}
.grid-item--gigante {
width: 100px;
height: 100px;
margin-left: 8px;
background-color: rgba(215, 210, 203, 0.3) !important;
color: #666;
border: 1px solid #ddd;
padding: 0.5% 8% 2.5% 5%;
z-index: 2;
}
.grid-item:hover {
background: #a2c;
border-color: white;
cursor: pointer;
}
<script src="https://masonry.desandro.com/masonry.pkgd.js"></script>
<div class="grid">
<div class="grid-holder">
<div class="grid-item">Jim</div>
<div class="grid-item">Joe</div>
<div class="grid-item">John</div>
<div class="grid-item">James</div>
<div class="grid-item">Jack</div>
<div class="grid-item">Joseph</div>
</div>
</div>
I'm trying to append draggable items to an area. That's easy. The issue is that the DOM doesn't seem to be up to date.
https://codepen.io/anon/pen/OxQxJN?editors=0010
The issue:
- Append first element, drag that element to the bottom on the area.
- Append a second element. It is positioned relative, but instead of appearing at the top of the area as expected it appears below where the first element was. It's like a ghost.
Any ideas how I can get the DOM to update so that the appended elements appear as expected?
$('.addWidget').click( (event) => {
let new_widget = `
<div class="widget_container draggable" style="height: 130px; width: 260px;">
<div class="widget">
<b>Amazing widget</b>
<p>My cool blah blah blah</p>
</div>
</div>`;
$('main').append(new_widget);
$(".draggable").draggable({
containment: 'parent',
snap: true,
grid: [72, 72]
});
});
.btn {
padding: 0.5rem;
background: #ccc;
}
.btn:hover {
background: #efefef;
}
.pane_content_dimension_list {
float:right;
list-style: none;
width: 10rem;
}
.pane_content_dimension_list .btn {
width: 100%;
margin-bottom: 0.5rem;
}
.page_view {
background: #f2f2f2;
border: 1px solid #e2e2e2;
box-shadow: -1px 1px 4px 2px #aaa;
box-sizing: border-box;
height: 792px;
width: 612px;
}
.page_view main {
height: 100%;
margin: 18px;
width: 100%;
}
.widget_container {
padding:9px;
}
.widget {
background: #fff;
box-shadow: 0 1px 2px 2px #eee;
color: #939598;
font-size: 8px;
height: 100%;
line-height: 11px;
padding: 4px;
width: 100%;
}
<ul class="pane_content_dimension_list">
<li id="campaign_goals" class="btn addWidget">Campaign Goals</li>
<li id="flight_dates" class="btn addWidget">Flight Dates</li>
<li id="key_findings" class="btn addWidget">Key Findings</li>
<li id="mindsets" class="btn addWidget">Mindsets</li>
<li id="targeting_notes" class="btn addWidget">Targeting</li>
</ul>
<div class="page_view">
<main>
</main>
</div>
I have a menu on the left where all the elements have the same class. I've added the event $('.menuitem').click and also tried several other options, even calling the event based on the div id but without success.
As there aren't any error messages on the browser console, I'm kinda lost on the search for the error. I appreciate if you could help me figure out what the problem is.
Here is the Fiddle
HTML:
<div class='mainwindow'>
<div class='menupane'>
<div id='entity' class='menuitem'><p class='glyphicon glyphicon-triangle-right'>ENTITIES</p></div>
<div class='menuitem'><p class='glyphicon glyphicon-triangle-right'>COURSES</p></div>
<div class='menuitem'><p class='glyphicon glyphicon-triangle-right'>STUDENTS</p></div>
<div class='menuitem'><p class='glyphicon glyphicon-triangle-right'>CLASSES</p></div>
<div class='menuitem'></div>
</div>
<div class='contentpane'></div>
</div>
DOM:
$(document).ready(function(){
console.log("loaded");
$('.menuitem').click(function(){
console.log("CLICKED 1");
});
$('#entity').click(function(){
console.log("CLICKED 2");
});
$('.menupane').on('click', '.menuitem', function(){
console.log('CLICKED 3');
});
});
As you can see, I tried adding the click event through several methods and I'm not getting it. Thanks a ton for your help.
Negative z-index will not let event to dispatch on elements.
$(document).ready(function() {
console.log("loaded");
$('.menuitem').click(function() {
console.log("CLICKED 1");
});
$('#entity').click(function() {
console.log("CLICKED 2");
});
$('.menupane').on('click', '.menuitem', function() {
console.log('CLICKED 3');
});
});
.header {
position: absolute;
background-color: #525252;
height: 5%;
width: 100%;
min-height: 30px;
display: block;
margin: 0;
z-index: 0;
font-weight: 700;
line-height: 175%;
font-size: 1.4em;
text-align: center;
color: #FFFFFF;
display: inline-block
}
.mainwindow .menupane {
position: relative;
display: inline-block;
width: 25%;
min-width: 200px;
background-color: #FFFFFF;
margin: 0;
box-shadow: 1px 0px 10px -0px #F5F5F5;
//z-index: -1;
padding-top: 40px;
}
.mainwindow .contentpane {
position: relative;
display: inline-block;
width: 100%;
background-color: #FFFFFF;
margin: 0;
//z-index: -2;
padding-top: 40px;
}
.menuitem {
background-color: #525252;
position: relative;
width: 75%;
height: 1.5em;
min-height: 10px;
border-radius: 0.65em;
margin: 7.5%;
color: lightgray;
/*font-size: 0.8vw;*/
/*line-height: 1.5em;*/
padding-left: 10%;
border: 0.05em solid lightgray;
/*box-shadow: 0px 0px 1px 1px gray;*/
}
glyphicon-triangle-right {
transition: transform 180ms ease-in;
}
glyphicon-triangle-right.rotate90 {
transform: rotate(90deg);
transition: transform 180ms ease-in;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class='header'>SISTEMA CONTROLE DE CURSOS</div>
<div class='mainwindow'>
<div class='menupane'>
<div id='entity' class='menuitem'>
<p class='glyphicon glyphicon-triangle-right'>ENTITIES</p>
</div>
<div class='menuitem'>
<p class='glyphicon glyphicon-triangle-right'>COURSES</p>
</div>
<div class='menuitem'>
<p class='glyphicon glyphicon-triangle-right'>STUDENTS</p>
</div>
<div class='menuitem'>
<p class='glyphicon glyphicon-triangle-right'>CLASSES</p>
</div>
<div class='menuitem'></div>
</div>
<div class='contentpane'></div>
</div>
Fiddle Demo
Your z-index CSS was causing issues. Here is an updated example without those so you can fix from there: https://jsfiddle.net/zxgkprw9/1/
your issue is not the binding of the event but the class .mainwindow .menupane having this property position: relative;
the events is added properly but due to this class the actual position of the element is different . Remove this property and all work fine
jsfiddle : https://jsfiddle.net/zxgkprw9/3/
.mainwindow .menupane{
display: inline-block;
width: 25%;
min-width: 200px;
background-color: #FFFFFF;
margin: 0;
box-shadow: 1px 0px 10px -0px #F5F5F5;
z-index: -1;
padding-top: 40px;
}
JSFiddle: http://jsfiddle.net/357nf0ht/4/
If you are hovering one of the .item, a menu will appear. Hovering the "X" will show you a button.
I expect, that hovering the button will create a single temporary item, which belongs to the first selected .item. But instead of that, there are multiple temporary items, if you have hovered more then one .item at the beginning. It seems, that this remembers also the events in the past.
I don't understand this behavior.
$(document).on('mouseenter', '.item', function (event) {
var item = $(this);
$('#item_add').css({
"left": '5.5em',
"top": item.offset().top - 15
}).show();
$('#item_add').hover(function () {
var menue = $(this);
menue.animate({
"width": '7em',
"left": '0.5em'
}, 200, function () {
$(this).find(".body").stop().slideDown(200);
});
}, function () {
var menue = $(this);
menue.find(".body").stop().slideUp(200, function () {
menue.animate({
"width": '2em',
"left": '5.5em'
}, 200);
});
});
$('#item_element_new').hover(function () {
item.after('<div id="item_new"></div>');
}, function () {
$('#item_new').remove();
});
});
This is happening because every time you trigger mouseenter on .item you attach a new event to button.
Quick Solution: You have to remove previous events before attaching a new one, you can do this with .unbind(), here is a working example
$('#item_element_new').unbind();
$('#item_element_new').hover(function () {
$(document).on('mouseenter', '.item', function (event) {
var item = $(this);
$('#item_add').css({
"left": '5.5em',
"top": item.offset().top - 15
}).show();
$('#item_add').hover(function () {
var menue = $(this);
menue.animate({
"width": '7em',
"left": '0.5em'
}, 200, function () {
$(this).find(".body").stop().slideDown(200);
});
}, function () {
var menue = $(this);
menue.find(".body").stop().slideUp(200, function () {
menue.animate({
"width": '2em',
"left": '5.5em'
}, 200);
});
});
$('#item_element_new').unbind();
$('#item_element_new').hover(function () {
item.after('<div id="item_new"></div>');
}, function () {
$('#item_new').remove();
});
});
.item {
border: 1px solid #e2e2e2;
margin: 6px;
padding: 0px 10px 0px 10px;
position: relative;
height: 40px;
}
.wrap {
margin-left: 8em;
}
#item_new {
border: 1px dashed #C0C0C0 !important;
background: none repeat scroll 0% 0% #F7F7F7;
display: block;
height: 2.2em;
margin: 6px;
padding: 0px 10px;
position: relative;
}
#item_add {
display: none;
position: absolute;
width: 2em;
border: 1px solid #ddd;
background-color: #f7f7f7;
color: #aaa;
padding: 0px 6px;
}
#item_add .body {
display: none;
}
#item_add .arrow {
width: 0px;
height: 0px;
-webkit-transform:rotate(360deg);
border-style: solid;
border-width: 5px 0 5px 7px;
border-color: transparent transparent transparent #f7f7f7;
top: 5px;
right: -7px;
position: absolute;
}
#item_add button {
background: none repeat scroll 0px center #fff;
padding: 0.2em 2em;
margin: 3px .2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wrap">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div id="item_add">
<header>X</header>
<div class="body">
<button id="item_element_new">Example</button>
</div>
<div class="arrow"></div>
</div>
Soulution 2: As #Regent pointed out your code have some problems, you can solve a part of them:
Moving event binding outside mouseenter event handler
Caching jQuery objects
Not using .unbind() anymore
var $itemAdd = $('#item_add');
var $menuBody = $itemAdd.find(".body")
var $item = $('.item');
$itemAdd.hover(function () {
$itemAdd.animate({
"width": '7em',
"left": '0.5em'
}, 200, function () {
$menuBody.stop().slideDown(200);
});
}, function () {
$menuBody.stop().slideUp(200, function () {
$itemAdd.animate({
"width": '2em',
"left": '5.5em'
}, 200);
});
});
$('#item_element_new').hover(function () {
$('.item-hovered').after('<div id="item_new"></div>');
}, function () {
$('#item_new').remove();
});
$item.mouseenter(function (event) {
var $currentItem = $(this);
$currentItem.addClass('item-hovered');
$currentItem.siblings().removeClass('item-hovered');
$itemAdd.css({
"left": '5.5em',
"top": $currentItem.offset().top - 15
}).show();
});
.item {
border: 1px solid #e2e2e2;
margin: 6px;
padding: 0px 10px 0px 10px;
position: relative;
height: 40px;
}
.wrap {
margin-left: 8em;
}
#item_new {
border: 1px dashed #C0C0C0 !important;
background: none repeat scroll 0% 0% #F7F7F7;
display: block;
height: 2.2em;
margin: 6px;
padding: 0px 10px;
position: relative;
}
#item_add {
display: none;
position: absolute;
width: 2em;
border: 1px solid #ddd;
background-color: #f7f7f7;
color: #aaa;
padding: 0px 6px;
}
#item_add .body {
display: none;
}
#item_add .arrow {
width: 0px;
height: 0px;
-webkit-transform:rotate(360deg);
border-style: solid;
border-width: 5px 0 5px 7px;
border-color: transparent transparent transparent #f7f7f7;
top: 5px;
right: -7px;
position: absolute;
}
#item_add button {
background: none repeat scroll 0px center #fff;
padding: 0.2em 2em;
margin: 3px .2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wrap">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div id="item_add">
<header>X</header>
<div class="body">
<button id="item_element_new">Example</button>
</div>
<div class="arrow"></div>
</div>
The easiest fix, reason is what #erik-philips said:
$(document).on('mouseenter', '.item', function (event) {
var item = $(this);
$('#item_add').css({
"left": '5.5em',
"top": item.offset().top - 15
}).show();
$('#item_element_new').data('hovering_item', item);
});
$('#item_add').hover(function () {
var menue = $(this);
menue.animate({
"width": '7em',
"left": '0.5em'
}, 200, function () {
menue.find(".body").stop().slideDown(200);
});
}, function () {
var menue = $(this);
menue.find(".body").stop().slideUp(200, function () {
menue.animate({
"width": '2em',
"left": '5.5em'
}, 200);
});
});
$('#item_element_new').hover(function () {
var item = $('#item_element_new').data('hovering_item');
item.after('<div id="item_new"></div>');
}, function () {
var item = $('#item_element_new').data('hovering_item');
$('#item_new').remove();
});
.item {
border: 1px solid #e2e2e2;
margin: 6px;
padding: 0px 10px 0px 10px;
position: relative;
height: 40px;
}
.wrap {
margin-left: 8em;
}
#item_new {
border: 1px dashed #C0C0C0 !important;
background: none repeat scroll 0% 0% #F7F7F7;
display: block;
height: 2.2em;
margin: 6px;
padding: 0px 10px;
position: relative;
}
#item_add {
display: none;
position: absolute;
width: 2em;
border: 1px solid #ddd;
background-color: #f7f7f7;
color: #aaa;
padding: 0px 6px;
}
#item_add .body {
display: none;
}
#item_add .arrow {
width: 0px;
height: 0px;
-webkit-transform:rotate(360deg);
border-style: solid;
border-width: 5px 0 5px 7px;
border-color: transparent transparent transparent #f7f7f7;
top: 5px;
right: -7px;
position: absolute;
}
#item_add button {
background: none repeat scroll 0px center #fff;
padding: 0.2em 2em;
margin: 3px .2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wrap">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div id="item_add">
<header>X</header>
<div class="body">
<button id="item_element_new">Example</button>
</div>
<div class="arrow"></div>
</div>