Appended new divs, but they're not draggable? - jquery-ui

I'm a newbie and have some problems with making new divs draggable.
The example is: http://jsbin.com/iyexi3/
The problem is when I show the dialog for the name, I create some divs, but they aren't draggable.

You've made some elements that are hardcoded in the HTML draggable by doing this:
$('.seleccionable').draggable({
drag: function(e, ui) {
$('#status_nombre').html($(this).attr('id'));
$('#status_top').attr('value',$(this).css('top'));
$('#status_left').attr('value',$(this).css('left'));
}
,containment: '#layout'
,refreshPositions: true
,snap: true
});
When you add a new element you need to call .draggable() for that one too.
One way to do it would be to put that selector/draggable code into a function and call it after you've added a new element.

The issue is that when you append a new element to the DOM, it doesn't inherit the event handlers of the existing draggable elements.
You may have some luck with liveQuery
This will allow you to create live events on all current and future elements matching a selector. It's similar to the built-in live() method. I haven't used it but it should work with draggable.

finally find the solution is afther append the new div...
$('#nv_objeto').click(function(){
var nbr =prompt("Por favor escriba el nombre del Objeto:","");
$("#layout").append("<div id='"+c_nbr(nbr)+"' class='seleccionable' style='top: 300px; left: 400px; width : 40px; height : 40px; background-color : black; position :absolute;'></div>");
$('#layout > div:last').blur().draggable({
drag: function(e, ui) {
$('#status_nombre').html($(this).attr('id'));
$('#status_top').attr('value',$(this).css('top'));
$('#status_left').attr('value',$(this).css('left'));
}
,containment: '#layout'
,refreshPositions: true
,snap: true
});
});
thanks for the help.

Related

Issue with JQuery UI 'Droppable'

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).

Reset positions from Jquery UI Sortable

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

jQuery UI droppable: resizing element on hover not working

I have a jQuery UI droppable element which I would like to get bigger when a draggable is hovered over it. I have tried both using the hoverClass option and also binding to the drophover event.
Visually, both these methods work fine. However, once the draggable exits the original (smaller) boundary of the droppable, jQuery UI interprets this as a 'dropout', despite still being within the current (larger) boundary.
For example, js:
$("#dropable").droppable({
hoverClass: 'hovering'
}.bind('dropout', function () {console.log('dropout')});
css:
#droppable { background: teal; height: 10px; }
#droppable.hovering { height: 200px; }
In this case, when a draggable hovers over the droppable, the droppable visually increases in size to 200px. If at this point, the draggable is moved down by 20px, I would expect it to still be hovering over the droppable. Instead, jQuery UI fires the dropout event and the droppable reverts to being 10px high.
Anyone know how to get it to behave in the way I'd expect it to?
jsFiddle example: http://jsfiddle.net/kWFb9/
Had the same problem, I was able to solve it by using the following options:
$("#droppable").droppable({
hoverClass: 'hovering',
tolerance: 'pointer'
});
$('#draggable').draggable({
refreshPositions: true
});
Here's the working fiddle: http://jsfiddle.net/kWFb9/51/
See http://bugs.jqueryui.com/ticket/2970
So I made a couple tweaks to your fiddle
First I set the droppable tolerance to "touch" which will activate whenever any part of the draggable is touching it. This causes the hovering class to be applied.
Next I added an animation to resize your draggable element slightly. I wasn't sure if this was functionality you wanted or not so I put it in there anyways.
Lastly, I permanently apply the hovering class to the droppable element when the draggable element is dropped into the droppable zone. This way the droppable doesn't revert to that narrow height when there is an element in it
http://jsfiddle.net/kWFb9/2/
EDIT:
Better fiddle: http://jsfiddle.net/kWFb9/6/
I hope this helps :)
you could create a bigger (i.e. the size of #droppable.hovering) div without background and apply your droppable to it. Note that you didn't provide HTML but the new #drop_container should contain both divs.
JS
var dropped;
$("#droppable").droppable({
drop: function(event, ui) {
dropped = true;
}
});
$('#draggable').draggable({
start: function(event, ui) {
$("#droppable").addClass("hovering");
dropped = false;
},
stop: function(event, ui) {
if (!dropped) {
$("#droppable").removeClass("hovering");
}
}
});
CSS
#droppable { background: teal; height: 10px; }
#droppable.hovering, #drop_container { height: 200px; }
Or you could try another solution with .live() or .livequery() from this article
[EDIT] I've edited my code and here is a jsfiddle: http://jsfiddle.net/94Qyc/1/
I had to use a global var, I didn't find a better way to check wether the box was dropped. If anybody has an idea, that would be great.
There is an other (hum hum) not bad solution :
TL;DR: Fiddle
The problem is that the plugin stores dom element's size values when the widget is created (something like) :
//jquery.ui.dropable.js
$.widget("ui.droppable", {
...
_create: function() {
var proportions,
this.proportions = function() { return proportions; }
And the offset for widgets are initialized in $.ui.ddmanager.prepareOffsets();
So we only need to overwrite the proportions object.
This way allow to access to real plugin properties so we can write something like :
$("#droppable").droppable({
hoverClass: 'hovering',
over: function(ev, ui) {
var $widget = $(this).data('droppable');
$widget.proportions = {
width: $(this).width(),
height: $(this).height()
};
},
out: function(ev, ui) {
var $widget = $(this).data('droppable'); //ui-droppable for latests versions
$widget.proportions = {
width: $(this).width(),
height: $(this).height()
};
}
})

jQuery UI draggable element always on top

I need to have elements that are dragged from left-hand side area to be always on top. And they are when I first drag them from left area, however if I drop them into Box 2 and then decide to drag to Box 1, the item I drag appears below Box 1.
Confused? Here's DEMO of what I'm talking about.
Yes, I have added zIndex -- did not help.
Looks like you are doing some editing. :)
The solution is set the two boxes to the same z-index, and then lower the z-index of the sibling (the box the card is NOT over) using the "start" event. The "stop" event should set them equal again. Of course the draggable itself needs a higher z-index.
You can also try the stack option.
EDIT: Working example. Note that its actually the draggable drop event that needs to set the z-indexs equal again.
You'll need to make these changes (omit asterisks in your code, of course):
In dragdrop-client.js
// make the new card draggable
newCard.draggable({
zIndex: 2500,
handle: ".card",
stack: ".card",
revert: "invalid",
start: function() {
$(this).effect("highlight", {}, 1000);
$(this).css( "cursor","move" );
**var $par = $(this).parents('.stack');
if ($par.length == 1) {
console.log('in stack');
$par.siblings().css('z-index', '400');
}**
},
stop: function() {
$(this).css("cursor","default");
$(".stack").css('z-index', '500');
}
});
// make the new stack droppable
newStack.droppable({
tolerance: "intersect",
accept: ".card",
greedy: true,
drop: function(event, ui) {
**$(".stack").css('z-index', '500');**
card = ui.draggable;
putCardIntoStack(card,stackId);
}
});
In dragdrop-client.css
.stack {
width: 300px;
border: 1px dashed #ccc;
background-color: #f5f5f5;
margin: 10px;
float:left;
**z-index:500;**
}
I do what two7s_clash recommends for my drag-drop when elements are inserted dynamically. We have some elements being inserted over a canvas and then we want to drag n drop over everything:
start: function(e) { $('element').css('z-index', -1)}
stop: function(e) { $('element').css('z-index', 0)}

How to remove rounded corners from one jQuery UI widget but not the others?

My particular problem is that I want the autocomplete function to not have round corners, but all the other widgets that have round corners should.
Is there a parameter I can pass to disable the corners just for the autocomplete?
Edit
Let's see if this can be answered.
On page Datepicker.
I'd like to remove all round-corner classes from appearing (the header and the next-previous buttons).
$( "#datepicker" ).datepicker('widget').removeClass('ui-corner-all'); would not work.
Very late but here it goes:
jQuery UI widgets have a method, which returns the HTML node for the widget itself.
So the answer would be:
$('#someinput').autocomplete(...).autocomplete('widget').removeClass('ui-corner-all');
Responding to the EDIT:
As far I can see, you need to chain widget() method with autocomplete() (or datepicker()) method for it to work. Seems like it doesn't work for regular HTML nodes returned by $().
assign this css class to the element with corners of your widget.
.ui-corner-flat {
border-top-left-radius: 0px !important;
border-top-right-radius: 0px !important;
border-bottom-left-radius: 0px !important;
border-bottom-right-radius: 0px !important;
}
$("#elementwithcorners").addClass("ui-corner-flat");
to remove the bottom left radius
in the constructor I did this
$( "#signup" ).dialog(
{
create: function (event, ui) {
$(".ui-dialog").css('border-bottom-left-radius','0px');
},
}
);
The _suggest() method of the Autocomplete widget calls menu.refresh(), and therefore resets the ui-corner-all class for menu items, etc., each time the input changes. However, the open() callback is called after every menu.refresh() call within _suggest(), and so is a sensible place to adjust classes as desired:
$("#autocomplete").autocomplete("option", {
open: function(event, ui) {
$(this).autocomplete("widget")
.menu("widget").removeClass("ui-corner-all")
.find(".ui-corner-all").removeClass("ui-corner-all");
}
});
The Datepicker widget is a little tougher, as it's built to be sort of a semi-singleton. Here we need a monkey patch to do it consistently, since none of the supplied callback options is suitable:
// store the built-in update method on the "global" instance...
$.datepicker.__updateDatepicker = $.datepicker._updateDatepicker;
// ...and then clobber with our fix
$.datepicker._updateDatepicker = function(inst) {
$.datepicker.__updateDatepicker(inst);
inst.dpDiv.removeClass("ui-corner-all")
.find(".ui-corner-all").removeClass("ui-corner-all");
};
Note that the default _updateDatepicker() implementation has no return value. Also, note that the _updateDatepicker() method is not an interface method, so should not be assumed to be available. As such, the most consistent way to accomplish the corner fix is with appropriate CSS, along the lines of:
.ui-autocomplete.ui-menu.ui-corner-all,
.ui-autocomplete.ui-menu .ui-menu-item > a.ui-corner-all,
.ui-datepicker.ui-corner-all,
.ui-datepicker-header.ui-corner-all,
.ui-datepicker-next.ui-corner-all,
.ui-datepicker-prev.ui-corner-all {
border-radius: 0;
}
More specificity (or the !important directive) may be used to ensure these selectors are respected. This is exactly why jQuery uses theme classes – fudging these things in is an interesting hack, but it's the less clean option unless style is unavailable…
Create a new CSS class for the element you don't want rounded corners.
p.rounded { border-radius: 10px; }
p.none-rounded { border-radius: 0; }

Resources