The goal of the script is drag element but leave copy of the element.
function makeDraggable() {
$('.col-md-4').addClass('is-draggable');
$('.is-draggable').draggable({
start: function(event, ui){
if($(this).hasClass('not-draggable'))
return;
var cl = $(this).clone();
$(this).after(cl);
var of = cl.offset();
$(this).addClass('rect').offset({top:of.top,left:of.left}).css({width:cl.css('width'), height:cl.css('height')});
makeDraggable();
$(this).addClass('not-draggable');
}
});
}
makeDraggable();
When you mousedown on some boxes it clones box and then draggable placing this element to the left top corner and don't allow to set my own offset. I want the dragable element left on the same place and don't jump. Demo jsfidle
You can't use offset because it's already used by the drag event. You can use margins to offset your draggable.
Also, use ui.helper to get the offset
var of = $(ui.helper).offset();
$(this).addClass('rect').css({'margin-top':of.top,'margin-left':of.left}).css({width:cl.css('width'), height:cl.css('height')});
Demo
External JSFiddle: http://jsfiddle.net/9QmbG/22
function makeDraggable() {
$('.col-md-4').addClass('is-draggable');
$('.is-draggable').draggable({
start: function (event, ui) {
var $this = $(this);
if ($this.hasClass('not-draggable')) return;
var cl = $this.clone();
$this.after(cl);
var of = $(ui.helper).offset();
$this.addClass('rect').css({
'margin-top': of.top,
'margin-left': of.left
}).css({
width: cl.css('width'),
height: cl.css('height')
});
makeDraggable();
$this.addClass('not-draggable');
}
});
}
makeDraggable();
#score {
height:50px;
}
.col-md-4 {
width:40px;
height:40px;
margin:10px 20px;
border:1px solid #000000;
float:left;
cursor:pointer;
text-align:center;
line-height:40px;
position:relative;
top:0;
left:0;
}
.rect {
position: absolute;
z-index:100000;
border-style: dashed;
border-width: 2px;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.js"></script>
<div id="score"> </div>
<div class="col-md-4">1</div>
<div class="col-md-4">2</div>
<div class="col-md-4">3</div>
Related
I want to add two arrows to the sides of the "boxes" divs (below) to cycle through the 3 divs.
Working JSFiddle: https://jsfiddle.net/HBHcC/11/
Can someone help me with this?
HTML:
<div class="container">
<div class="boxes">
<div class="one box">
</div>
<div class="two box">
</div>
<div class="three box">
</div>
</div>
</div>
CSS:
.container{
width:100px;
height:100px;
overflow:hidden;
position:relative;
}
.box {
display:inline-block;
float: left;
width: 100px;
height: 100px;
}
.one{
background-color:green;
}
.two{
background-color:red;
}
.three{
background-color:blue;
}
.boxes{
width:400px;
}
JS:
$(document).ready(function(){
$('.box').on("click", function() {
// Is this the last div, or is there a next one?
if ($(this).next().length) {
var animSpeed = 200; // Make this 0 for an instant change
$('.boxes').animate({marginLeft : "-=100"}, animSpeed);
}
});
});
After adding arrows to the div, here is a new fiddle that should get you started:
$('.rightarrow').on("click", function() {
// Is this the last div, or is there a next one?
var animSpeed = 200; // Make this 0 for an instant change
$('.boxes').animate({marginLeft : "-=100"}, animSpeed);
});
$('.leftarrow').on("click", function() {
// Is this the last div, or is there a next one?
var animSpeed = 200; // Make this 0 for an instant change
$('.boxes').animate({marginLeft : "+=100"}, animSpeed);
});
https://jsfiddle.net/tx2yg06w/1/
Updated w/arrows moved out of divs:
$(document).ready(function(){
var animSpeed = 200;
$('.rightarrow').on("click", function() {
if(parseInt($("#boxes").css("marginLeft")) == -200){ return;}
$('.boxes').animate({marginLeft : "-=100"}, animSpeed);
});
$('.leftarrow').on("click", function() {
if(parseInt($("#boxes").css("marginLeft")) == 0){ return;}
$('.boxes').animate({marginLeft : "+=100"}, animSpeed);
});
});
https://jsfiddle.net/b56r0d72/
Errata has given you a good solution. Just wire up his code to the arrows in the snippet below.
Run snippet to view:
<html>
<body>
<style type="text/css">
.leftarrow, .rightarrow {
font-size: 48px;
color: blue;
text-decoration: none;
}
.rightarrow {
color: red;
float: right;
}
.content {
width: 200px;
padding: 4px;
border: 1px gray solid;
}
.box {
height: 200px;
border: 1px green solid;
}
</style>
<div class="content">
<div>
◀
▶
</div>
<div class="box">slide</div>
</div>
</body>
</html>
I have looked through same questions on this topic but somehow suggested solutions do not work for me :/
Problem is that divs get moved from #box1 to #box2 only once. If detach() used then divs are clickable in #box2 but get rearranged when clicked. If remove()used divs are not clickable in #box2 at all (event listener gone?). I have a feeling that the process of moving the divs is somehow not really complete and I ether have duplicates around in DOM or moved divs disappear entirely and do not react to clicks.
I tried detach(), remove() and appendTo() in various combinations and the best I can get is in the fiddle below
http://jsfiddle.net/uoz3t914/13/
$('#box1 .item' ).on('click', function() {
// $( this ).detach().appendTo('#box2'); moves divs around in #box2
$( this ).remove().appendTo('#box2');
});
$('#box2 .item' ).on('click', function() {
// $( this ).detach().appendTo('#box2'); moves divs around in #box2
$( this ).appendTo('#box1');
});
In your case you have to use the Event Delegation
$('#box1' ).off().on('click','.item', function() {
// $( this ).detach().appendTo('#box2'); moves divs around in #box2
$( this ).appendTo('#box2');
});
$('#box2' ).off().on('click', '.item', function() {
// $( this ).detach().appendTo('#box2'); moves divs around in #box2
$( this ).appendTo('#box1');
});
You attach the event to the parent, that propagate it to the children, and then any time that you attach the event, put an off() to detach it.
$('#box1' ).off().on('click','.item', function() {
// $( this ).detach().appendTo('#box2'); moves divs around in #box2
$( this ).appendTo('#box2');
});
$('#box2' ).off().on('click', '.item', function() {
// $( this ).detach().appendTo('#box2'); moves divs around in #box2
$( this ).appendTo('#box1');
});
.item {
width: 50px;
height: 50px;
float: left;
}
#box1 {
border: 1px dotted blue;
position: relative;
width: 200px;
height: 100px;
}
#i1 {
background-color: yellow;
}
#i2 {
background-color: green;
}
#i3 {
background-color: red;
}
#box2{
border: 1px solid black;
width: 250px;
height: 100px;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id ="box1">
<div class ="item" id ="i1"></div>
<div class ="item" id ="i2"></div>
<div class ="item" id ="i3"></div>
</div>
<div id = "box2">
</div>
You can move them between the boxes with:
$('#box1, #box2').on('click', '.item', function () {
$(this).appendTo($(this).parent().prop('id') == 'box1' ? '#box2' : '#box1');
});
$('#box1, #box2').on('click', '.item', function () {
$(this).appendTo($(this).parent().prop('id') == 'box1' ? '#box2' : '#box1');
});
.item {
width: 50px;
height: 50px;
float: left;
}
#box1 {
border: 1px dotted blue;
position: relative;
width: 200px;
height: 100px;
}
#i1 {
background-color: yellow;
}
#i2 {
background-color: green;
}
#i3 {
background-color: red;
}
#box2 {
border: 1px solid black;
width: 250px;
height: 100px;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="box1">
<div class="item" id="i1"></div>
<div class="item" id="i2"></div>
<div class="item" id="i3"></div>
</div>
<div id="box2"></div>
This uses .on()'s event delegation syntax to handle the elements, and a ternary operator to determine which box the element exists in.
Use this html:
<div id="wrapper">
<div id ="box1" class="container">
<div class ="item" id ="i1"></div>
<div class ="item" id ="i2"></div>
<div class ="item" id ="i3"></div>
</div>
<div id = "box2" class="container">
</div>
</div>
and this javascript
$('.item').on('click', function(){
var index = $("#wrapper > .container").index($(this).parent()),
maxIndex = $('#wrapper > .container').length,
nextIndex = (index + 1) < maxIndex ? (index + 1) : 0;
$(this).appendTo($('#wrapper > .container').eq(nextIndex));
});
in your fiddle to move boxes between any number of containers
You may also add Box3, Box4 (with class .container) etc. into the "#wrapper div", you may do it dynamycally
I'm trying to simulate an animate effect via jQuery that consists drag and drop as events to be fired. The code I use seems to be fine until the point when I have to swap divs by setting their display to none/block. Whenever I swap to the first div it perfectly executes the animation but when it gets on the 2nd div (after swapped) it doesn't fire the droppable event. I chose to have id selectors for the respective divs to instance the container of the droppable event hence to animate. I'm stuck and are out of any solution after searching numerous results so far. Thank you in advance. Here is my JS fiddle I prepared to easily understand my problem.
<html>
<head>
<style>
#wrapper {
border: 1px solid gray;
height:300px;
margin: 0 auto;
padding: 20px 20px 20px 20px;
position:relative;
text-align:center;
width:600px;
}
p {
display:inline;
font-family:Calibri;
font-size:20px;
color: #0b1207;
text-shadow: #63c9b8 0px 10px 10px;
}
#div1, #div2 {
border: 1px dotted green;
bottom:0;
margin-left:100px;
position: absolute;
}
#div1 {
background-color: orange;
height:200px;
width:300px;
}
#div2 {
background-color: green;
display:none;
height:100px;
width:300px;
}
#btnchange {
background-color:black;
border-radius:10px;
color: #fff;
height:35px;
margin-top:10px;
margin-left:100px;
position:absolute;
width:80px;
}
.example {
border: 1px solid red;
background-color: blue;
height:75px;
margin: 5px auto 0 ;
width:75px;
}
</style>
</head>
<body>
<div id='wrapper'>
<p></p>
<div id='div1'></div>
<div id='div2'></div>
</div>
<button id ='btnchange' type='button'>Change</button>
<div class='example'></div>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="http://biostall.com/wp-content/uploads/2010/07/jquery-swapsies.js"></script>
<script type="text/javascript">
var id = 1;
var parent = document.getElementById('wrapper');
var makina = parent.children[id].id;
$(function(){
$( "#draggable" ).draggable({
connectToSortable: "#sortable",
helper: "clone",
revert: "invalid"
});
$('.example').draggable({
containtment: "#" + makina,
cursor: "pointer",
revert: true
});
$('#btnchange').click(function(){
if (id == 1)
{
document.getElementById(makina).style.display = 'none';
id = 2;
makina = parent.children[id].id;
document.getElementById(makina).style.display = 'block';
document.getElementById('wrapper').children[0].innerText = makina;
}
else
{
document.getElementById(makina).style.display = 'none';
id = 1;
makina = parent.children[id].id;
document.getElementById(makina).style.display = 'block';
document.getElementById('wrapper').children[0].innerText = makina;
}
console.log(makina);
});
$("#" + makina).droppable({
drop: function(){
doAnimate(makina);}
});
});
function doAnimate(container)
{
$('#'+ container).animate({height: '+=10px'}, 500, function(){
var message = container.clientHeight;
$(this).html(message);
});
}
</script>
</body>
</html>
http://jsfiddle.net/xoxxbr4t/6/
Your problem is you were only calling droppable once, on only one of the items. Once the .droppable() function is also put inside the change button click, it should work.
put this inside change function:
$("#" + makina).droppable({
drop: function () {
doAnimate(makina);
}
});
example:
http://jsfiddle.net/xoxxbr4t/7/
You aren't binding droppable to your second element. You call this function once:
$("#" + makina).droppable({
drop: function () {
doAnimate(makina);
}
});
Since your "makina" at this point is div1, that's the only thing that gets bound. I made that it's own function:
function setDroppable(makina) {
$("#" + makina).droppable({
drop: function () {
doAnimate(makina);
}
});
}
And then called it for both divs in your setup:
setDroppable('div1');
setDroppable('div2');
And now it works fine. Here's the updated fiddle
Thanks Michal indeed that was the answer but I think a good programmer would reduce the redundant snippet of code as far as I can tell those are duplicate lines from the $(document).ready() function. However it's a solution. And right after I read your post I decided to post the answer myself as it follows:
//Previous
$("#" + makina).droppable({
drop: function () {
doAnimate(makina);
}
});
//Current
$("#wrapper").droppable({
drop: function () {
doAnimate(makina);
}
});
Since I'm using nested divs I then realised that I could make the parent div droppable and just animate the child which is active(shown).
I'm trying to make a range slider but it's working in single direction(to right) only and dragging out of parent container(#volume). How can I fix this?
I've attached a demo fiddle link.
Markup
<div id="volume">
<div class="progress">
<div class="volumeslider"></div>
</div>
</div>
CSS
#volume{
width:300px;
background: #ddd;
cursor:pointer;
}
.progress{
height:10px;
background:#999;
position:relative;
width:0;
}
.volumeslider {
background: #808080;
position: absolute;
width: 20px;
height: 20px;
border-radius: 15px;
right: -10px;
top: -5px;
}
JS
$('.volumeslider').bind('mousedown', function(e){
$('.volumeslider').bind('mousemove', function(e){
$('.progress').width(e.pageX - $('.progress').offset().left + 'px');
$(this).css('left', e.pageX - ($(this).width()/2) );
});
$('.volumeslider').bind('mouseup',function(){
$('.volumeslider').unbind('mousemove');
});
});
JS Fiddle:
http://jsfiddle.net/2mYm7/
You have not taken into consideration the padding you have given to the body element.
I have made some changes to the code.
$('.volumeslider').bind('mousedown', function (e) {
console.log('binded');
$('.volumeslider').bind('mouseup', function (e) {
console.log('unbinded');
$('.volumeslider').unbind('mousemove');
});
$('.volumeslider').bind('mousemove', function (e) {
console.log('mousemove');
$('.progress').width(e.pageX - $('.progress').offset().left + 'px');
$(this).css('left', e.pageX - 25- $(this).width());
});
});
Check this jsFiddle http://jsfiddle.net/2mYm7/1/
Here's an example of how to make it work always and everywhere. Right now it will stay dragging forever if you leave the element.
It includes border checks and makes sure the body is large enough so it stops dragging wherever on the page.
http://jsfiddle.net/2mYm7/5/
var dragging = null;
function startDrag(){
console.log('started dragging', this);
var $this = $(this);
dragging = $this;
$(document.body).bind('mouseup', stopDrag);
$(document.body).bind('mousemove', drag);
}
function stopDrag(){
console.log('stopped dragging', dragging[0]);
$(document.body).unbind('mouseup', stopDrag);
$(document.body).unbind('mousemove', drag);
dragging = null;
}
function drag(e){
var slider = dragging;
var progress = slider.parent();
var container = progress.parent();
var maxOffset = container.width();
progress.width(Math.min(e.pageX - progress.offset().left, maxOffset) + 'px');
}
$('.volumeslider').bind('mousedown', startDrag);
I have a situation like this set up:
http://jsfiddle.net/gz4Z7/2/
The difference in my situation is that all of the elements are created in javascript with document.createElement, and they are appended to the DOM of various webpages on the internet.
Everything works great except one thing: The hover functionality doesn't work until I click on the container. This only happens on some webpages.
My question is: What would cause the need to click on the container element in order for the hover functionality of its children to work? I have tried doing a focus() on the container element but it doesn't seem to make a difference.
Here is the fiddle code:
<input id="myInput" type="text"/>
<myContainer id="myContainer">
<outerThing id="outerThing">
<myThing id="myThing"></myThing>
</outerThing>
</myContainer>
<button type="button" onclick="buttonClick()">show container</button>
#myContainer {
position: absolute;
top:100px;
bottom:auto;
right:auto;
left:100px;
width:200px;
height:200px;
display: none;
background-color: red;
}
#outerThing{
width:50px;
height:50px;
margin-top: 10px;
margin-left: 10px;
display: block;
background-color: white;
}
#myThing{
width:20px;
height:20px;
margin-top: 15px;
margin-left: 15px;
display: none;
background-color: blue;
}
function buttonClick() {
document.getElementById("myInput").focus();
var cont = document.getElementById("myContainer");
cont.style.display = "block";
var outerThing = document.getElementById("outerThing");
$( outerThing ).hover(
function()
{
$(this).children(":last").css( "display", "inline-block" );
},
function()
{
$(this).children(":last").css( "display", "none" );
});
}
$(document).ready(function({
function buttonClick() {
document.getElementById("myInput").focus();
var cont = document.getElementById("myContainer");
cont.style.display = "block";
var outerThing = document.getElementById("outerThing");
$( outerThing ).hover(
function()
{
$(this).children(":last").css( "display", "inline-block" );
},
function()
{
$(this).children(":last").css( "display", "none" );
});
}
});
Like this