jquery-ui drag and drop across multiple divs with sort - jquery-ui

I'm trying to create a jquery drag and drop solution and am a little lost with how I achieve the following.
Allow '.todo-task' to be dropped into any of the 4 'backlog, pending, inProgress, completed' div containers.
Use a highlight helper to show where the task will be placed in the container.
Be able to drag and drop with in a container to change to order.
my first issue is that I cannot seem to be able to activate the drag items correctly.
I have created a jsfiddle with the code I have so far. Appreciate any guidance / help
here is my jquery code
$(".task-container").contents().find(".todo-task").draggable({
connectToSortable: ".ui-droppable",
helper: function (event) {
},
iframeFix: true,
// stop: makeSortable()
stop: function (event, ui) {
// alert('stop');
}
});
$(".ui-droppable").sortable({
placeholder: "ui-state-highlight",
opacity: .5,
//dropOnEmpty: true,
helper: 'original',
beforeStop: function (event, ui) {
newItem = ui.item;
},
receive: function (event, ui) {
},
}).disableSelection().droppable({
over: ".ui-droppable",
activeClass: 'highlight',
drop: function (event, ui) {
$(this).addClass("ui-state-highlight");
}
})

I'm not sure exactly what else you're trying to achieve in terms of the "disabled" style CSS, but I just forked and monkeyed around with this for a minute:
jsfiddle
One thing is that I think your jQuery methods are redundant. Why say:
$(".task-container").contents().find(".todo-task").draggable( ...etc.
When you can just as easily do this:
$(".todo-task").draggable( ...etc.
So I cleaned a little bit of that up.
The other thing I did was to make the .task-container droppable.
See the jQuery API: droppable methods
This allows you to sort and move between columns, but like I mentioned this fix seems to behave strangely with your CSS class methods.

Related

Get draggable parent container

I have 2 containers.
Both of them is a draggable and dropable, to be sure I can move tags from one to another.
In the drop function I check the id of containers. Based on the name of the id, I decide, should I add a tag to a user or should I remove it from the user.
Let's says, there is a container div for existsTagsContiner. This contains the tags of the user.
The other container is userTagsContainer what contains all of the tags what are not belongs to user.
Both of these container has a class: .draggableTagContainer
Everything is works fine, when I move the tag from one to other, ajax made the operations, and a message appears for user.
For example, if user moves a tag from existsTagsContiner to userTagsContainer then I should add the tag to user.
But, and here comes my problem: if I am moving a tag from existsTagsContiner to existsTagsContiner (so no movement happened, just a drag and drop in the same container), the message appears too!
Definitely it should not happen. So, what I want to achive is to get the "source" id of the container. If the "source" is the same as $(this).attr('id') in the drop function, I just do nothing.
I've added a comment, where I need to get the original container name.
Here is my code.
$('#existsTagsContiner, #userTagsContainer').droppable({
tolerance: "intersect",
accept: ".draggableTagContainer",
drop: function (event, ui) {
var tagId = $(ui.helper.context).data('id');
$('#tagId').val(tagId);
//At here I need something like $(ui.helper.___SOURCE___)
if ($(this).attr('id') === 'existsTagsContiner') {
$.removeTagFromUser();
} else {
$.saveTagToUser();
}
$('#tagId').val('0');
if (!$(this).find('ul').length) {
$(this).html('<ul>');
}
$(this).find('ul').append($(ui.draggable));
}
});
$('.draggableTagContainer').draggable({
start: function (event, ui) {
$(ui.helper).addClass("draggableTagContainer");
},
appendTo: 'parent',
cursor: "move",
helper: 'clone',
revert: 'invalid',
cancel: ".draggableTagDelete",
});
UPDATE
That could be a workaround, if I add a data-from to the li when start to drag. But maybe there is a built in function for this, this is what I want to know.
This is the workaround. In the start function of draggable add:
$(ui.helper).data('from', $(this).closest('.tagContainer').attr('id'));
in the droppable drop function add:
if ($(this).attr('id') === ui.helper.data('from')) {
return false;
}

Why can my <tr>s only be dragged (connectToSortable) to other tables only once?

I'm using draggable with connectToSortable to allow <tr>s from my tables to be dragged and added to other tables.
It works great, but once I drag a <tr> to another table, it cannot be moved again, except for within its own (new) table. Is this an inherent limitation of jQuery UI or did I do something wrong?
Sortable:
$("#sem1").sortable({
receive: function (event, ui) {
ui.item.remove();}
});
$("#sem2").sortable({
receive: function (event, ui) {
ui.item.remove();}
});
Draggable:
$("#sem1 tr").draggable({ connectToSortable: "#sem1, #sem2",helper:"clone"});
$("#sem2 tr").draggable({ connectToSortable: "#sem1, #sem2",helper:"clone"});
I had to use the clone helper and then remove because otherwise the drag would do funky things like overlap rows... open to any suggestions!
Thanks in advance for any help!
P.s, this is a follow-up to a question I had previously gotten answered:
Are dynamically created table rows not targetable by jQuery?
Got it - I just added the exact same code above to be executed on a onmouseup handler attached to my <tr>s

jquery ui dialog how to detect loss of focus

I have been searching for quite some time without success. I want to detect when a particular jquery ui dialog has lost focus.
I know I can detect when it gains focus like so:
focus: function(event, ui) { console.log('focus in: '+this.id); }
However the focusout event does not get triggered in any way I've tried:
focusout: function(event, ui) { console.log('focus out: '+this.id);}
This is my (PHP echo'ed) code:
<script type=\"text/javascript\">
$(\"".$element."\").click(function(e){
$(\"#".$divname."\").load('".$url."').dialog({
title: '".$title."',
modal:".$modal.",
resizable: true,
width:'".$width."',
height:'".$height."',
show: 'clip',
hide: 'clip',
open: function(event, ui) {\$(\".ui-widget-overlay\").css({'background-image': 'url(\"../css/stripe_small.png\")','background-repeat':'repeat', 'opacity':'0.8'})},
minimize: '#toolbar',
focus: function(event, ui) { console.log('focus in: '+this.id); },
focusout: function(event, ui) { console.log('focus out: '+this.id);}});
});
</script>
<div id=\"".$divname."\"></div>";
Everything works allright, apart from the focus out detection. Is there a way to do this, or do I have to iterate all window elements to find out which has the focus ?
EDIT: Alternatively, I would like to know if I can find which UI Dialog is the one at the front.
Since nobody has answered I will give a brief answer to what I have come up with.
jQuery's blur and focusout do not seem to trigger for my dialogs:
When trying to listen for events of a dialog widget:
$(".ui-dialog.ui-widget.ui-widget-content.ui-corner-all.ui-draggable.ui-resizable").blur(function({ //NOP });
When trying to listen for events of the divname used for a dialog:
$("#divname").blur( function({ //NOP });
Do not get triggered.
Weirdly enough, focusin does work:
$("#divname").focusin( function({ console.log('focused in'); });
A hackish solution (which may be a bit heavy if there are many ui-dialogs on the page as it so happens in my case, but which works nonetheless, is to listen for click events on ui-dialogs:
$(".ui-dialog.ui-widget.ui-widget-content.ui-corner-all.ui-draggable.ui-resizable").live('click',function(){
$(this).addClass('ui-active').removeClass('ui-inactive');
});
What this does it the exact opposite: instead of trying to detect a dialog losing focus, onclick I iterate all dialogs. The one with the highest ZIndex is at the top, the rest are not (and thus have lost focus):
var topZindex = 0;
$(".ui-dialog.ui-widget.ui-widget-content.ui-corner-all.ui-draggable.ui-resizable").each( function( ){
var thisZindex = parseInt($(this).css('zIndex'), 10);
if ( thisZindex > topZindex ) topZindex = thisZindex;
});
It would be really nice if somehow a callback would trigger when the entire ui-dialog lost focus, but I can't seem to find another solution on the web, and I cannot get blur or focusout to trigger.

jQuery Drag and Drop Breaks When Loading Divs by AJAX

I have a list of draggables that need to be dropped onto divs loaded by AJAX. However, when the divs are loaded by AJAX it breaks the droppables functionality. I removed AJAX from the equation and it worked fine.
Here's working code. With this code I can drag items in my .contentList to #block1 div and everything works peachy.
<div id="block1"></div>
$(".contentList").draggable();
var dropOpts = {
hoverClass: "activated",
tolerance: "pointer",
drop: getURL
};
$("#block1").droppable(dropOpts);
I then have the following code load a new div via jQuery .load.
$(document).ready(function() {
$("#template1").click(function() {
$("#dynamic-ui").load("/templates/newtemplate.html");
});
The newtemplate.html contains a div with the same id; #block1. However, once it loads I can no longer drag onto it. Any help would be greatly appreciated!
Add the code to make #block1 droppable after the newtemplate.html is loaded into dom. e.g.
$(document).ready(function() {
$("#template1").click(function() {
$("#dynamic-ui").load("/templates/newtemplate.html");
var dropOpts = {
hoverClass: "activated",
tolerance: "pointer",
drop: getURL
};
$("#block1").droppable(dropOpts);
});
});
The binding of events happens when the browser loads the webpage.
So during the loading if the JavaScript didn't find the specified division/element they won't bind the event. So for dynamically created divisions you need use jQuery live to bind the events.
For your question i think this question will answer you.
Hope it will help you.
Good luck

Update div on event

I am using the jquery slider and using append() to update the value, but it will keep adding it unless I empty it on the start event. Is there a way where I can just updated the value instead of printing it out every time the action takes place. i tried replaceWith but no luck there.
start: function(event, ui){
$('#current_value').empty();
},
slide: function(event, ui){
$('#current_value').fadeIn().append('Value is '+ui.value);
},
You probably want something like
slide: function(event, ui){
$('#current_value').text('Value is '+ui.value);
$('#current_value').fadeIn();
}
text() documentation
you need to use html() not append(), append adds the value at end of the given element, html sets the innerHtml for the given element.
$('#current_value').html('Value is '+ui.value).fadeIn();
If i understand you right, you should:
var existing = $('#current_value').html();
$('#current_value').html(existing + ui.value).fadeIn();

Resources