Adding a jQuery delay on autocomplete - javascript

I'm trying to create a jQuery autocomplete for an application:
$("#search-input").on('keyup', function() {
search = $(this).val();
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
});
});
What would I need to add to the above code to add a 400ms delay?

Use
setTimeout(function() {
// your code here
}, 400);
setTimeout is a method provided by the browser's window object.
A more complete example that cancels a timer if already set using clearTimeout would be:
var myTimer = 0;
$("#search-input").on('keydown', function() {
search = $(this).val();
// cancel any previously-set timer
if (myTimer) {
clearTimeout(myTimer);
}
myTimer = setTimeout(function() {
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
});
}, 400);
});
Also note use of on instead of the deprecated live.

Your code should look like this: (for jQuery 1.7+)
$(document).on('keyup', "#search-input", function () {
clearTimeout($(this).data('timeout'));
var _self = this;
$(this).data('timeout', setTimeout(function () {
$.get('/ajax/search/', {
search: _self.value
}, function (response) {
$(".autocomplete").html(response);
});
}, 400));
});
If using older jQuery version, use live() or better delegate(). BTW, you should bind it to closest static container, not document.

You can use the setTimeout() function to delay the start of the expression, in this case, your function. Beware that this does not delay processing beyond this code. It will only delay the start of this function, while continuing to process code after the function.
$("#search-input").live('keydown', setTimeout(function() {
search = $(this).val();
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
})
},400));
EDITED: to correct misplaced parentheses.

Related

Using 'this' in nested functions

Wow.. to get real information about 'this' is not easy as google basically ignores the word.
The code opens an image from a database using the information from thumbnail.. the onlick works, and the hover code works, but I can't figure out how to get 'this' from the mouseenter to be used in the showModal function.
function showModal() {
$("body").css("overflow-y", "hidden");
$(".small").removeClass("smallHover");
$(".modal").fadeIn(200);
var altLong = $(this).attr("alt");
var altSplit = altLong.split("#");
$(".picTitle").text(altSplit[0]);
var srclong = $(this).attr("src");
var srcshort = srclong.split("_");
var srcextension = srclong.split(".");
$(".big").attr("src", srcshort[0]+'.'+srcextension[1]);
}
$(".small").click(showModal);
var timer;
$(".small").mouseenter(function() {
timer = setTimeout(function(){
$(this).showModal(); // **<--this is the line that doesnt work**
}, 2000);
}).mouseleave(function() {
clearTimeout(timer);
});
also if you could explain why you would use $(this) as a jquery object instead of just 'this' and how they differ, that would be great. Thanks in advance~!
There are two separate aspects to this.
Getting the right this in the setTimeout callback
Calling showModal with that this
#1 is addressed by this question's answers. You have several options, the simplest in this case (for now) probably being to use a variable:
$(".small").mouseenter(function() {
var _this = this; // ***
timer = setTimeout(function(){
$(_this).showModal(); // ***
}, 2000);
}).mouseleave(function() {
clearTimeout(timer);
});
...but that code still won't work, because showModal isn't a property of jQuery objects, it's a standalone function. To call it with a specific this, you'd use Function.prototype.call:
$(".small").mouseenter(function() {
var _this = this;
timer = setTimeout(function(){
showModal.call(_this); // ***
}, 2000);
}).mouseleave(function() {
clearTimeout(timer);
});
(Alternately, change showModal to accept the element as a parameter and then just pass it as an argument.)
More on this in this question's answers as well, as well as this (old) post on my anemic little blog.
this will also work if you could change your showModel function like this :
$.fn.showModal = function() {
$("body").css("overflow-y", "hidden");
$(".small").removeClass("smallHover");
$(".modal").fadeIn(200);
...
}
and inside timer method
$(this).showModal();

Maintaining jQuery order of execution

In my jQuery code, I am having trouble with keeping the correct order of execution. I looked around and found out that using setTimeout() is an option but I am not sure where to use. The current structure of the code is like below with setTimeout():
$(document).ready(function(){
$('#search-submit').on('click', function(){
var keyword = $('#search-input').val();
$(".loading").show();
setTimeout(function() {
if(){
//some conditions and calls to post
}
$(".loading").hide();
}, 0);
}
}
The hide() should take effect after the if block is finished executing, but now it directly hides the element.
Actually, jQuery has a more refined way of making things synchronous :
$(function() {
$('#search-submit').on('click', function(){
var keyword = $('#search-input').val();
$('.loading').show().queue(function() {
if ( ... ) {
//some conditions and calls to post
}
$(this).dequeue();
}).queue(function() {
$(this).hide().dequeue();
});
});
});
$(document).ready(function(){
$('#search-submit').on('click', function(){
var keyword = $('#search-input').val();
$(".loading").show();
if(){
//some conditions and calls to post
}
setTimeout(function() {
$(".loading").hide();
}, 1500);
}
}

Move element with jQuery plugin - setInterval

Why this code doesn't work?
I wrote This code but:
(function($){
$.fn.newsSlider = function() {
setTimeout(function() {
this.each( function() {
$(this).each(function(){
$(this).append($(this).children(":first-child").clone());
$(this).children(":first-child").remove();
});
});
}, 3000);
}
}(jQuery));
With setInterval:
http://jsfiddle.net/OmidJackson/46UNg/
Without setInterval:
http://jsfiddle.net/OmidJackson/6bKWU/
Your problem is that this has different meaning (the window object) inside the setTimeout function literal. Check this answer for further info about this in different contexts.
The solution is to save a reference to this so you can use it inside the setTimeout.
See this example.
You need to store the this as it currently has a value of window
var $this = this;
setTimeout(function() {
$this.each( function() {
$(this).each(function(){
$(this).append($(this).children(":first-child").clone());
$(this).children(":first-child").remove();
});
});
}, 3000);

SetInterval using linkObj

With this code I expect to see a 'yo' added to the console every second while I'm hovering over .cell-top. But I get one 'yo' and that's it.
function cellUp(linkObj) {
console.log('yo');
}
$(".cell-top").hover(function() {
setInterval(cellUp($(this)), 1000);
});
Any idea what I can do to get my expected results?
PS. I'm using linkObj to get $(this) in a function within cellDown, I didn't include the function because that's unrelated to the issue I'm having. I did include the linkObj because I figured it may be part of the issue.
Since you're using jQuery, you can use $.proxy.
$(".cell-top").hover(function() {
setInterval($.proxy(cellUp, null, $(this)), 1000);
});
var interval;
function cellUp(linkObj) {
console.log(linkObj);
}
$(".cell-top").hover(function() {
var self = this;
interval = setInterval(function(){cellUp($(self))}, 1000);
},function() {
clearInterval(interval);
});

Fade or clear div element after a period in MooTools 1.1

Hello I am trying to simulate the fade method provided in mootools 1.2 in 1.1.
Due to development restrictions I have to use 1.1. I basically update my div after an ajax response and I want this div to get cleared after some time
var resp = Json.evaluate( response );
$(elem).setHTML('Thanks!'); //Show the message for a while and then clear the div
Thanks for your responses I'm trying to use Dimitar's approach but since I'm not a MooTools expert at all I will need some help
window.addEvent('domready', function(){
$(link_id).addEvent('click', function(){
var a = new Ajax( '{$url}'+this.id, {
method: 'get',
onComplete: function(response) {
var resp = Json.evaluate( response );
$(resp.id).setHTML('Thank you');
//My stupid approach //setTimeout('$("'+divname+'").setHTML("")',3000);
}
}).request();
});
}
So in the context of my code where should I define the Element.extend you propose?
I just tried to add it inside the domready function but couldn't recognise the fade method
to define element prototypes in 1.1x you need Element.extend
Element.extend({
fade: function(from, to, remove) {
new Fx.Style(el, "opacity", {
duration: 500,
onComplete: function() {
if (remove)
this.element.remove();
}
}).start(from, to);
}
});
var el = $("elem");
el.setHTML('Thanks!');
(function() {
el.fade(1,0, true);
}).delay(2000);
in this example I have created a simple element.fade() which DOES need start and end value and can optionally remove the element from the dom etc if you dont plan on needing it again.
here's a working example: http://jsfiddle.net/dimitar/cgtAN/
edit as per your request to empty the html:
window.addEvent('domready', function() {
$(link_id).addEvent('click', function() {
new Ajax('{$url}' + this.id, {
method: 'get',
onComplete: function(response) {
var resp = Json.evaluate(response), target = $(resp.id);
target.setHTML('Thank you');
(function() {
target.empty();
}).delay(3000);
}
}).request();
});
});
Never used Mootools much, but after a bit of jsfiddle, it seems like something along these lines would work:
function fadeAfter(id, msec)
{
setTimeout(function(){
new Fx.Styles(id).start({'opacity': ['1', '0']});
}, msec);
}
Ok I found a solution using setTimeout
setTimeout('$("'+divname+'").setHTML("")',3000);
where 3000 the waiting time in milliseconds

Categories

Resources