jquery UI draggable: ui.children is not a function - javascript

i have a draggable list, a sortable-droppable list and a couple of li's inside the first.
now i want to pull them over, in the stop-funtion i have a function that adds a class to the first child (it's a span representing the clip-number like
<li>
<span>1.</span>
<span>Title</span>
<span>1min23sec</span>
</li>
). the reason for this is, i want to represent the original clip number in the playlist(sortable).
but i get a console error saying
TypeError: ui.children is not a function
ui.children("li")[0].addClass(".slot_clip_info");
i am not 100% sure, but i think this exact code HAS already worked in the past time, i might have changed somthing without knowing, but i am not aware of that.
draggable:
$(function() {
$(".pl_clipEntry").draggable({
appendTo: "body",
revert: "invalid",
connectToSortable: "#tracks",
distance: 20,
helper: function(){
return $(this).clone().width($(this).width()); // hack for the drag-clone to keep the correct width
},
stop: function(ui) {
ui.children("li")[0].addClass(".slot_clip_info");
},
zIndex: 100
});
});
sortable:
$(function() {
var removeItem;
$("#tracks").sortable({
items: "li:not(.placeholder)",
connectWith: "li",
placeholder: "sort_placeholder",
helper: "clone",
distance: 20,
sort: function () {
$(this).removeClass("ui-state-default");
updatePlaylist();
},
over: function (event,ui) {
updatePlaylist();
removeItem = false;
console.log(event);
console.log(ui);
var originalClass = ui.helper.context.childNodes[0].className;
console.log(originalClass);
var small_clip = originalClass.match(/(\d+)/g)[1];
ui.item.context.children[0].innerHTML = small_clip;
ui.item.context.children[0].classList.add("slot_clip_info");
},
out: function () {
updatePlaylist();
removeItem = true;
},
beforeStop: function(event,ui) {
if (removeItem) {
ui.item.remove();
}
},
stop: function(event,ui) {
console.log("checking placeholder");
var list = $(this);
var count = list.children(':not(.placeholder)').length;
list.children('.placeholder').css("display", count > 0 ? "none" : "block");
savePlaylist();
}
});
as soon as i pull and element IN or reorder them, i get the said error.
also, on refresh, the list seems to multiply itself.. but i guess that's another issue...
Full fiddle (pretty messy, functionality in top dropdown button "PL TOGGLE"
UPDATE: another thing i noticed: the first drag works without problems, then shows the error on release, subsequent drags will (mostly.. sometimes they do...) not work

you need to make ui a jquery object, and then wrap the first element in another jquery object to do what you want.
so change:
ui.children("li")[0].addClass(".slot_clip_info");
to
$($(ui).children("li")[0]).addClass(".slot_clip_info");

In jQuery UI's draggable module, the stop function has 2 parameters : event and ui.
ui is a javascript object (and not a jQuery one, there's a difference.)
This object has 3 attributes :
helper which is a jQuery object
position which is a javascript object
offset which is a javascript object
Depending on your HTML code (we don't have), you could replace
ui.children("li")[0].addClass(".slot_clip_info");
by
ui.helper.children("li")[0].addClass(".slot_clip_info");

Related

alert if already dropped div is dropped again using jquery

Below is my drag and drop script and it seems to be working like a charm, but what I want to add is if I drop a dragable div on a div that already contains the same div than it should give me an alert that this dragable element already exists or something like that, in order to achieve this I applied .prevAll.each() function to get the id's and compare to the last dropped div. So it compares the id's fine but when I drop the already existing div, it completely jumps the .prevAll.each() condition, it alerts its own id like the others but it does not go in the .prevAll, why is that?
Summing up what I want is:
Edit the approach below to get alert if already existed div is dropped.
Or any other approach would also be appreciated if it gives me the same functionality and doesn't affect any other thing, I already tried the .length approach its not working.
I hope I was able to explain, Any help would be appreciated, Thank you
$(".dragable").draggable({
cancel: "a.ui-icon",
revert: true,
helper: "clone",
cursor: "move",
live: true,
revertDuration: 0
});
$('.droppable').droppable({
accept: ".dragable",
activeClass: "ui-state-highlight",
drop: function(event, ui) {
var $item = $(ui.draggable);
if (!$item.hasClass('clone')) {
$item = $item.clone().addClass('clone');
$item.draggable({
cancel: "a.ui-icon",
revert: true,
cursor: "move",
revertDuration: 0
});
}
$(this).addClass('has-drop').append($item);
var divIdIs = $(ui.draggable).attr( "id" );
//if($(".droppable:has()"))
/*if($("#"+divIdIs).length>1){
alert("Yeah it does exist");
}*/
$("#"+divIdIs).prevAll().each(function() {
var upperDiv = $(this).attr('id');
/*var tes=$("#"+divIdIs).length;
alert(tes);*/
if(divIdIs == upperDiv){
alert("Matched");
}
else{
alert("Not Matched");
}
//if(divIdIs == existingdivId){}
//else{}
});
drop: function(event, ui) {
replace the above line as below and try
if (ids.indexOf("," + ui.draggable[0].id + ",") >= 0)
{
alert("This div already exists");
return;
}
ids += ui.draggable[0].id + ",";
Also make sure you declare the below variable globally,
var ids = ",";

Display hidden element with the help of jquery

I have some code in a jsfiddle and I want to display one hidden element <div id="e1"></div>
I have written code for this in jquery like this:
$("#credit4").sortable({
receive: function (event, ui) {
ui.item.remove();
var s="PLEASE SELECT ANOTHER BLOCK";
$("#e1").show();
$("#e1").html(s);
setTimeout('$("#e1").hide()',1500);
}
});
credit4 is the id of a draggable element and when the user wants to drag the element then this hidden elemet should be displayed.
You can also check my jsfiddle here - http://jsfiddle.net/sanjayrathod7/5cZD5/44/.
Please suggest me where I'm wrong.
Here's a simplified fiddle with a set of alerts in place indicating which line is hiding #e1. You can see that you're probably hiding it when you didn't intend to (at lines 45 and 171):
http://jsfiddle.net/isherwood/5cZD5/50
$("#credit").sortable({
receive: function (event, ui) {
ui.item.remove();
$("#e1").show();
$("#e1").html(s);
setTimeout('$("#e1").hide()', 1500); alert('hiding 10');
}
});
I have find out the answer
Try this
$( "#credit4" ).draggable({
revert: true,
start: function( event, ui ) {
var s="PLEASE SELECT ANOTHER BLOCK";
$("#e1").show();
$("#e1").html(s);
setTimeout('$("#e1").hide()',1500);
}
});

dragging DIVs to horizontal sortable container

I'm building some sort of a playlist creator. I have some items the user can choose from and a horizontal sortable timeline area to drop those items on.
The Draggable:
$(".Name:not(#Add a .Name)").draggable({
revert: 'invalid',
start: function(){
$('#MainPage').css('cursor', '-moz-grabbing');
$(".Name").css('cursor', '-moz-grabbing');
},
// helper: "clone",
helper: function() {
return $("<div class='"+$(this).parent().attr('class')+"' id='"+$(this).parent().attr('id')+"'><div class='"+$(this).attr("class")+"' id='"+$(this).attr("id")+"'>"+ $(this).attr("class").split(' ')[1] +"</div></div>");
},
stop: function() {
$('#MainPage').css('cursor', 'auto');
$(".Name").css('cursor', '-moz-grab');
},
connectToSortable: "#TimelineDrop",
appendTo: '#MainPage',
containment: 'DOM',
zIndex: 800,
addClasses: false
});
The Sortable:
$("#TimelineDrop").sortable({
over: function(event, ui) {
var Breite = ((TimeSpace*5)/(TimeSpace/(currentspacing+24)))-2;
$("#TimelineDrop").append("<div class='TimelineMarker' style='width:"+ Breite +"px;'>\u00A0</div>");
},
receive: function(event, ui) {
dropped=true;
AddElementToTimeline($(this), event, ui, dropped);
},
start: function( event, ui ){
$('#MainPage').css('cursor', '-moz-grabbing');
$('.TimelineElement').css('cursor', '-moz-grabbing');
drag=true;
},
axis: "x",
stop: function( event, ui ){
$('#MainPage').css('cursor', 'auto');
$('.TimelineElement').css('cursor', '-moz-grab');
database.updateElementPosition($('.TimelineElement').index($(ui.item)), $(ui.item).children('.TimelineElementTitle').attr('id').split('D')[1], GET('id'));
drag=false;
}
});
I tried all kinds of different stuff but can't get it to work propperly. What would like to be able to is drag items from the available area to the timeline und drop them between allready appended ones. So far the helper allways get appended (vertically) above the existing elements and when I drop it the final element get append at the very last position. I hope It's clear what I'm trying to archive...
I have a fiddle right here:
http://jsfiddle.net/5SBax/4/
I want the marker to be displayed where the element will be added (between others). And I need to get rid of the helper element which also get added every time...
Take a look at this fiddle. I'm not quite sure what you are asking, but this is a good example of drag and drop capabilities. I can't comment, and I am not quite sure what you are asking. But best of luck to you!
http://jsfiddle.net/cuhuak/4CHDZ/
function FieldType(typeName, name) {
var self = this;
self.TypeName = ko.observable(typeName || "");
self.Name = ko.observable(name || this.TypeName());
self.createField = function () {
return new Field(
{
Name: this.Name(),
TypeName: this.TypeName()
}
);
}
self.onDragStart = function(event, ui) {
dropFieldType = ko.utils.domData.get(this, "ko_drag_data");
};
self.onDragStop = function(event, ui) {
dropFieldType = null;
};
}

jQuery UI Draggable and Droppable, reverting and accepting elements

I have been experimenting with this code: jsfiddle It highlights and let you know which boxes you can drop the boxes onto but it is not accepting any droppables. Does anyone know how I can alter this code to accept a droppable instead of it just reverting back?
$(".DragItem").draggable({
revert: true,
helper: "clone"
});
$(".DropItem").droppable({
tolerance: "touch",
over: function (event, ui) {
var dropItem = $(this);
var dragItem = $(ui.draggable);
var valid = String(dropItem.data("id")).indexOf(dragItem.data("id")) > -1;
if (valid) {
dropItem.addClass("DropTargetValid");
} else {
dropItem.addClass("DropTargetInvalid");
}
},
out: function (event, ui) {
var dropItem = $(this);
dropItem.removeClass("DropTargetValid");
dropItem.removeClass("DropTargetInvalid");
},
deactivate: function (event, ui) {
var dropItem = $(this);
dropItem.removeClass("DropTargetValid");
dropItem.removeClass("DropTargetInvalid");
}
});
You will need to append the clones() to the correct divs and revert them if they don't match, first accept: all the dragable elements and then handle the revert in the drop: section.
also you will need to create and save the origin position for the ellement you clone and drag so you can revert him to its original position and then removing it from the page.
Here is the finall script demo:
JSnippet demo draggable & droppable
have fun!
I would start from something like this:
re-use the built-in query-ui functionality, e.g. "accept" or "activeClass" parameters of a droppable
if there is a small number of containers - you might declare "droppables" separately and use "accept" to e.g. allow only certain classes of draggables (like in the demo below)
trying to "hack" draggables & droppables is possible but not very easy, especially with complex elements (if draggables and droppables have more complex html structure than just flat divs)
Sample:
$(".drop1").droppable({
accept: '.drag1',
activeClass: 'DropTargetValid',
drop: function (ev, ui) {
$(ev.target).append(ui.draggable.clone());
}
});
Fiddle demo
--- EDIT ---
Updated demo

Sortable list, sort items just between different list

In this example http://jqueryui.com/sortable/#connect-lists is possible to drag and drop the items between different list and also the same list.
Will it be possible to dis-activate the drag and drop in the same list and allow just the drag and drop between different lists? how?
This is the best Ican do here:
$("#sortable1, #sortable2").sortable({
connectWith: ".connectedSortable",
stop: function(event, ui) {
if (ui.item[0].parentNode == this) {
$(this).sortable('cancel');
}
}
}).disableSelection();​
Demo http://jsfiddle.net/dfsq/J6uM5/
Working Demo :) http://jsfiddle.net/UnFdU/1/
I have built a small logic behind three events, recieve, start and stop. Everytime if the list is same list then user cannot drop it else if different list they can, try it your self. Little Explanation below
When user starts Dragging start says: canDropThat = false;
recieve only gets triggered if it item is dropped from connected list, i.e. if receive is triggered make canDropThat = true; ; hence allow dropping.
In the end stop checks for the flag and if its the right flag it allows dropping else reject.
Hope it fits the cause :))
Code
$(function() {
canDropThat = false;
var sortlists = $("#List1, #List2").sortable({
tolerance: 'pointer',
connectWith: '#List1, #List2',
helper: 'original',
scroll: true,
receive: function(event, ui) {
//Run this code whenever an item is dragged and dropped into this list
canDropThat = true;
},
start: function(event, ui) {
canDropThat = false;
},
stop: function(event, ui) {
if (!canDropThat) {
$(this).sortable('cancel');
}
}
}).on('scroll', function() {
sortlists.scrollTop($(this).scrollTop());
});
});​

Categories

Resources