I'm asking as a last resort before I tear the last of my hair out. At the moment I am showing an initial 2 divs. The user can then add these two divs below the original as many times as they want. They can also remove the 2 divs if necessary. I am trying to allow reording of the divs using drage and drop. I've tried numerous methods but I just can't get it working. As an extra note, the divs need to reindex themselves once the user has dragged and dropped. Here is the code that I have. Please take into consideration that I have added and deleted lots of code attempts before settling on this basic implementation. Thanks in advance.
Load JQuery
Display first div to end user
<!--Div contains each answer step-->
<div id = "answer_step" class = "answer_step">
<!--This placeholder text is styled from CSS and will empty the div once the user starts typing-->
<div id="answer_step_equation0" class="answer_step_equation" contenteditable="true" placeholder="Enter The Next Solution Step This Question"></div>
<div id="answer_step_description0" class = "answer_step_description" contenteditable="true" placeholder="Enter A Description as to how this step was reached or how to solve the next step"></div>
</div>
</div>
<!-- Buttons to dynamically add and remove answer divs. The remove functionality is added in JQuery for the add button-->
<button id="add_answer_step_button" class="add_answer_step_button">+ Add next Step</button>
This code appends the new divs. I have to put the three divs within a div like above but I can't get it to work.
<!--Script to append/remove div when user clicks on add_answer_step_button-->
<script type = "text/javascript" language = "javascript">
$(document).ready(function() {
<!--This variable gives each new set of answer divs a unique id by appending a number to the end of th id-->
<!--The first set of answer divs will have an id of zero-->
var answer_identifier_number = 1;
$("button.add_answer_step_button").click(function () {
$("div.answer_steps").append('<div id="answer_step_equation' + answer_identifier_number + '" class="answer_step_equation" contenteditable="true" placeholder="Enter The Next Solution Step This Question"></div>');
$("div.answer_steps").append('<div id="answer_step_description' + answer_identifier_number + '" class = "answer_step_description" contenteditable="true" placeholder="Enter A Description as to how this step was reached or how to solve the next step"></div>');
$("div.answer_steps").append('<button id="remove_answer_step_button' + answer_identifier_number + '" class = "remove_answer_step_button">- Remove This Step</button>');
answer_identifier_number++;
});
});
</script>
Allow the divs to be draggable
<script type = "text/javascript" language = "javascript">
$(function() {
$( "#answer_steps" ).sortable();
$( "#answer_steps" ).disableSelection();
cursor: move;
});
</script>
I haven't figured out how to reindex the names yet but I have experience of that part so I should be fine. Thanks for your help.
ok, before you go tearing your hair out, have a look at this 'drag and drop' fiddle - its a heres-one-I made-earlier one jsfiddle.net/RachGal/ahnx7kwc It'll give you an idea about how the whole drag and drop thing works – Rachel Gallen 2 days ago
The HTML from this fiddle
<div class="common">
<div class="container-fluid">
<div class="row">
<ul class="col-sm-3 col-md-2 sidebar nav nav-sidebar" >
<li class="group" class="draggable" ><a href="#" class="list-group-item">
<h4>
dsad
<br /><small>dsadsa</small>
<br /><small>dsadsa</small>
</h4>
</a>
</li>
<li class="group" class="draggable"><h2>
BAH
</h2><br><small>hello</small>
</ul>
<div id="drophere" class="col-sm-9 col-md-9">MAIN PANEL</div>
</div>
</div>
The Javascript from this fiddle
$(".draggable").draggable();
var draggableArguments={
revert: 'invalid',
helper:'clone',
appendTo: '#drophere',
refreshPositions: true,
containment: 'DOM',
zIndex: 1500,
addClasses: false
};
$('.group').draggable(draggableArguments);
$('.group').droppable();
$(".nav-sidebar").droppable({
tolerance: "intersect",
accept: ".group",
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
drop: function(event, ui) {
$(".nav-sidebar").append($(ui.draggable));
}
});
$('#drophere').droppable({
tolerance: "intersect",
accept: ".group",
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
drop: function(event, ui) {
$('#drophere').append($(ui.draggable));
}
});
$('#drophere').sortable();
The CSS from this Fiddle
.draggable {
border: solid 2px gray;
}
.sidebar {
position:fixed;
width:200px;
top: 51px;
bottom: 0;
left: 0;
z-index: 1000;
display: block;
padding: 20px;
overflow-y: auto;
/* Scrollable contents if viewport is shorter than content. */
overflow-x: visible;
background-color: #f5f5f5;
white-space: nowrap;
border-right: 1px solid #eee;
padding-left: 30px;
padding-right: 30px;
}
/* Sidebar navigation */
.nav-sidebar {
width:200px;
height:100vh;
margin-right: -21px;
/* 20px padding + 1px border */
margin-bottom: 20px;
margin-left: -20px;
}
.group{width:150px;
height:auto;
}
#drophere{width:700px;left:200px; height:100vh;}
Related
Using jQuery UI, I've just set up a simple test with draggable and droppable
HTML:
<div>
<img src="img/2.jpg" alt="Donut" id="a" class="drag"><span id="4" class="drop" >Eclair</span>
</div>
<div>
<img src="img/3.jpg" alt="Eclair" id="b" class="drag"><span id="3" class="drop">Donut</span>
</div>
I am trying to drag the first image and drop into the related span.Along with this if i drag and drop first image at id="4" it should revert back to its original position.Similarly when i drag and drop second image at id="3" it should revert back to its original position.
script:
$(function () {
$("#a").draggable({
revert: "valid",
});
$("#b").draggable({
revert: "invalid",
});
$(".drop").droppable({
accept: '.drop',
});
});
I can drag the image but could not drop it in a correct position.What i am doing wrong?
css:
.drag,.drop{
width:130px !important;
height: 130px !important;
border:2px solid !important;
margin-top:10px !important;
margin-left: 15% !important;
}
.drop{
float: right !important;
margin-right: 30% !important;
}
https://jsfiddle.net/jjewhwLt/
You need to style the elements a bit different, add the draggable() to the .drag class and you can then append the droppable() to the .drag elements. I've also added data-id to both drag and drop elements to be able to match them. I hope this is what you're looking for:
Updated FIDDLE.
$(".drag").draggable({
revert: 'invalid'
});
$(".drop").droppable({
accept: function(drag) {
var drop_id = $(this).attr('data-id');
var drag_id = $(drag).attr('data-id');
return drop_id === drag_id;
}
});
I had a bit of trouble understanding the question here, but i'll give it my best shot at explaining what I think you're trying to achieve.
I'd recommend in the future to start naming out what you're trying to do clearly so that you yourself can understand it while you're working. Stuff like "A" and "B", "3" and "4" etc. will get confusing very very fast with what you're working on.
What I took from this was that you are trying to get each container to accept it's corresponding image. Here's a cleaned up version of your jsfiddle: https://jsfiddle.net/8hr3vf3L/
I've separated out the images + drop areas in the HTML first and replaced the images that were broken with placeholders:
<div class="images">
<img src="http://placehold.it/120?text=donut" alt="Donut" id="donut" class="drag">
<img src="http://placehold.it/120?text=eclair" alt="Eclair" id="eclair" class="drag">
</div>
<div class="drop-areas">
<div class="drop-area" id="eclairArea">Eclair</div>
<div class="drop-area" id="donutArea">Donut</div>
</div>
Then cleaned up the CSS a little to make it a bit more generic:
.drop-areas {
margin-top: 40px;
}
.drop-area,
.drag {
display: inline-block;
width: 120px;
height: 120px;
border: 2px solid black;
margin-right: 20px;
}
.drag { border: none; }
Then finally your JS, which I hope makes more sense for you now. revert within a draggable function when named invalid will send the square back to where it was if it isn't in an area where it's accepted, which is explained by the droppable functions, which in this case I've separated out to make a little more sense to you, but you could I assume, make this programmatically check which image is being dropped in. As you can see, #eclairArea is set up to only accept the #eclair and vice-versa.
$(function () {
$(".drag").draggable({
revert: "invalid",
});
$("#eclairArea").droppable({
accept: '#eclair'
});
$("#donutArea").droppable({
accept: '#donut'
});
});
I have a series of HTML spans, such as:
<span class="dragable" id="Apple">
<span class="dragable" id="Banana">
<span class="dragable" id="Carrot">
...etc. My goal is to make each span dragable onto any other span. Upon this occurring, a JavaScript function will be invoked, which will somehow determine the ID of both the dragged and dropped elements, and then log them to the console (for debugging purposes of course)
Making these spans dragable is simple, but I'm not sure how to go out about passing the IDs to JavaScript. I've seen some tutorials on passing the IDs through events, but not any clear ones.
Any advice would be greatly appreciated.
You can use jQuery UI. It provides drag and drop just like you need it:
$(document).ready(function() {
var $output = $('#output');
$(".draggable").draggable({revert: true}).droppable({
drop: function(event, ui) {
var $dragged = $(ui.draggable[0]);
$output.text($dragged.attr('id') + " was dropped on " + $(this).attr('id'));
}
});
});
.draggable {
width: 50px;
height: 50px;
display: inline-block;
border: 1px solid black;
background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<span class="draggable" id="Apple"></span>
<span class="draggable" id="Banana"></span>
<span class="draggable" id="Carrot"></span>
<div id="output"></div>
Have a closer look to the docs of draggable and droppable to see full functionality.
I have issue with jQuery sortable.
Here is live example: JSFiddle
HTML:
<div class="a">
<div class="b">
a<br>
b<br>
c<br>
d<br>
e<br>
f<br>
g<br>
h<br>
i<br>
j<br>
k<br>
l<br>
m<br>
n<br>
o<br>
</div>
</div>
JS:
$(function(){
$('.a').sortable();
});
CSS:
.b {
border: 1px solid;
width: 100px;
height: 100px;
overflow-y: scroll;
overflow-x: hidden;
text-align: center;
}
In this case I have div with scroll. I scroll to the end of the div and I try to sort element using drag&drop. After this action, scroll in div jumps to beginning of this div. How I can "remember" position of scroll and "revert" it after sortable?
You need to save the scroll position and then reapply it when you stop moving the object.
JSFIDDLE: JSFIDDLE
$(function(){
var scrollTop = 0;
$('.a').sortable({
start: function(event, ui){
scrollTop = ui.item.scrollTop();
},
stop: function(event, ui){
ui.item.scrollTop(scrollTop);
}
});
});
You should use the sortable() method on the inner <div id="b"> and put every element you want to sort inside a <div> tag so they can be treated as DOM elements.
Here's a working solution JSFiddle
You might want to check THIS topic.
I want to create a simple "let's build a look" tool which basically allows a user to drag a div (with an image inside) on to a target area, resize it, rotate it or delete it and do the same with several other elements.
I can create the drag part to all elements and also resize one element but can't do it do more than one.
Here's what I have (I have copied partially the code from an example found here in Stackoverflow):
$(document).ready(function() {
//Counter
counts = [0];
$(".closeMe").hide();
$(".dragImg").draggable({
revert: "invalid",
containment: "#droppable",
helper: "clone",
cursor: "move",
start: function(event, ui) {
counts[0]++;
isDraggingMedia = true;
},
stop: function(event, ui) {
isDraggingMedia = false;
}
});
$("#droppable").droppable({
accept: ".dragImg",
drop: function(e, ui){
if(ui.draggable.hasClass("dragImg"))
$(this).append($(ui.helper).clone());
//Pointing to the dragImg class in dropHere and add new class.
$("#droppable .dragImg").addClass("item-"+counts[0]);
//Remove the current class (ui-draggable and dragImg)
$("#droppable .item-"+counts[0]).removeClass("dragImg ui-draggable ui-draggable-dragging");
$("#droppable .item-"+counts[0]+" .closeMe").addClass("del-"+counts[0]);
$(".item-"+counts[0]).click(function(){
$(".item-"+counts[0]+" .closeMe").show();
//$(".item-"+counts[0]).attr('class', 'ui-draggable-helper');
$(".item-"+counts[0]+" img").resizable({
aspectRatio: true
});
});
make_draggable($(".item-"+counts[0]));
}
});
var zIndex = 0;
function make_draggable(elements){
elements.draggable({
containment:'#droppable',
start:function(e,ui){ ui.helper.css('z-index',++zIndex); },
stop:function(e,ui){}
});
}
});
What I can not do is to achieve resize to every element or even have found a decent way to rotate them or delete them.
I want to click to select and show handles that allow resize, rotate and select and also when clicking outside the element, the handles should disappear.
How can i do this ?
It's a bit hard to answer the question accurately since the HTML is not provided, but I created a tiny sample page implementing these functionalities (dragging, dropping, deleting and resizing). Deleting uses the droppable 'trash' div, you may want to implement the delete functionality within the element similar to drag and resize.
Since jQuery UI provides no rotating functionality in itself, I left that one out. There is several plugins offering this kind of functionality so you should decide which suits you best. Rotating is also offere in CSS3, but you should keep in mind that this approach is very likely to have some browser compatibility issues, for more information see http://caniuse.com/transforms2d.
EDIT: Added a link to a very minimalistic demo application with this functionality: https://github.com/relicode/dragdrop-minimalistic/
<!doctype html>
<head>
<meta charset='utf-8'>
<title>jQuery draggable / droppable test</title>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<style>
.drop-hover {
border: solid green 3px;
}
.handle {
display: none;
}
.move-handle {
cursor: move;
}
.rotate-handle {
cursor: pointer;
}
.resize-handle {
cursor: nwse-resize;
}
.trash {
background-color: silver;
display: table-cell;
height: 100px;
vertical-align: middle;
width: 100px;
}
div.area {
border: solid black 1px;
float: left;
height: 500px;
width: 300px;
}
div.interactable {
background-color: silver;
height: 100px;
position: relative;
width: 100px;
}
div.interactable-tools {
bottom: 0;
position: absolute;
width: 100%;
}
p {
text-align: center;
}
</style>
</head>
<body>
<div id='target-area' class='area'>
<p>target</p>
<div class='trash' id='trash'>Trash</div>
</div>
<div id='source-area' class='area'>
<p>source</p>
<div class='interactable'>
Draggable 1
<div class='interactable-tools'>
<span class='handle move-handle'>Mo</span>
<span class='handle rotate-handle'>Ro</span>
<!-- <span class='handle resize-handle'>Re</span> -->
</div>
</div>
<div class='interactable'>
Draggable 2
<div class='interactable-tools'>
<span class='handle move-handle'>Mo</span>
<span class='handle rotate-handle'>Ro</span>
<!-- <span class='handle resize-handle'>Re</span> -->
</div>
</div>
<div class='interactable'>
Draggable 3
<div class='interactable-tools'>
<span class='handle move-handle'>Mo</span>
<span class='handle rotate-handle'>Ro</span>
<!-- <span class='handle resize-handle'>Re</span> -->
</div>
</div>
</div>
<script src='http://code.jquery.com/jquery-1.11.0.min.js'></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script>
$(document).ready(function() {
var counts = 0; // make sure you use var before your variable name to prevent declaring it as a global variable
$('.interactable')
.resizable()
.draggable({
handle: '.move-handle'
})
.hover(function() {
$(this).find('.handle').toggle();
}, function() {
$(this).find('.handle').toggle();
});
;
$('#target-area').droppable({
drop: function(ev) {
counts += 1;
}
});
$('#trash').droppable({
accept: '.interactable',
drop: function(ev) {
$(ev.toElement).parent().parent().remove();
},
hoverClass: 'drop-hover'
});
});
</script>
</body>
Example:
<div>
<div class='drop'>
<div class='drag'></div>
</div>
<div class='drop'>
</div>
<div class='drop'>
</div>
<div class='drop'>
</div>
<div>
</div>
</div>
$('div.drag').draggable({ containment: 'div.drop' });
Normally, if there is only 1 "div.drop" element, it works as intended. If there are more than 1(like in the example above), I thought that it would be dragged/dropped in any of the "div.drop" divs. As it turns out, it is only draggable/droppable to the first element matched by the "div.drop" selector.
Is there a workaround for this(that is, make it contained/droppable/draggable only in the "div.drop" divs)?
EDIT: I guess you are right guys. After some introspection, I realized that I didn't go for your suggested solutions since there are padding between the divs and I don't want the the "div.drag" divs to be dropped on the padded area.
It don't works like that !!
The containment is to constraint bound of dragging.
You want drag and drop.
Then you have to configure drag for div.grag:
$('div.drag').draggable();
And configure drop for div.drop:
$('div.drop').droppable();
You can add containment for your drag element with your first div level:
<div id='dragZone'>
<div class='drop'>
<div class='drag'></div>
</div>
<div class='drop'>
</div>
</div>
$('div.drag').draggable({ containment: '#dragZone'});
containment restricts the movement of a draggable within the bounds of the given element(s). You could set containment to the parent of the div.drops.
You should make the div.drops droppable, append the draggable on drop, and use the revert: 'invalid' option so that the draggable reverts if it's not dropped on a droppable
$('div.drop').droppable({drop: function(e, ui) {
ui.draggable.appendTo(this);
}});
$('div.drag').draggable({
helper: 'clone',
revert: 'invalid'
});
As the guys have pointed out the containment selector does not work like that as it Constrains dragging to within the bounds of the specified element or region.
You could try something like below:
JQuery References:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
HTML:
<div id="dragContainer">
<div class='drop'>
<div class='drag'>drag</div>
</div>
<div class='drop'>drop
</div>
<div class='drop'>drop
</div>
<div class='drop'>drop
</div>
<div class='nodrop'>
</div>
</div>
JQuery:
<script type="text/javascript">
$('div.drag').draggable({ containment: '#dragContainer', revert: "invalid" });
$('div.drop').droppable( {
drop: handleDropEvent
} );
function handleDropEvent( event, ui ) {
var draggable = ui.draggable;
alert( 'Ok to drop here onto me!' );
}
</script>
Do try my code
<style>
.container {
border: 2px solid #000;
}
.container img {
width: 45px;
height: 45px;
}
.draggable {
width: 40px;
height: 40px;
background: #F90;
border-radius: 10px;
margin: 0 0 0 0;
float: top;
}
.draggable.is-pointer-down {
background: #09F;
z-index: 2; /* above other draggies */
}
.draggable.is-dragging { opacity: 0.7; }
</style>
<script>
$(document).ready( function() {
var $draggables = $('.draggable').draggabilly({
// contain to parent element
**containment: "#box"**
});
});
</script>
Hello. I think this might help you :)
<div class="container" id="box">
and my images are inside this div.