Delay before dragging in gridster - javascript

I'm using gridster.net in project, and i've run into problem.
I'm trying to get widgets start dragging only after a second of holding mouse after click. I'm using the next code:
$(".gridster .gs-w").on('mousedown', function(e) {
gridsterObj.disable();
dragTimeout = setTimeout(function() {
gridsterObj.enable();
}, 500);
}).bind('mouseup mouseleave', function() {
clearTimeout(dragTimeout);
});
but it didn't work. It seems that i have to call function of starting dragging, something like gridsterObj.on_start_drag.call(gridsterObj, e, ui);, but where can i get the UI object? It's used everywhere in gridster code, but i can't find where it created.
It seems that it jquery UI object. How can i create it?

You should be able to reference the UI object as $.ui or window.jQuery.ui.
So your code should look like this:
$(".gridster .gs-w").on('mousedown', function(e) {
gridsterObj.disable();
dragTimeout = setTimeout(function() {
gridsterObj.enable();
gridsterObj.on_start_drag.call(gridsterObj, $.ui);
}, 500);
}).bind('mouseup mouseleave', function() {
clearTimeout(dragTimeout);
});

I've ended with the next code:
$(".gridster .gs-w").on('mousedown', function(e, data) {
var self = this;
if (!data || !data.start) {
gridsterObj.disable();
dragTimeout = setTimeout(function() {
gridsterObj.enable();
$(self).trigger(e, [{ start: true }]);
}, 500);
} else {
$(self).addClass('dragging');
}
}).bind('mouseup mouseleave', function() {
clearTimeout(dragTimeout);
});
With that, gridster has delay 0.5 second before starting dragging.

Related

Problems with mouseover and mouseout events in a continuous jQuery content slider

I have tried to built a continuous content slider in jQuery.
If you don't hover over it, then it works fine, it slides (even though I feel like I made it happen in a wrong way).
When you hover it then it stops, but only for 2 seconds. As you'd imagine, it should stay stopped until the cursor is removed. Maybe the interval is not cleared properly?
Generally the whole thing works improperly when you starts to hover/unhover.
Here's a demo of my plugin: http://jsfiddle.net/T5Gt3/
(function ($) {
$.fn.productSlider = function(options) {
var defaults = {
speed: 2000
};
var config = $.extend(defaults, options);
this.each(function() {
var $this = $(this),
$scrollable = $this.find('#content-product-slider-inner'),
timeLeft;
function animateScrollable() {
$scrollable.animate({ left: '-120px' }, config.speed, 'linear', function() {
$scrollable.css({ left: '0px' }).find('a:first-child').remove().appendTo($scrollable);
});
};
animateScrollable();
var timer = setInterval(animateScrollable, config.speed);
$scrollable.mouseover(function() {
$scrollable.stop();
clearInterval(timer);
});
$scrollable.mouseout(function() {
animateScrollable();
var timer = setInterval(animateScrollable, config.speed);
});
});
return this;
};
})(jQuery);
Any help would be greatly appreciated.
$(".event_list_inner_wrapper").live({
mouseenter: function () {
$(this).find('.front_side').fadeOut(600).hide();
$(this).find('.back_side').fadeIn(600).show();
},
mouseleave: function () {
$(this).find('.back_side').fadeOut(600).hide();
$(this).find('.front_side').fadeIn(600).show();
}
});
That's code I used for a project that was similar to your description. Basically, bind the mice events, and do your thing.

Update available drop targets after dragstart fires in jquery.event.drag

Overview:
I have a page which uses jquery.event.drag and jquery.event.drop.
I need to be able to drag and drop onto elements which are constantly being added to the dom, even after the drag has started.
Problem:
When the dragstart event fires it checks for available drop targets and adds them to the drag object.
The problem I have is I am adding drop targets dynamically, after the dragstart event has fired, and therefore the user cannot drop onto these dynamically added drop targets.
Example:
http://jsfiddle.net/blowsie/36AJq/
Question:
How can I update the drag to allow dropping on elements which have been added to the dom after drag has started?
You can use this snippet.
The important function is: $.event.special.drop.locate();
Tested on chrome/safari/firefox/ie9 and seems to work.
SEE DEMO
UPDATE
For overlapping events, see if following code works. I set it inside an anonymous function just to avoid any global variable.
Idea is to use currentTarget property of event to check if not the same element is triggering same event. I set an id on newdrop element just in purpose of test here.
SEE UPDATED DEMO
(function () {
var $body = $("body"),
newdrops = [],
currentTarget = {},
ondragstart = function () {
$(this).css('opacity', .75);
}, ondrag = function (ev, dd) {
$(this).css({
top: dd.offsetY,
left: dd.offsetX
});
}, ondragend = function () {
$(this).css('opacity', '');
for (var i = 0, z = newdrops.length; i < z; i++)
$(newdrops[i]).off('dropstart drop dropend').removeClass('tempdrop');
newdrops = [];
}, ondropstart = function (e) {
if (currentTarget.dropstart === e.currentTarget) return;
currentTarget.dropstart = e.currentTarget;
currentTarget.dropend = null;
console.log('start::' + e.currentTarget.id)
$(this).addClass("active");
}, ondrop = function () {
$(this).toggleClass("dropped");
}, ondropend = function (e) {
if (currentTarget.dropend === e.currentTarget) return;
currentTarget.dropend = e.currentTarget;
currentTarget.dropstart = null;
console.log('end::' + e.currentTarget.id)
$(this).removeClass("active");
};
$body.on("dragstart", ".drag", ondragstart)
.on("drag", ".drag", ondrag)
.on("dragend", ".drag", ondragend)
.on("dropstart", ".drop", ondropstart)
.on("drop", ".drop", ondrop)
.on("dropend", ".drop", ondropend);
var cnt = 0;
setInterval(function () {
var dataDroppables = $body.data('dragdata')['interactions'] ? $body.data('dragdata')['interactions'][0]['droppable'] : [];
var $newDrop = $('<div class="drop tempdrop" id="' + cnt + '">Drop</div>');
cnt++;
$("#dropWrap").append($newDrop);
var offset = $newDrop.offset();
var dropdata = {
active: [],
anyactive: 0,
elem: $newDrop[0],
index: $('.drop').length,
location: {
bottom: offset.top + $newDrop.height(),
elem: $newDrop[0],
height: $newDrop.height(),
left: offset.left,
right: offset.left + $newDrop.width,
top: offset.top,
width: $newDrop.width
},
related: 0,
winner: 0
};
$newDrop.data('dropdata', dropdata);
dataDroppables.push($newDrop[0]);
$newDrop.on("dropstart", ondropstart)
.on("drop", ondrop)
.on("dropend", ondropend);
$.event.special.drop.locate($newDrop[0], dropdata.index);
newdrops.push($newDrop[0]);
}, 1000);
})();
I wasn't able to get this working using jquery.event.drag and jquery.event.drop, but I did make it work with the native HTML5 events:
http://jsfiddle.net/R2B8V/1/
The solution was to bind the events on the drop targets within a function and call that to update the bindings. I suspect you could get this working with jquery.event.drag and jquery.event.drop using a similar principal. If I can get those working I will update my answer.
Here is the JS:
$(function() {
var bind_targets = function() {
$(".drop").on({
dragenter: function() {
$(this).addClass("active");
return true;
},
dragleave: function() {
$(this).removeClass("active");
},
drop: function() {
$(this).toggleClass("dropped");
}
});
};
$("div[draggable]").on({
dragstart: function(evt) {
evt.originalEvent.dataTransfer.setData('Text', 'data');
},
dragend: function(evt) {
$('.active.drop').removeClass('active');
}
});
setInterval(function () {
$("#dropWrap").append('<div class="drop">Drop</div>');
// Do something here to update the dd.available
bind_targets();
}, 1000)
});
You can't. On dragstart, possible drop zones are calculated from the DOM, and can't be edited until dragend. Even constantly rebinding the .on() (Demo: http://jsfiddle.net/36AJq/84/) will not provide the desired effect.
I solved the issue a little differently. (Demo: http://jsfiddle.net/36AJq/87/)
Start with every <div> in the HTML.
Apply opacity: 0 to make it invisible, and width: 0 to keep it from getting a dropend when hidden.
Use setInterval to show the next hidden div ($('.drop:not(.visible)').first()) each 1000ms.
JS:
$("body")
.on("dragstart", ".drag", function () {
$(this).css('opacity', .75);
})
.on("drag", ".drag", function (ev, dd) {
$(this).css({
top: dd.offsetY,
left: dd.offsetX
});
})
.on("dragend", ".drag", function () {
$(this).css('opacity', '');
})
.on("dropstart", ".drop", function () {
$(this).addClass("active");
})
.on("drop", ".drop", function () {
$(this).toggleClass("dropped");
})
.on("dropend", ".drop", function () {
$(this).removeClass("active");
});
setInterval(function () {
$('.drop:not(.visible)').first()
.addClass('visible').removeClass('hidden');
}, 1000)
Enable the refreshPositions option.
Why not place all the divs into the page and set their visibility to hidden? Then use setInterval() to change each one's visibility every second.

SlideToggle Div Animation

i have the following jQuery code.
$(function() {
$('.clickme').click(function() {
$('.totalthing').slideToggle('slow','easeInOutQuart', function() {
// Animation complete.
});
$('.expandedcase').slideToggle('slow','easeInOutQuart', function() {
// Animation complete.
});
});
});
At the moment it closes one of the div's and opens another at the same time. What I want it to do is close the open div then once it is fully closed it opens the other.
try:
$(function() {
$('.clickme').click(function() {
var tot = $('.totalthing');
var exp = $('.expandedcase');
var frt = (tot.is(":visible"))?tot:exp;
var lst = (tot.is(":visible"))?exp:tot;
frt.stop().slideToggle('slow','easeInOutQuart', function() {
lst.stop().slideToggle('slow','easeInOutQuart', function() {/*complete*/});
});
});
});
Your comments should point you in the right direction. If you want one animation to start once the other is complete, then move it to the function.
$(function() {
$('.clickme').click(function() {
$('.totalthing').slideToggle('slow','easeInOutQuart', function() {
// Animation complete.
$('.expandedcase').slideToggle('slow','easeInOutQuart', function() {
// Animation complete.
});
});
});
});

jQuery swap div on hover with delay

I'm trying to create two "buttons" that using the hover event, hide some divs and then display some others in their place. I'm then trying to delay the swapping back to the default div.
All works, fine, unless you go from one button to the other at which point you get many divs displaying at the same time until the delay passes. If we don't use the delay it works perfectly.
The javascript:
jQuery(function ($) {
$('#servers-btn').hover(
function() {
$('#servers, #servers-heading, #servers-arrow').show(0);
$('#default, #default-heading').hide(0);
},
function() {
setTimeout( function() {
$('#servers, #servers-heading, #servers-arrow').hide(0);
$('#default, #default-heading').show(0);
},1000)
}
);
$('#hosting-btn').hover(
function() {
$('#hosting, #hosting-heading, #hosting-arrow').show(0);
$('#default, #default-heading').hide(0);
},
function() {
setTimeout( function() {
$('#hosting, #hosting-heading, #hosting-arrow').hide(0);
$('#default, #default-heading').show(0);
},1000)
}
);
});
I assume i need to make one hover function aware of the other so it can cancel the timeout, i just have no clue how to do it.
EDIT - just tidyed up code to put all divs into one hide/show.
Also, i should have probably mentioned that the #default, #servers and #hosting divs appear in exactly the same location. So need to instantly switch at the same time (which the above does).
EDIT - latest attempt to use clearTimeout here http://jsfiddle.net/KH4tt/1/ - but can't quite make it work right.
You can use the .delay() function in jquery (I'm using Jquery 1.7.1 version) like the below example:
$(selector).delay(1000).hide("slow");
Try something like this
$('#servers-btn').hover(
function() {
$('#servers, #servers-heading, #servers-arrow').show(0);
$('#default, #default-heading').hide(1000, function() {
$('#servers, #servers-heading, #servers-arrow').hide(0);
$('#default, #default-heading').show(0);
});
}
);
Ok here's the final thing using the clearTimeout() function to cancel the setTimeout() that is used on mouseleave (hover handlerOut) that creates the delay:
jQuery(function($) {
var timeoutserver;
function canceltimeout() {
if (timeoutserver) {
window.clearTimeout(timeoutserver);
timeoutserver = null;
}
}
function closeServertime() {
timeoutserver = window.setTimeout(function() {
$('#servers, #servers-heading, #servers-arrow').hide(0);
$('#default, #default-heading').show(0);
}, 1000);
}
function closeHostingtime() {
timeoutserver = window.setTimeout(function() {
$('#hosting, #hosting-heading, #hosting-arrow').hide(0);
$('#default, #default-heading').show(0);
}, 1000);
}
$('#servers-btn').hover(
function() {
canceltimeout();
$('#servers, #servers-heading, #servers-arrow, ').show(0);
$('#default, #default-heading, #hosting, #hosting-heading, #hosting-arrow').hide(0);
}, function() {
closeServertime();
});
$('#hosting-btn').hover(
function() {
canceltimeout();
$('#hosting, #hosting-heading, #hosting-arrow').show(0);
$('#default, #default-heading, #servers, #servers-heading, #servers-arrow').hide(0);
}, function() {
closeHostingtime();
});
});

Implementing Hover Intent

I just finished developing this Wordpress theme:
http://www.minnesdiner.com/
Everything is working well, but I'm not 100% happy with the navigation.
The sliding position indicator works smoothly, but I'd like to integrate the hover intent jQuery plugin to prevent the sliding indicator from sliding when the user unintentionally passes over the nav.
Any ideas as to how I could integrate this plugin? I'm currently firing a separate jQuery function for each nav item and passing coordinates to the sliding indicator based on which item is being hovered upon.
Here's my current jQuery code:
$(document).ready(function() {
var $currentpos = $("#menu-indicator").css("left");
$("#menu-indicator").data('storedpos', $currentpos);
$(".current-menu-item").mouseenter(function () {
$("#menu-indicator").stop().animate({left: $currentpos}, 150);
});
$(".menu-item-26").delay(500).mouseenter(function () {
$("#menu-indicator").stop().animate({left: "52px"}, 150);
});
$(".menu-item-121").mouseenter(function () {
$("#menu-indicator").stop().animate({left: "180px"}, 150);
});
$(".menu-item-29").mouseenter(function () {
$("#menu-indicator").stop().animate({left: "310px"}, 150);
});
$(".menu-item-55").mouseenter(function () {
$("#menu-indicator").stop().animate({left: "440px"}, 150);
});
$(".menu-item-27").mouseenter(function () {
$("#menu-indicator").stop().animate({left: "570px"}, 150);
});
$(".menu-item-164").mouseenter(function () {
$("#menu-indicator").stop().animate({left: "760px"}, 150);
});
$delayamt = 400;
$("#header-row2").click(function () {
$delayamt = 5000;
});
$("#header-row2").mouseleave(function () {
$("#menu-indicator").stop().delay($delayamt).animate({left: $currentpos}, 600);
});
});
As you can see, I need to bind mousover and mouseout to separate elements (list-item and containing div).
Thanks!
If all you want to do is avoid the user triggering the slide by mousing over the nav, I would just setTimeout in your hover function to call your sliding code after a certain amount of time has passed, and clear the timeout on the mouseout event. No extra plugin needed.
For example:
var hover_timer;
$('.menu-item').hover(
function() {
hover_timer = setTimeout(function() {
...
}, 500);
},
function() { clearTimeout(hover_timer); }
);
EDIT: by the by, you should be combining all those hover functions into one. You can do something like:
$('.menu-item-26').data('slider-pos', '52px');
$('.menu-item-121').data('slider-pos', '180px');
...
And then in the code to slide, call it back:
$this = $(this);
$('#menu-indicator').stop().animate({left: $this.data('slider-pos')}, 150);
And that's just a start - you can generalize it even more, I bet.

Categories

Resources