I’m setting up a form to lookup or create a new city record in a web app. I need the text field for the city to do the following:
- Upon receiving text input, show a “spinner” indicating the computer is processing the input.
- After the user has stopped typing for 1 second, send an ajax request to check the input.
- Respond with the status (whether the input is valid).
I have this almost working but I have one major issue: the delay script I wrote works but after the delay is over it runs the rest of the function once per keyup that occurred during the delay. I would like it to only run once. Here’s the code I’m working with (the console log events would be replaced with other function calls later):
$(function() {
locationSelector.initialize();
});
var locationSelector = {
initialize: function() {
locationSelector.bindCityName $('input#city_name')
},
city: {
status: function( status ) {
console.log( "Status message: " + status );
},
error: function(message) {
console.log("Error message: " + message );
}
},
bindCityName: function(selector) {
selector.on('keyup', function() {
locationSelector.city.status('loading');
var timer = null;
if(timer) {
window.clearTimeout(timer);
}
timer = window.setTimeout(
function() { locationSelector.getCity( selector ); },
1000
);
});
},
getCity: function(selector) {
if( selector.val() == "" ) {
locationSelector.city.error('Cannot be blank.');
} else {
console.log("AJAX REQUEST");
}
}
};
Why is the getCity function is being run once per keyup, and how can I fix that? Also, to be honest I’m very much a javascript novice, so I would appreciate any other suggestions on how to improve this code scaffold.
Thanks!
It looks like the problem is here:
Timer gets set to null, so it never gets cleared. I’d suggest declaring timer at the top, above initialize, and then setting it to null only after you clear it, or after it gets executed.