In one panel I have the called resource,like a yellow square
I want drag the element to the another panel,and copy one,but the original one still there,
the markup is simple:
<div id="panel">
<div id="square" class="square"></div> //the resource
</div>
<div id="canvas">
</div>
the drag js code:
$('#panel .square').draggable({
appendTo: "#canvas",
helper: "clone"
});
$('#canvas').droppable({
drop: function (e, ui) {
var $temp_id = $(ui.draggable).attr('id');
var $new_id = $temp_id + "_01";
$(ui.draggable).clone()
.css({ 'top': ui.offset.top, 'left': ui.offset.left })
.appendTo($(this))
.attr('id', $new_id);
$('#'+$new_id+'').draggable();
}
});
I want only the resource element could copy itself,but the copy one in the canvas could copy themself,too!Inherit the copy ablity!
Thank you
here is example
What I have done ?Why this could happened?How can I cancel this?
Just add this to your drop event.
ui.draggable.remove();
That would remove the original element.
also to prevent the duplication of your items, consider adding this to your draggable.
accept: function(d) {
return $(this).find(d).length == 0
}
What it does is; it checks your container for the prescence of object d, if that object is present, the code would return false therefore preventing the drop of the object which causes the duplication.
Hope this helps.
Related
I am currently trying to make an extended droppable area but I got some problem. Here is the code (explanation below) :
$('div#1').find('div[cid="draggable"]').each(function(i, e) {
$(e).after("<div id='drp' style='width:100%;'></div>");
$('div#drp').droppable({
drop:function(event, ui) {
ajaxCall = false;
ui.draggable.css("left", "0");
ui.draggable.css("top", "0");
$(event.target).after(ui.draggable);
$(this).css("height", "0px");
$(this).removeClass("isDroppable");
$(this).removeClass("mb-1");
var t = ui.draggable.attr("i");
// callPage(81758758, 'POST', {t:t,s:0}, '');
},
over:function(event, ui) {
$(this).css("height", (parseInt(ui.helper.css("height")) + 50)+"px");
$(this).addClass("isDroppable");
$(this).addClass("mb-1");
if($(this).prev().attr("o") < ui.helper.attr("o")) {
// Move to top : Un padding s'ajoute, étrangement.
}
},
out:function(event, ui) {
$(this).css("height", "0px");
$(this).removeClass("isDroppable");
$(this).removeClass("mb-1");
},
accept:function(d) {
if(d.attr("cid") == "draggable" && d.attr("i") != $(this).prev().attr("i")) {
return true;
}
},
tolerance:'touch'
});
});
So actually, I am creating, for each child of div#0, a div#drp. It means that if I have, in div#0, 5 div#card, I will have, for each div#card, a div#drp (width:100%, height:0), for a total amount of 5 div#drp. As you should have understand, each div#drp is a DROPPABLE AREA (and each div#card can be dropped on each div#drp).
But here is the problem : The only way to get this working is to set the tolerance, as it is on my code, to "touch", as long as "pointer", "intersect" & "fit" will never work because of div#drp is set to height=0px.
Now, imagine the following structure :
<div id="card" i="1" style="width:100%;height:300px;">CARDTEST</div>
<div id="grp" i="1" style="width:100%;height:0;"></div>
<div id="card" i="2" style="width:100%;height:100px;">CARDTEST</div>
<div id="grp" i="2" style="width:100%;height:0;"></div>
<div id="card" i="3" style="width:100%;height:100px;">CARDTEST</div>
<div id="grp" i="3" style="width:100%;height:0;"></div>
Here, if I move the 2nd or 3rd card, everything will be alright. But if I move the first card (with height:300px) :
First, the id#grp height will be set to "(parseInt(ui.helper.css("height")) + 50)+"px"", it means 350px.
Second, even with that, my first card will trigger the first div#drp and the second div#drp as long as it height is too big. It's like if changing the height of my div#drp doesn't extend my DROPPABLE AREA.
So, my question is : Is there a way to "actualise" the DROPPABLE AREA within the "over" event ? I tried to change the droppable event within the "over" event, I also tried to change the tolerance within the "over" event, but nothing seems to work.
Any idea ?
Solution :
There isn't anything in Droppable() making this possible. However, it is possible to update DROPPABLE AREA positions within Draggable options. See below :
$( ".selector" ).draggable({
refreshPositions: true
});
I didn't expect a DROPPABLE property to be editable through DRAGGABLE elements. Note that, according to the documentation :
"If set to true, all droppable positions are calculated on every mousemove. Caution: This solves issues on highly dynamic pages, but dramatically decreases performance."
Tested on multiples devices, it doesn't cause lags or freez, so it should be fine.
Note that this config value will also fix margins caused by any Element added on Droppable.over if the Draggable Element is under the Droppable element (In example, if you want to do the same as what Sortable() do, but with Draggable() & Droppable()).
Problem solved !
This is the problem I am having:
I have created several draggable elements but when I drop one on the droppable element, it does not stay there.
Below are more details.
My JavaScript function receives JSON array from PHP and then uses a loop to create the draggable elements:
<script type="text/javascript">
function init() {
var items = <?php echo $result_j;?>; //items is an one dimensional array
for ( var i=0; i<<?php echo $total_rows_j;?>; i++ ) {
$('<div>' + items[i] + '</div>').data( 'item_name', items[i] ).attr( 'class', 'snk_button' ).appendTo( '#drag' );
}
With the 'items' array I have created several div elements (above code) which I then turn into draggable elements (code below).
$(".snk_button").draggable( {
containment: '#drag_section',//Div #drag_section contains the Div #drag
stack: '#drag div',
cursor: 'move',
revert: true
} )
So, far everything seems to be as expected and I am able to drag my elements (created from 'items' array).
Next, I have created the droppable element as shown below:
$( "#dropp" ).droppable({
drop: function() {
alert('ok');
}
});
}// End function init()
</script>
But when I drag one of my draggable elements on this droppable element, I even get the alert, but the draggable element does not stay on the droppable element.
Can anyone please help me identify why my draggable element is not staying on the droppable element?
Thanks in advance for any help!
You have used revert :true.. It means
Revert means If set to true, the element will return to its start position when dragging stops. Possible string values: 'valid', 'invalid'. If set to invalid, revert will only occur if the draggable has not been dropped on a droppable. For valid, it's the other way around.
Probably you need invalid in case your draggable element is not dropped on proper element
Thanks very much for pointing me in the right direction.
I have solved this particular problem in the following way:
I have edited my droppable code as below:
$( "#filtered" ).droppable(
drop: handleDrop
});
function handleDrop( event, ui ) {
ui.draggable.draggable( 'option', 'revert', false );
} // End function handleDrop
This has solved the problem of the draggable not staying on the droppable (that was previously described).
I have a jquery UI drag and drop for an inventory. It works but i want it to not happen if my inventory already has 20 items in (if it's full).
I'm not that great at javascript/jquery, I can't figure out how to fix my code to do this. I want it to revert back to it's original position if the inventory is full.
Here's the function I'm using to drag/drop
function itemInSpot(drag_item,spot) {
// this is my count. i don't want it to drop an item if it's 20 or more.
var inv_count = parseInt(<? echo count($inv_item) ?>, 10);
var oldSpotItem = $(spot).find('img');
oldSpotItem.appendTo('#inventory').draggable({ revert: 'invalid' });
var item = $('<img />');
drag_item.empty().remove();
item.attr('src',drag_item.attr('src')).attr('title',drag_item.attr('title')).attr('id',drag_item.attr('id')).attr('class',drag_item.attr('class')).appendTo(spot).draggable({ revert: 'invalid' });
}
This is the code that runs the function, set on pageload:
$(document).ready(function() {
$(".weapons,.shield").draggable({ stack: "div", revert: 'invalid'});
$('#inventory').droppable();
$("#weapon_spot").droppable({ accept: '.weapons'})
$('#shield_spot').droppable({ accept: '.shield'});
$('#weapon_spot,#shield_spot,#inventory').bind('drop', function(ev,ui) { itemInSpot(ui.draggable,this); });
});
So how can I add a if inv_count > 19 then revert item back to it's original position in?
Here's a basic jsFiddle example that has six draggable/droppable items, and after the third item is dropped on the target, an alert is triggered and no other draggables are allowed in the droppable area. The elements retain thair draggable property and revert to their original position if a drop is attempted.
jQuery:
$(".ui-widget-content").draggable({
revert: "invalid"
});
$("#droppable").droppable({
drop: function(event, ui) {
$(this).addClass("ui-state-highlight").find("p").html("Dropped!");
$(ui.draggable).addClass('in');
if ($('.in').length == 3) {
$("#droppable").droppable("option", "accept", ".in");
alert('Full!');
}
}
});
I am using sortable from Jquery UI. Each time I get the value from resultPos, it gives me the last move, but rememebr the last order. I need to reset it.
For example, I have 3 elements:
Move 3rd element to 2nd position: end=1&end=3&end=2
Again ...
Move 3rd element to 2nd position: end=1&end=2&end=3
Again ...
Move 3rd element to 2nd position: end=1&end=3&end=2
I need to have something that return to me the following:
Move 3rd element to 2nd position: end=1&end=3&end=2
Again ...
Move 3rd element to 2nd position: end=1&end=3&end=2
Again ...
Move 3rd element to 2nd position: end=1&end=3&end=2
This is my code:
$( ".sortableChip" ).sortable({
revert: true,
containment: "#carousel",
axis: "x",
items: 'li.edited',
tolerance: 'pointer',
placeholder: 'draggin-space',
start: function(event, ui) {
var startPos = $('.sortableChip').sortable('serialize',{ key: 'start'});
},
sort: function(event, ui) {
ui.item.addClass('draggin');
$('.remove-chart').hide();
},
update: function(event, ui) {
var resultPos = $('.sortableChip').sortable('serialize',{ key: 'end'});
ui.item.removeClass('draggin');
}
});
every item in the jquery UI sortable is an LI, there are a few ways you can do it, one way is to to save a variable that has the sortable list contents when the page initially loads like in the document ready part. all its doing is rearranging the order of li tags that are inside of the ul tag.
<script type="text/javascript">
$(document).ready(function(){
$('#link').click(function(){
//this will empty out the contents of the ul
$('.sortableChip').html('');
/*this will replace the contents of the ul with
contents that were caputred
*/
$('.sortableChip').html(reset);
});
});
var reset = $('.sortableChip').html();
/*this is here at the bottom because you want to everything that is created
dynamically with jquery or javascript to be captured also.
*/
</script>
all you are basically doing is returning the right settings once the link is clicked and thats it, you actually don't need this line `$('.sortableChip').html('');
but I put it here so you know that its being emptied out and replaced
if they need to be sorted based on what you click you would save the states you want tohave as variables like reset and simply clear the contents and load the variables based on what the user clicks
I've got a sortable panel (jQuery UI) on my website, but need to limit the amount of elements in each column to a maximum of 12.
I've tried a few things, but can't seem to get it to work. I need to see if 'i' is 12 or greater, and if so, don't update but I can't seem to do it!
Anyone got any advice or can push me the right way?
The jQuery is below!
function updateWidgetData(){
var items=[];
$('.column').each(function(){
var columnId=$(this).attr('id');
$('.dragbox', this).each(function(i){
var collapsed=0;
if($(this).find('.dragbox-content').css('display')=="none")
collapsed=1;
var item={
id: $(this).attr('ID'),
collapsed: collapsed,
order : i,
column: columnId
};
items.push(item);
});
});
var sortorder={ items: items };
//Pass sortorder variable to server using ajax to save state
$.post('includes/updatePanels.php', 'data='+$.toJSON(sortorder), function(response){
if(response=="success")
$("#console").html('<div class="success">Your preferences have been saved</div>').hide().fadeIn(1000);
setTimeout(function(){
$('#console').fadeOut(1000);
}, 2000);
});
}
Sortables
For connected sortables, the solution is to count the elements in each sortable when dragging starts, and disable the ones which have the maximum number of allowed elements. We need to exclude the current sortable, so we can re-order the items within and allow the current element to be dragged.
The problem here is that if we do the above on any of the sortables' events, it's already too late and disabling them won't have any effect. The solution is to do the bind the check to the mousedown event of the items themselves, which will fire before the sortable would get any control. We also need to re-enable all sortables when dragging stops.
Have a look at this example, using <ul> sortables with <li> items, the maximum number of items in each sortable is 3: http://jsfiddle.net/qqqm6/10/
$('.sort').sortable({
revert: 'invalid',
connectWith: '.sort',
stop: function(){
// Enable all sortables
$('.sort').each(function(){
$(this).sortable('enable');
});
}
});
$('.sort li').mousedown(function(){
// Check number of elements already in each sortable
$('.sort').not($(this).parent()).each(function(){
var $this = $(this);
if($this.find('li').length >= 3){
$this.sortable('disable');
} else {
$this.sortable('enable');
}
});
})
Draggables and droppables
The theory is simple, the solution is a bit tricky, there should really be a proper option in jQuery UI to cancel the operation on drop. If there is, but I missed something, please let me know.
Anyways, here's how you check for maximum count in the drop event (maximum of 4 in this example):
$('.drag').draggable({
revert: 'invalid',
stop: function(){
// Make it properly draggable again in case it was cancelled
$(this).draggable('option','revert','invalid');
}
});
$('.drop').droppable({
drop: function(event,ui){
var $this = $(this);
// Check number of elements already in
if($this.find('.drag').length >= 4){
// Cancel drag operation (make it always revert)
ui.draggable.draggable('option','revert',true);
return;
}
// Put dragged item into container
ui.draggable.appendTo($this).css({
top: '0px',
left: '0px'
});
// Do whatever you want with ui.draggable, which is a valid dropped object
}
});
See this fiddle in action: http://jsfiddle.net/qqqm6/