I have a function that uses Ajax to get search results in real time, as the user types. It has a check if the input field's length is 1 or more, and if it is then it adds the class 'open' to display the dropdown for the search results. It also has an else statement, where if the length is 0 it removes open. This works fine on my localhost, but on my website if i hold backspace on more than two characters, it won't remove open (If i tap backspace it always works).
$(document).ready(function() {
$("#search").on('input', function() {
if ($('#search').val().length >= 1) {
$.ajax({
type: "POST",
url: "/url",
data: {
"json_str": $('#search').val()
},
dataType: "json",
success: function(data) {
if (!$("#searchbar").hasClass("open")) {
$("#searchbar").addClass("open")
}
if (data.length == undefined) {
$('#display').html("No results")
} else {
for (var i = 0; i < data.length; i++) {
console.log(data[i].username)
$('#display').append("<some html>")
}
}
}
});
} else {
$("#searchbar").removeClass("open")
}
});
})
I have found a solution, I am now aborting the last AJAX call if a new one is made before a response comes in.
var request = null;
$("#search").on('input', function() {
if (request){
request.abort()
}
if ($('#search').val().trim().length >= 1) {
request = $.ajax({.........
Try to trim the input value
if($('#search').val().trim().length)
Related
I have an ajax function which loads the next page or results in without refreshing. This works fine, but what I'm aiming to do is run this in a loop until a certain element is loaded in through the ajax call.
jQuery
var ajaxPageNumber = 2;
function infiniteResults() {
$.ajax({
type: 'GET',
url: '/?page=' + ajaxPageNumber,
success: function(data) {
ajaxPageNumber +=1;
if (data.length) {
$('.table tbody').append(data);
} else {
$('<div class="text-center"><strong>No more results remaining.</strong></div>').insertAfter('.table');
}
}
});
}
$(document).ready(function() {
var i = 0;
while (($('.desired-element').length < 1) && (i < 50)) {
infiniteResults();
i++
console.log("More results loaded");
}
} else {
console.log("Max tries reached, fail);
}
});
The problem I'm running into is that it fires all 50 of my loops ajax calls at once, so it appends page 2 of the data 50 times. This happens even though in my test, the desired element is on page 4.
Is something like this feasibly possible in jQuery/javascript?
All the calls happen in sequence very rapidly. Without knowing your full intent I would have it so the infiniteResults is only called again after it has completed, so these happen sequentially and not together.
I haven't tested this but this is what I am thinking...
var ajaxPageNumber = 2;
function infiniteResults() {
$.ajax({
type: 'GET',
url: '/?page=' + ajaxPageNumber,
success: function(data) {
ajaxPageNumber += 1;
if (data.length) {
$('.table tbody').append(data);
if (ajaxPageNumber < 50) {
infiniteResults(); // NEW
}
} else {
$('<div class="text-center"><strong>No more results remaining.</strong></div>').insertAfter('.table');
}
}
});
}
$(document).ready(function() {
infiniteResults();
});
You could return the promise that $.ajax returns, and use that in a kind of loop, by calling a function recursively (although the stack will not grow, due to the asynchronous nature):
var ajaxPageNumber = 2;
function infiniteResults() {
// return the jQuery promise
return $.ajax({
type: 'GET',
url: '/?page=' + ajaxPageNumber,
success: function(data) {
ajaxPageNumber +=1;
if (data.length) {
$('.table tbody').append(data);
} else {
$('<div class="text-center"><strong>No more results remaining.</strong></div>').insertAfter('.table');
}
}
});
}
$(document).ready(function() {
(function repeat(i) {
infiniteResults().done(function () {
if ($('.desired-element').length == 0 && i < 50) {
console.log("More results loaded");
repeat(i+1);
} else {
console.log("Max tries reached, fail");
}
});
})(0);
});
So I've been stuck at this problem for quite a long time. Basically I have a button (#action) located in index.html. I have a second page : number.html. I'm trying to get in the .receiver span from index.html either .success content or .failure content from number.html, depending if #action was clicked in less than 2 seconds.
Here is the code :
$(function() {
var ajaxRetrieve = function(callback) {
$.ajax({
url: 'number.html',
method: 'POST',
success: function(responseData) {
callback(responseData);
},
error: function(responseData) {
alert('Check yourself');
}
});
}
var flag = 0;
$('#action').on('click', function() {
flag = 1;
});
if (flag == 1) {
ajaxRetrieve(function(data) {
$('.receiver').html($(data).find('.success'));
});
} else {
setTimeout(function() {
ajaxRetrieve(function(data) {
$('.receiver').html($(data).find('.failure'));
});
}, 3000);
};
});
Problem : on click, I never get the .success content, and I have no error message. But after 2 seconds, the .failure actually shows up. I tried several ways to make it work but it doesnt. I also checked if the flag value was changed on click with an alert box, and it was
You need to include the ajax calls within the on click function, otherwise the if logic will only be called when the page is loaded and never again.
$(function() {
var ajaxRetrieve = function(callback) {
$.ajax({
url: 'number.html',
method: 'POST',
success: function(responseData) {
callback(responseData);
},
error: function(responseData) {
alert('Check yourself');
}
});
}
var flag = 0;
$('#action').on('click', function() {
flag = 1;
flagCheck();
});
var flagCheck = function() {
if (flag == 1) {
ajaxRetrieve(function(data) {
$('.receiver').html($(data).find('.success'));
});
} else {
setTimeout(function() {
ajaxRetrieve(function(data) {
$('.receiver').html($(data).find('.failure'));
});
}, 3000);
};
}
});
I want to create a "add" button in my jQuery calculator. When I click "add" button, it display "+" in the display and the number that I have entered will be stored. After that I can input another number to finish the equation. I can stuck in the part of the add button not sure how to do it. Do I need to use load()?
Try this out. Made a solution with limited inputs you have given
http://jsfiddle.net/sabkaraja/utc7f2ex/
You can decide what you want to do with the added value in #add.click(....) event. I have used a simple eval to get the result in.
$(function () {
var $display = $('#display');
$display.val(0);
$(document).on('click', 'button.number', function () {
if ($display.val().length >= 8) {
$display.val("Error");
} else if ($display.val() == "Error") {
$display.val("0");
} else {
$display.val( $display.val() + '+' + $(this).val());
}
});
$("#clear").click(function () {
$display.val("0");
});
$("#ce").click(function () {
if ($display.val().length >= 2) {
$display.val($display.val().substring(0, $display.val().length - 1));
} else {
$("#ce").trigger("click");
}
});
$("#add").click(function () {
if ($display.val().length !== 0) {
v = eval($display.val()); //<----- here is where I add the numbers
$display.val( v); //------------> do whatever you like to do after this
$.ajax({
url: 'submit.php',
type: 'POST',
dataType :'html',
data: {sum: v},
success: function(data) {
alert(data);
}
});
}
});
});
I have a function that attaches an autocomplete to any textbox I pass into it. As you can see, in the open function, towards the end, I fill in the word for the user and select the autofilled part so that they can delete it by pressing the delete key. The problem I am having is that when I delete the autofilled/autoselected part by pressing delete, the open function runs again for some reason and autofills the word again. This behavior only happens once. If I go ahead and delete the autofilled text for a second time, the textbox stays that way.
function attachAutoComplete(id, webMethod) {
$("#" + id).autocomplete({
source: function (request, response) {
$.ajax({
url: webMethod,
data: "{ 'pre':'" + request.term + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.d, function (item) {
return { value: item }
}))
}
});
},
messages: {
noResults: '',
results: function () { }
},
minLength: 2,
open: function () {
$('.ui-autocomplete').css('width', '169px');
$('.ui-autocomplete').css('z-index', '10000');
$('.ui-autocomplete').css('list-style-type', 'none');
$('.ui-autocomplete').css('border-width', '1px');
$('.ui-autocomplete').css('border-color', '#b6b6b6');
$('.ui-autocomplete').css('border-style', 'solid');
$('.ui-autocomplete').css('background-color', '#fff');
$('.ui-autocomplete').css('padding', '0px');
$('.ui-menu-item').css('cursor', 'pointer');
var input = $(this),
firstElementText = input.data("ui-autocomplete").menu.element[0].children[0].textContent,
original = input.val();
input.val(firstElementText);
input[0].selectionStart = original.length;
input[0].selectionEnd = firstElementText.length;
},
close: function () {
var input = $(this);
var firstThreeLetters = input[0].id.substring(0, 3);
if (firstThreeLetters == "SNP") {
GetVariantsGene(input);
}
}
});
}
Thanks in advance
update: The open function only runs again if the last character that the user entered is a letter. If the last character is a number, it does not run again.
I've this section of code (I'll point out where I'm confused, just added that huge wall to incase anyone wanted to really dig in).
anyway, the behaviour is to display these boxes, when you click on a box, the box expands, and displays more information. this works 70% of the time, however, it seems when an image is not chached, when you click the box again to minimize it, it starts to minimize, then pops back out. I'm wondering if this has something to do with the line: if($(this)[0].style.width == '70%'){
If this isn't enough, feel free to ask, and if you want to attempt to replicate the issue:
http://newgameplus.nikuai.net/
Try searching a few games, and clicking on the results. (That's only if what I"m saying isn't making sense though)
Thank you.
$container.on("click", ".box", function (event) {
var description;
var user_id;
var org_img = $(this).find("img").attr("src");
if ($(this)[0].style.width == '70%') {
$(this).find("img").attr("src", org_img);
$(this).css('width', '18%');
$(this).find(".resultData").fadeOut('slow');
$container.masonry('reload');
} else {
var me = this;
value['name'] = $(me).find("p").html();
oldImage = $(this).find("img").attr("src");
$.ajax({
url: 'scripts/php/fetchResultsData.php',
data: {
action: value
},
type: 'post',
dataType: 'json',
success: function (data) {
description = data[0][2];
for (var i = 0; i < $test.length; i++) {
if ($test[i][1][2]['name'] == value['name']) {
pos = i;
break;
}
}
$(me).find("img").attr("src", data[0][4]);
$(me).css('width', '70%');
$(me).append("\
<div class='resultData'>\
<div class='resultName'>" + value['name'] + "</div>\
<div class='resultDesc'>" + description + "</div>\
<div class='reasonDataTitle'> Similar tropes between this game and the searched games </div>\
<div class='reasonData'>" + $test[pos][4] + "</div>\
<div class='wikiLink'><a href='http://wikipedia.org/wiki/" + value['name'] + "'>Wikipedia</a></div>\
<div class='resultLike'></div>\
</div>");
value['clicked'] = 0;
$.ajax({
url: 'scripts/php/userProfile.php',
data: {
action: value
},
type: 'post',
dataType: 'json',
success: function (profileData) {
if (profileData == 'alreadyAdded') {
$(me).children('.resultData').children('.resultLike').html('un-Favourite');
} else if (profileData == 'notLoggedIn') {
$(me).children('.resultData').children('.resultLike').html('Login to add');
} else {
$(me).children('.resultData').children('.resultLike').html('Favourite?');
}
}
});
$(me).on("click", '.resultLike', function (event) {
event.stopPropagation()
value['clicked'] = 1;
$.ajax({
url: 'scripts/php/userProfile.php',
data: {
action: value
},
type: 'post',
dataType: 'json',
success: function (profileData) {
if (profileData == 'removed') {
$(me).children('.resultData').children('.resultLike').html('Favourite?');
} else if (profileData == 'notLoggedIn') {
$(me).children('.resultData').children('.resultLike').html('Login to add');
} else {
$(me).children('.resultData').children('.resultLike').html('un-Favourite');
}
}
});
});
$container.masonry('reload');
}
});
}
});
I would suspect there's a race condition in your effects code. jQuery effects run asynchronously, so $container.masonry('reload') will get called when fadeOut starts rather than after it's finished. If the jQuery Masonry plugin affects the display of any blocks you're fading out (and its documentation indicates that's highly possible), that race condition of both functions running at once will cancel the first one out.
To work around this, try running the Masonry reload in a callback function to fadeOut, like so:
$(this).find(".resultData").fadeOut('slow', function () {
$container.masonry('reload');
});
The reason it happens only sometimes is based on the speed of how things are loading, which would explain why it only happens when certain assets aren't cached.