i have a dynamic search in php with jquery.
When i'm entering a letter, an ajax call starts.
My problem is, that all ajax calls are working till end, so that every letter is a full call.
When a user is entering a full word then i have unused requests.
How can i stop the unused calls?
Thank you very much
Use timeouts to delay the request for a few millisecond, and clear it when a new key is pressed.
something like
var searchtimeout;
$('#search').keyup( function(){
if (searchtimeout)
{
clearTimeout(searchtimeout);
}
searchtimeout = setTimeout(function(){
// initiate the ajax call here..
}, 300);
} );
Either use a button to process the request that the user has to click when their finished or perhaps use something like debouncing.
One way you could do it , is to send the request when the user presses the return key , or atleast wait a few seconds ( 1-3 ) to see if the user stoped typing then make the request , you don't have to do the search for all changes on the input box .
Why dont you use the autocomplete plugin in jquery.. I am assuming you have handcoded the dynamic lookup.. auto complete takes care of most of these things and it is also configurable as to after how many letters you want to post to the server..it also implements caching.
I have used it in a lot of asp.net projects and it is pretty neat..
docs.jquery.com/Plugins/autocomplete
Ok, here is my solution:
if (searchtimeout)
{
clearTimeout(searchtimeout);
}
searchtimeout = setTimeout(function(){
if(x){
x.abort();
alert("MACH WEG!");
}
x = $.post(url + "ajax.html?nsearch=1&ckey="+SID, {queryString: ""+inputString+""}, function(data) { // Do an AJAX call
$('#suggestions').fadeIn(); // Show the suggestions box
$('#suggestions').html(data); // Fill the suggestions box
x = null;
});
}, 300);
Related
I'm creating online chat, but I'm wondering while using jQuery .load() in my script, my browser seems to get slow. When i checked the inspect element "Net" section, it loads bunches of GET-data... etc.
I would like to know if there's a better script solution with this code to prevent chat being heavy in the background while the data keeps looping in the background to check who's keep coming online/offline.
setInterval('loadThis()', 5000);
function loadThis () {
$("#loads").load('includes/users.php', function(){
$(".chat-side-panel li").each(function(i){
i = i+1;
$(this).addClass("stats"+i);
var status = $(".stats"+i).find("span.bullet").data("status"),
flag = $(".stats"+i).find("span.mail").data("flag");
if(status == 1) {
$(".stats"+i).find("span.bullet").addClass("online");
}
if(flag == 1) {
$(".stats"+i).find("span.mail").addClass("active");
}
});
});
}
the Chat-Side-Panel will be the main panel, and LI will be the listings of users including their status (online/offline) and flag (message received). As for the standard, what can you suggest for the setInterval time loading (if 5sec. is enough) or should i increase it.
Thanks for your input for this.
PS. We're doing this with both PHP/MySQL also.
One issue I see is that you keep re-querying the DOM for the same elements. Get them once, re-use them thereafter:
var load_target = $('#loads');
function loadThis () {
load_target.load('includes/users.php', function () {
load_target.find('.chat-side-panel li').each(function (i) {
var stats_li = $(this),
bullet = stats_li.find('span.bullet'),
mail = stats_li.find('span.mail');
bullet.toggleClass('online', (bullet.data('status') == 1))
mail.toggleClass('active', (mail.data('flag') == 1));
});
});
}
I don't know all of your involved logic or what the rest of your system looks like, so this particular code may not work exactly. It should simply serve as a re-factor done in a vacuum to show what that function could look like if you stopped hitting the DOM so hard.
Also, use of setInterval is not generally recommended. If the load of the remote file takes a while, you could end up calling loadThis() again before a previous one was completed. This would compound your DOM issues if calls to loadThis() began stacking up. Recursive use of setTimeout is preferred in a situation like this. Here is the above code modified to run recursively, and some usage examples below that:
var load_target = $('#loads'),
loadThis = function (start_cycle) {
$.ajax({
url: 'includes/users.php',
dataType: 'html',
type: 'GET',
success: function (response) {
load_target
.html(response)
.find('.chat-side-panel li').each(function (i) {
var stats_li = $(this),
bullet = stats_li.find('span.bullet'),
mail = stats_li.find('span.mail');
bullet.toggleClass('online', (bullet.data('status') == 1))
mail.toggleClass('active', (mail.data('flag') == 1));
});
},
complete: function () {
if (typeof start_cycle !== 'boolean' || start_cycle) {
load_target.data('cycle_timer', setTimeout(loadThis, 5000));
}
}
});
};
//to run once without cycling, call:
loadThis(false);
//to run and start cycling every 5 seconds
loadThis(true);
// OR, since start_cycle is assumed true
loadThis();
//to stop cycling, you would clear the stored timer
clearTimeout(load_target.data('cycle_timer'));
Last years (around 2012) I developed a chat system for a social network, and saw that
Using setInterval issue is when the request is being sent regularly, without waiting or carry about the result of the first requests in the queue. Sometimes the script can not respond and Mozilla or IE asks the user whether he should block or wait for the non-responding script.
I finally decided to use setTimeout instead. Here is what I did (I use $.getJSON so please study the example and how can use load instead)
function loadThis () {
$.getJSON('url').done(function(results){
//--use the results here
//then send another request
setTimeOut(function(){
loadThis();
},5000);
}).fail(function(err){
//console.log(print(err))
setTimeOut(function(){
loadThis();
},1000);
});
}
loadThis();
PS.: I would like to mention that the time depends on our many items are to be retrieved in your users.php file. Maybe you should use the paging tip. Your users.php can then treat url params users.php?page=1&count=100 for the first request, users.php?page=2&count=100 for the second until the results rows number is 0.
EDITS: In addition, I suggest you consider not interacting with the DOM every time. It is important too.
I have a form using the TinyMCE Editor running on a LAMP system. I wish to create an autosave feature similar to Google Docs. I have thought of two scenarios however, both will produce an overhead on the server.
Post an Ajax request on keyup
Post an Ajax request every 60s
Obviously the first point is not feasible. Can anyone suggest a better solution to point two?
Edit 1
Ok, so a third option could be a combination of Thariama's answer and my second point.
3) Post an Ajax request every 60s if there is signifcant change eg 10 chars or more
Any advances on this would be much appreciated.
Edit 2
Ok I have prototyped my solution based on point 3. In case anyone is interested my code flows like this:
I am using JQuery. I have a form with a textarea with TinyMCE attached to it and a hidden field to store a count of keystrokes.
tinyMCE.init({
...
// Callback for counting keystrokes in TinyMCE
handle_event_callback : "keyCount"
});
$(function() {
autoSaveContent();
});
// Callback function - Get count, increment it and then set it
function keyCount(e) {
if(e.type == "keypress") {
var count = parseInt($("#keyCount").val());
count++;
$("#keyCount").val(count);
}
}
// Autosave every 10s if there have been over 30 keystrokes
function autoSaveContent() {
var keyCount = parseInt($("#keyCount").val());
if(keyCount > 30) {
tinyMCE.triggerSave();
var formData = $("#programmedItineraryForm").serialize();
$.post("/path/to/save.php", formData, function(data,textStatus) {
if(data.success) {
$("#keyCount").val(0);
}
});
}
setTimeout('autoSaveContent()',10000);
}
Hmm, there are many options.
Point 1 is indeed a bit too expensive.
I think it would be a good idea to send a request based on the number of new characters entered in the editor. For example send a request every 5-10 new characters.
You can increment a counter onKeyDown or onKeyUp and reset that counter when a request gets send.
tinymce.init({
plugins: "autosave"
});
I'm trying to get an effect like the http://www.minecraft.net page where it auto updates sales from a database, I've been researching this for two months now and no luck.
I have a php file which finds how many results are in a database and displays them as a number, works fine http://tzeale.com/sandbox/stats/pull.php
What I'm trying to do is get the effect like minecraft.net where it auto updates without refreshing the page. Could anyone guide me on what to do? I don't know what else to try.
Thanks.
hYou need to use AJAX.
setTimeout, alongside a AJAX call to that pull.php
If you are using jQuery, here is a good example on how to achieve what you want.
Added a simple logic to see if the server is dead, and eventually stop.
var failed = 0;
var limit_failed = 5;
(function updateSales( waitTime ){
waitTime = waitTime || 1000; // Set to 1 second by default
setTimeout(function(){
$.ajax({
url: 'pull.php',
success: function( response ){
// Update something with your response
alert ("sales are now at: "+ response);
updateSales(); // Recursion
},
error: function(){
// Error handling - not necessary
// If the request failed more then (limit_failed) times, you might want to stop it from checking after (limit_failed) times,
// and in the meanwhile icnrease the wait time, so the server has more time to get back online.
if( ++failed < limit_failed ){
waitTime += 1000;
updateSales( waitTime );
}
}
});
}, waitTime);
})();
You would use setTimeout and Ajax. setTimeout would get the data every 1000 ms (or however you set it) using Ajax to get the data.
You would wrap your display count in your html like this for example:
<span id="mycount"></span>
Then your jQuery code would look something like this:
setTimeout(function(){
$.get("/sandbox/stats/pull.php",function(data){
$("#mycount").html(data);
});
},1000);
1000 is one second, you can change it if you'd like. I don't know how to make it animate like that, but it would go inside your $.get() function once you retreive the data. Also this must be on the same domain as http://tzeale.com/ for the Ajax to work due to same origin policy
HOWEVER, After reviewing te minecraft.net site, I noticed they are loading this data into their page one time, instead of getting it every 1 second:
<script>
var justLoggedIn = false;
var totalUsers = 33652552;
var paidUsers = 6495707;
var totalUsersRate = 1.2166667;
var paidUsersRate = 0.15;
</script>
Then they are not getting live data with this. They are just getting the current amount, then keep adding 1 to it.
They make it animate using this plugin: http://timeago.yarp.com/
And still using setTimeout() to keep adding 1 to it every second. I don't think this is real users, just a counter starting at the var totalUsers
I'm making a fairly simple rating system, and I've got a small problem. When you +1 rate something, I'm trying to run a PHP script which will connect to the database, download the value from it, +1 to that value, and UPDATE the value in the database again.
I don't think reloading the page for a continious rating system would be a very good idea :S
I'm wondering how I can toggle a PHP script with Ajax, so that when you Click an image of a + sign, it runs the PHP add 1 script, and the + button turns in to a tick. I'm crap at ajax, and I'd go for trying jQuery + $.ajax({}); but I've failed 73 attempts. haha.
Anyone willing to give me a hand writing an Ajax script? :DDD
Thanks! :)
If you want someone to click a link which will access your page, let's assume you have this marup:
<a class = 'plusOne' id = 'someIDForYourSQLTable'>+1</a>
The ID is what you are going to pass to your server script so you can update the appropriate row, generally speaking this should be a primary identifier (i.e. Key) for the record that you want to +1.
Here is the jQuery that will send the ajax request to the file: plusOne.php in the same directory as the current page:
$(function() {
$(".plusOne").bind("click", function() {
$.ajax({
type: "GET",
data: "v="+$(this).attr("id"),
url: "plusOne.php",
success: function(data) {
// Whatever you want to do after the PHP Script returns.
}
});
});
});
The request will send the a URL parameter 'v' which you can access in your PHP script from the $_GET super global array.
html
<img src="plusone.png" rel="some_unique_id" class="rate" />
javscript
$(".rate").click(function() {
var elem = $(this);
$.get('/rate.php?id=' + elem.attr('rel'), function() {
elem.attr('src', 'checked.png').unbind('click');
});
});
and in php
mysql_connect('localhost','db_user','pssword');
mysql_query('UPDATE database_name.table_name SET rating=rating+1 where id=' . mysql_real_escape_string($_GET['id']));
Have a look at xAjax, a library to expose PHP functions/method to client-side JavaScript. xAjax makes things very simple.
For example, you are able to perform several changes in the browser in parallel:
$objResponse = new xajaxResponse();
$objResponse->assign("myInput1","value",$DataFromDatabase);
$objResponse->assign("myInput1","style.color","red");
$objResponse->append("myDiv1","innerHTML",$DataFromDatabase2);
$objResponse->prepend("myDiv2","innerHTML",$DataFromDatabase3);
$objResponse->replace("myDiv3","innerHTML","xajax","<strong>xajax</strong>");
$objResponse->script("var x = prompt("Enter Your Name");");
return $objResponse;
I don't know what it's call. Example
http://search.twitter.com/search?q=%23idontbelieveyou
When you click link above wait a few seconds. Then you will see a notify like this
102 more results since you started searching. Refresh to see them.
There any tutorial for this? Let me know how to make something like that
It's really simple, logically:
A piece of Javascript checks back with the server every n seconds with a timestamp of the latest result it has.
The server checks if any results are available newer than this timestamp and reports back how many there are.
The Javascript displays this notification in the browser.
It would just sent an XHR to the server to see if any more tweets match the query.
If there are new matches, it will return the count and JavaScript updates the DOM to suit.
It is simply polling a script via jquery or Ajax (same thing really)
// Untested, written here without syntax.
var timeSinceUpdate = <?php echo(time()); ?>;
$(document).ready(function(){
setInterval(function(){
$.get('queriesSince.php?searched=idontbelieveyou×inceupdate=' + timeSinceUpdate , function(data){
alert(data);
if(confirm('Add new Data to screen?'))
{
//Add Stuff to DOM and update the timeSinceUpdate from the data recieved.
}
});
}, 3000);
});