Within the droppable function how can I get the draggable element's class name which is currently being dragged.
$( ".drop" ).droppable( { accept: handleFunction } );
function handleFunction(draggable){
//How to get currently dragging element's class name
}
I don't think you've got the accept option's usage correctly. It does not get the draggable currently being dragged, it tests the draggable that you just dropped in the droppable element. From the droppable documentation:
Function: A function that will be called for each draggable
on the page (passed as the first argument to the function).
The function must return true if the draggable should be accepted.
Regardless, what you get as a parameter is a jQuery element, not a JS object. You can test its classes in several ways:
$( ".drop" ).droppable( { accept: handleFunction } );
function handleFunction(draggable){
// This will return ALL classes attached to this draggable element as a string
// This is probably NOT what you need; it's VERY fragile
var className = $(draggable).attr('class');
// This returns a boolean for testing if myClass is present in the element's classes
// This is a very common function and probably what you want
var test = $(draggable).hasClass('myClass');
// Note return value should be a boolean.
return test;
}
my mouseleave is not working in my jquery code
http://jsfiddle.net/alano/9Dr7T/29/
providing my js code below
mouseleave: function () {
$(this).find("div:last").remove();
}
The problem isn't with the mouseleave listener, the problem is how you're binding those event handlers and unbinding them for that matter. The div was being removed, but it was being readded with every mouseenter event. For some reason the mouseenter event wasn't being unbound when using the selector filter for .on(). It probably has something to do with the way bubbling occurs when using the selector filter.
When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.
Now, I'm not 100% sure why just yet, but either way it will work if you use directly-bound handlers like so:
$('.specialHover').on({
mouseenter: function() {
$("<div class='cta'>add image</div>").click(function() {
var $me = $(this);
$me.parent().unbind('mouseenter').children('img').attr(
'src',
'http://www.onlinegrocerystore.co.uk/images/goodfood.jpg'
);
$me.remove();
}).appendTo(this);
},
mouseleave: function() {
$(this).find('div:last').remove();
}
});
See: http://jsfiddle.net/9Dr7T/35/
Did you tried this way:
mouseleave: function () {
$("div:last",this).remove();
}
I am extending a jQuery UI widget using the $.widget factory. In this particular case I'm inheriting from Wijmo's wijlinechart. I need to respond to the wijlinechart's "painted" event from within my child class.
Consider this:
$.widget("bw.wijlinechartcursor", $.wijmo.wijlinechart, {
_create: function () {
var self = this;
$.wijmo.wijlinechart.prototype._create.apply(self, arguments);
self.element.on("painted", function (e) {
alert("Got painted in child via element.on"); // Doesn't get called.
});
// This works, but blows away the client code's handler (below)
self.options.painted = function (e) {
alert("Got painted in child class via options.painted!");
}
},
_painted: function () {
alert("Got painted in child via _painted"); // Doesn't get called.
}
});
$("#mywijlinechartcursor").wijlinechartcursor({
// ... stuff...
painted: function (e) {
alert("Got painted in client code");
}
});
So what is the most effective way to handle an event down in a child class that is _trigger'ed by an inherited parent class?
Binding to the event with on() should work, then again that event is probably not named painted.
Each widget has its own event prefix, which defaults to the widget's name. If your base widget is not overriding this default value, the event will be named wijlinechartpainted.
In any case, the prefix is available in the widget's widgetEventPrefix property, so you can write:
self.element.on(self.widgetEventPrefix + "painted", function(e) {
alert("Got painted in child via element.on"); // Should be called.
});
I'm looking a way to binding the snap event.
When I'm dragging an element over my surface and the draggable element is snapped to a declared snap position I want to trigger an event.
Something like this:
$(".drag").draggable({
snap: ".grid",
snaped: function( event, ui ) {}
});
Bonus point: with a reference to the .grid element where the draggable element was snapped.
The draggable widget does not expose such an event out of the box (yet). You could modify it and maintain your custom version or, better, derive a new widget from it and implement the new event there. There is, however, a third way.
From this question, we know the widget stores an array of the potentially "snappable" elements in its snapElements property. In turn, each element in this array exposes a snapping property that is true if the draggable helper is currently snapped to this element and false otherwise (the helper can snap to several elements at the same time).
The snapElements array is updated for every drag event, so it is always up-to-date in drag handlers. From there, we only have to obtain the draggable widget instance from the associated element with data(), and call its _trigger() method to raise our own snapped event (actually dragsnapped under the hood). In passing, we can $.extend() the ui object with a jQuery object wrapping the snapped element:
$(".drag").draggable({
drag: function(event, ui) {
var draggable = $(this).data("draggable");
$.each(draggable.snapElements, function(index, element) {
if (element.snapping) {
draggable._trigger("snapped", event, $.extend({}, ui, {
snapElement: $(element.item)
}));
}
});
},
snap: ".grid",
snapped: function(event, ui) {
// Do something with 'ui.snapElement'...
}
});
The code above, however, can still be improved. As it stands, a snapped event will be triggered for every drag event (which occurs a lot) as long as the draggable helper remains snapped to an element. In addition, no event is triggered when snapping ends, which is not very practical, and detracts from the convention for such events to occur in pairs (snapped-in, snapped-out).
Luckily, the snapElements array is persistent, so we can use it to store state. We can add a snappingKnown property to each array element in order to track that we already have triggered a snapped event for that element. Moreover, we can use it to detect that an element has been snapped out since the last call and react accordingly.
Note that rather than introducing another snapped-out event, the code below chooses to pass an additional snapping property (reflecting the element's current state) in the ui object (which is, of course, only a matter of preference):
$(".drag").draggable({
drag: function(event, ui) {
var draggable = $(this).data("draggable");
$.each(draggable.snapElements, function(index, element) {
ui = $.extend({}, ui, {
snapElement: $(element.item),
snapping: element.snapping
});
if (element.snapping) {
if (!element.snappingKnown) {
element.snappingKnown = true;
draggable._trigger("snapped", event, ui);
}
} else if (element.snappingKnown) {
element.snappingKnown = false;
draggable._trigger("snapped", event, ui);
}
});
},
snap: ".grid",
snapped: function(event, ui) {
// Do something with 'ui.snapElement' and 'ui.snapping'...
var snapper = ui.snapElement.attr("id"),snapperPos = ui.snapElement.position(),
snappee = ui.helper.attr("id"), snappeePos = ui.helper.position(),
snapping = ui.snapping;
// ...
}
});
You can test this solution here.
In closing, another improvement might be to make the snapped event cancelable, as the drag event is. To achieve that, we would have to return false from our drag handler if one of the calls to _trigger() returns false. You may want to think twice before implementing this, though, as canceling a drag operation on snap-in or snap-out does not look like a very user-friendly feature in the general case.
Update: From jQuery UI 1.9 onwards, the data() key becomes the widget's fully qualified name, with dots replaced by dashes. Accordingly, the code used above to obtain the widget instance becomes:
var draggable = $(this).data("ui-draggable");
Instead of:
var draggable = $(this).data("draggable");
Using the unqualified name is still supported in 1.9 but is deprecated, and support will be dropped in 1.10.
In jquery-ui 1.10.0, the above code doesn't work. The drag function is instead:
drag: function(event, ui) {
var draggable = $(this).data("ui-draggable")
$.each(draggable.snapElements, function(index, element) {
if(element.snapping) {
draggable._trigger("snapped", event, $.extend({}, ui, {
snapElement: $(element.item)
}));
}
});
}
I'm looking over the ui.dialog source code, which is probably the best learning experience ever.
I see they reference uiDialog a lot, and it seems clear that uiDialog reefers to the widget itself. So I tried this in my widget, as in namespaceWidgetName but it's undefined. Do I understand uiDialog correctly, and how do I reefer to my widget within the widget?
(function( $, undefined ) {
$.widget("dbd.myWidgetName", {
options: {
//autoOpen: true,
},
_create: function() {
},
widget: function() {
return this.dbdMyWidgetName;
}
// rest of widget code
In the _create function of ui.dialog there is a line that reads:
uiDialog = (self.uiDialog = $('<div></div>'))
This is how the uiDialog property is initialized.
Depending on how your widget works, you might not need to provide a widget property/function. Many jQuery widgets do not. The dialog widget creates some DOM content that wraps the element you specify in $.dialog(), and its widget property/function enables you to access that DOM element.
If you want to provide a widget property to be consistent with dialog, you could simply use the underlying element of your widget like this:
$.widget("dbd.myWidgetName", {
options: {
//autoOpen: true,
},
_create: function() {
},
widget: function() {
return this.element;
}
}
All jQuery widgets have a property called element that refers to the underlying DOM element(s), wrapped in a jQuery instance. Take a look in a debugger to see how it works.