Reputation: 685
I use EasyAutocomplete
jQuery/AJAX showing all loaders while typing any field below is my example code and in the bottom has an example image like currently what happening.
My issue is while I type for job title then showing all loaders like city, on the other hand for the city input as same.
The question is how to show only this loader while I type for this like while I type for job title then want to show loader for job title input filed nor for the city, same as the city.
Perdon me if I didn't explain as well.
<form action="/search" accept-charset="UTF-8" method="get">
<div class="row">
<div class="col-md-6">
<div class="job-search-field">
<input type="text" name="key" id="key" placeholder="Keyword or Label like: Top,Mid,Entry" class="form-control" autocomplete="off">
<i class="icofont icofont-user-search"></i>
<div class="loader" style="display: none;"></div>
</div>
</div>
<div class="col-md-6 p-l">
<div class="city-field">
<input type="text" name="city" id="city" placeholder="City" class="form-control" autocomplete="off">
<i class="icofont icofont-location-pin"></i>
<div class="loaderCity" style="display: none;"></div>
<button type="submit" class="btn btn-default">Search</button>
</div>
</div>
</div>
</form>
and the JS
$(function(){
$(document).ajaxStart(function(){
$(".loader").css("display", "block");
});
$(document).ajaxComplete(function(){
$(".loader").css("display", "none");
});
});
$(function(){
$(document).ajaxStart(function(){
$(".loaderCity").css("display", "block");
});
$(document).ajaxComplete(function(){
$(".loaderCity").css("display", "none");
});
});
example image
Upvotes: 0
Views: 301
Reputation: 3854
Lets analyze your js code
$(function() {
$(document).ajaxStart(function() {
$(".loader").css("display", "block");
});
$(document).ajaxComplete(function() {
$(".loader").css("display", "none");
});
});
$(function() {
$(document).ajaxStart(function() {
$(".loaderCity").css("display", "block");
});
$(document).ajaxComplete(function() {
$(".loaderCity").css("display", "none");
});
});
$(document).ajaxStart(function()...
means taht we bind an ajaxStart
event to document. And you do it twice.
ajaxStart
event fires every time
Whenever an Ajax request is about to be sent...
So when any Ajax request is about to be sent here is what happens:
Both events triggers (because they are the same) and this is executed:
$(".loader").css("display", "block");
$(".loaderCity").css("display", "block");
Exactly the same thing happens for ajaxComplete
event.
When any Ajax request completes here is what happens:
$(".loader").css("display", "none");
$(".loaderCity").css("display", "none");
I hope you understand that (because that is what you did)
Now what is the solution?
Instead binding an ajaxStart
or ajaxComplete
events to document it is better to use beforeSend
and complete
callbacks.
Example
$.ajax({
url: "your_url.com",
... //all other ajax settings and callbacks
beforeSend: function( xhr ) {
$(".loader").css("display", "block");
},
complete: function( xhr ) {
$(".loader").css("display", "none");
}
});
EDIT
Since you're using EasyAutocomplete you should follow this section.
There are listed events that you can use.
So do it like this (Example)
var options = {
url: "resources/countries.json",
getValue: "name",
list: {
onLoadEvent: function () {
(".loader").css("display", "block");
}
onShowListEvent: function() {
$(".loader").css("display", "none");
}
}
};
$("#your-id").easyAutocomplete(options);
Upvotes: 1
Reputation: 2876
You should start your ajax request at a certain event like when the user is typing in the field with a debouncer(or use _.debounce(function, wait, [immediate]).
Some quick code so excuse my mistakes:
//When typing in the Keyword input field call the search function
//after the last keyup event.
$("#key").keyUp(function(event) {
debounce(search(inputElem), 300);
})
//Function that performs the ajax
function search(inputElem) {
//From the input element, get the `.loader`
inputElem.parent().find(".loader").show();
$.ajax({
url: "/search",
}).done(function() {
//Do something with the response
//Hide the `.loader`
inputElem.find(".loader").hide();
});
}
//Debounce function that executes the given function after a certain time
function debounce(fn, bufferInterval) {
var timeout;
return function () {
clearTimeout(timeout);
timeout = setTimeout(fn.apply.bind(fn, this, arguments), bufferInterval);
};
}
Upvotes: 0
Reputation: 1
Try to change $(document).ajaxComplete
to $(document).ajaxStop
Hope this helps.
Upvotes: 0
Reputation: 225
You are calling ajaxStart() function for document, which means if any ajax is started in a page or document, then the inside code will execute. As per your code
$(function(){
$(document).ajaxStart(function(){
$(".loader").css("display", "block");
});
$(document).ajaxComplete(function(){
$(".loader").css("display", "none");
});
});
$(function(){
$(document).ajaxStart(function(){
$(".loaderCity").css("display", "block");
});
$(document).ajaxComplete(function(){
$(".loaderCity").css("display", "none");
});
});
The code
$(".loaderCity").css("display", "block");
$(".loader").css("display", "block");
will be executed simulataneously as both are called on document ajaxStart.
Instead, you can try individually hiding and showing the loader on your $.ajax codes.
// Ajax code for jobsearch.
$.ajax({
url: 'yourURL',
type: 'post',
data: {parameter:data},
beforeSend: function(){
// Show image container
$("#loader").show();
},
success: function(response){
//Your Success code
},
complete:function(data){
// Hide image container
$("#loader").hide();
}
});
You can include the beforesend and complete function in your ajax calls for other inputs.
Hope this helps.
Upvotes: 0