mouseleave not working in jquery - jquery-ui

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();
}

Related

Can't get events to work on images with Highmaps

I'm trying to get the click and mouseOver handlers to work with Highmaps. I've checked the docs and tried to follow their examples. I inserted the event handler configs just about everywhere where I think it makes sense.
The wanted result is that the click and mouseOver handlers get called when hovering and clicking on the labels (pin icons) in the map.
Fiddle with my non-working code:
http://jsfiddle.net/fyp86hct/1/
One of the Highmaps examples shows that you should be able to do this:
point:
{
events:
{
click: function ()
{
alert("this doesn't work"); // <-- non working event handler
},
mouseOver: function()
{
alert("this doesn't work"); // <-- non working event handler
}
}
}
Unfortunately it is not supported, but you can add shape by renderer and then attach click event.

How to disable toolbar buttons during page transition?

I am using an external toolbar in a jQuery Mobile site I'm working on. I initialize it like so:
$(document).ready(function () {
$("[data-role='header'], [data-role='footer']").toolbar();
});
I have a couple of buttons in the toolbar and want to disable them during page transitions so users don't click them multiple times which seems to get the framework into a weird state. My first attempt has been to listen for the pagebeforeshow and pageshow events to programmatically disable and enable the buttons:
$(function() {
$("[data-role='header'], [data-role='footer']").toolbar({
create: function (event, ui) {
$(document).on('pagebeforeshow', function () {
$('#page-header .ui-btn').button('disable');
});
$(document).on('pageshow', function () {
$('#page-header .ui-btn').button('enable');
});
}
});
});
I have the code nested inside like that because I don't want to register the handlers until the toolbar has been initialized. However, I'm running into a separate problem:
Uncaught Error: cannot call methods on button prior to initialization; attempted to call method 'disable'
Since I'm not explicitly initializing the buttons myself, I'm not sure I understand how / where I can wait for them to be initialized.
Is there a better approach to this, and does anyone have any suggestions to get this working?
Use .button() on input with type button, reset and submit. For anchor or button tag you need to add / remove ui-state-disabled class.
$(document).on("pagecontainerbeforehide", function () {
$('#page-header .ui-btn').addClass('ui-state-disabled');
});
$(document).on("pagecontainershow", function () {
$('#page-header .ui-btn').removeClass('ui-state-disabled');
});
Demo

jQuery UI – draggable 'snap' event

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)
}));
}
});
}

Click and keydown at same time for draggable jQuery event?

I'm trying to have a jQuery UI event fire only if it meets the criteria of being clicked while the shift key is in the keydown state ( to mimic being held), and if not disable the event.
This example uses jQuery UI's .draggable to drag a container div only if the user clicks and holds shift.
http://jsfiddle.net/zEfyC/
Non working code, not sure if this is the best way to do this or what's wrong.
$(document).click(function(e) {
$('.container').keydown(function() {
if (e.shiftKey) {
$('.container').draggable();
} else {
$('.container').draggable({
disabled: true
});
}
});
});​
I see lots of errors with that code. Firstly, you only add the key listener after there's been a click on the document. Second you are adding keydown to the container div, rather than the whole document. Then, you also need to listen to keyup, since releasing the shift key should disable draggability, then you also need to pass disabled: false to the case where shift is down. And your handler is missing the e parameter. Try this:
$(function(e) {
var handler = function(e) {
if (e.shiftKey) {
$('.container').draggable({
disabled: false
});
} else {
$('.container').draggable({
disabled: true
});
}
};
$(document).keydown(handler);
$(document).keyup(handler);
});

JQuery UI and event handling

I have a jQuery UI widget which attaches to a div and then listens to specific controls inside it (set via options). The problem is that in my event listener, this refers to the control that changed, not the element the widget is attached to. So how can I access the widget element?
_addressChanged: function () {
$(this).data("address").requiresValidation = true;
},
_bindEventHandlers: function () {
$(this.options.address1).bind("change", this._addressChanged);
$(this.options.address2).bind("change", this._addressChanged);
$(this.options.city).bind("change", this._addressChanged);
$(this.options.zip).bind("change", this._addressChanged);
},
Use the this._on() method to bind the handler. This method is provided by the jQuery UI widget factory and will make sure that within the handler function, this always refers to the widget instance.
_bindEventHandlers: function () {
this._on(this.options.address1, {
change: "_addressChanged" // Note: pass the function name as a string!
});
...
},
_addressChanged: function (event) {
// 'this' is now the widget instance.
// 'this.element', as suggested by sjsharktank, is the DOM element the widget was created on
},
Have you tried this.element?
From http://wiki.jqueryui.com/w/page/12138135/Widget%20factory:
this.element
The element that was used to instantiate the plugin. For example, if you were to do $( "#foo" ).myWidget(), then inside your widget instance this.element would be a jQuery object containing the element with id foo. If you select multiple elements and call .myWidget() on the collection, a separate plugin instance will be instantiated for each element. In other words, this.element will always contain exactly one element.

Resources