Need multiple independent timers in Ajax - php

I need the ability to create up to N amount timers in JavaScript/Ajax that will count like a stopwatch(but have no buttons).
Another issue is that my data will be loaded via another Ajax request so the page will constantly be updating. I'm not sure how I would be able to keep a timer's correct value when that happens.
Thanks!

Javascript already has this functionality. Checkout the
setInterval
setTimeout
functions. Both will let you say "In x number of milliseconds, I want the following callback function to fire". With setTimeout, the callback fires once. With setInterval, the callback fires repeatedly until you tell it to stop.

Related

how to have ajax call simultaneously?

A few times a day, when our website is busy, we have more than 1000 requests per second on our database.
During these busy times, when a user clicks on an element and makes an AJAX call and then clicks another element and makes another AJAX call, the second call will wait for the response of the first call.
How can I have this AJAX calls run simultaneously? Is this time space between two calls because of the server being busy? If yes, how can we handle simultaneous AJAX calls?
I had similar problem as you do in the past. Then it was open session on server side. Even if ajax call was async, then it have to wait for server because of lock on session file.
Try to close session write when you do not write anything and then, check you ajax again.
Here you have reference to proper method: session_write_close

Get second ajax call response before previous ajax call

I have an ajax call which is used to perform a task and correspondingly update a table with the progress status.Now i have another ajax call to fetch the status from the table to show the task progress status to the user.The second call gets called repeatedly for every 2 seconds until the task is complete.But i could not show the task progress status to the user as the second ajax call keeps on loading till the response comes for the first ajax call.
I found a similar question in stackoverflow in the following link and it was suggested that it might be due to session lock and that using session_write_close() might work.I tried it and found no success.
Prevent jQuery AJAX call from waiting for previous call to complete
Is there a way to get the response for the second ajax call even while the first ajax call is still processing?
You can controller your Ajax functions flow using deferring concept of jQuery like
var defered = jQuery.Deferred();
function your_function(){
//do something!
defered.reslove()
return defered.promise
}
your_function.then(function(){
//this will not run till your_function is done
})
learn more at https://api.jquery.com/jQuery.Deferred/

Check users status

I want to make a user status system and i was thinking to have in my database a datetime field called last_active and update that field automatically with ajax with current time.
Then i check minutes between last_active and current time.. to tell if the user is online, inactive and offline..
Is this a good technique? and what happens if the user for example has the site open but is doing something else?
Is there a way to fire ajax request only if the user is viewing the page?
Your current method is a good technique to do, and the way to go,
you can check with focusin and focusout function with jquery to check if user is currently active on document or not,
$(document).ready(function(){
$([window, document]).focusin(function(){
// start the ajax requests
}).focusout(function(){
// stop the ajax requests
});
});
you should take variable that will set to true in focusin function and, will set to false in focusout function. now the continues ajax request function will fire only if the variable is set to true.
This is a very good way to check for activity. You can fire Ajax requests when the page is in focus only. I would consider using the mousemove event or similar, but also the blur/focus events can prove useful.
When the mousemove event is fired, set a variable to true and check thet variable before doing your Ajax request. Don't forget to reset it to false between each Ajax call.

HOW TO make test.php continue with rest of coding without waiting for a function to complete task?

This is the case. At test.php, I have a function dotask(a,b,c,d);
This function need to do task that need 2-4 minutes to complete.
Task including insert new record into db, curl call to other url to do task and etc.
However, I want test.php to:
Just make sure dotask(a,b,c,d) is called, no need to wait until task completed then only return and continue with the remaining code at bottom.
Reason: test.php is a thank you page. I can't expect the user to wait few minutes for the task to be completed. Because I need to show thank you messages etc at that page to user.
What can I do?
You can't fork a process in PHP without a lot of hackery. I'd recommend using a queue and worker pattern instead. See this answer: PHP- Need a cron for back site processing on user signup... (or fork process)
I seen a few solutions here that require you to pass in the page that you want to run, eg:
BackgroundProcess::fork('process_user.php');
But my case is at test.php, I have dotask(a,b,c,d)
I need to pass in parameters from this site to continue the work.
So should I just pass in this few parameter into a new dbtable call pendingprocess, then at process_user.php , I read from database and continue the task instead?
I can't embed parameter into taskpage.php right...
Another solution I can think of is at thankyou.php I do a body onload ajax call by passing in parameter to process_user.php to perform task. Anyone can advice whether this is a good way?
Will the process stop executing when user click STOP at browser? What if they go to refresh the browser.

Avoid Race Conditions in PHP on Submit: Please do not click submit more than once!

A while back, online apps used to say, "do not click submit more than once." That's gone now, right? How do you guard against that in, say, PHP?
One solution I'm using involves putting a variable in the Session, so you cannot submit to a page more than once every 10 seconds. That way the database work will have completed so the normal checks can take place. Obviously, this feels like a hack and probably is.
Edit: Thanks everybody for the Javascript solution. That's fine, but it is a bit of work. 1) It's an input type=image and 2) The submit has to keep firing until the Spry stuff says it's okay. This edit is just me complaining, basically, since I imagine that after looking at the Spry stuff I'll be able to figure it out.
Edit: Not that anyone will be integrating with the Spry stuff, but here's my final code using Prototype for the document.getElementByid. Comments welcome!
function onSubmitClick() {
var allValid = true;
var queue = Spry.Widget.Form.onSubmitWidgetQueue;
for (var i=0;i<queue.length; i++) {
if (!queue[i].validate()) {
allValid = false;
break;
}
}
if (allValid) {
$("theSubmitButton").disabled = true;
$("form").submit();
}
}
For some reason, the second form submit was necessary...
You should do both client- and server-side protections.
Client side - disable button e.g. by jquery as cletus has described.
Server side - put a token in the form. If there are two submissions with the same token, ignore the latter. Using this approach, you are protected against CSRF.
This is an excellent example of what jQuery is useful for (you can do it in any Javascript though). Add this code:
$("form").submit(function() {
$(":submit",this).attr("disabled", "disabled");
});
And it disables submit buttons once clicked once.
As others have noted, you can disable the button. I like server-side checks better, though - JS may be disabled, user might hit refresh (although if you're properly using POST that will generate a warning), etc.
You can add a timestamp to the form and track it in the session - require the POSTed timestamp be greater than the tracked one. That will prevent most double-posts without noticeably affecting the UI.
It's also important to note that PHP's default behaviour if it detects the user has "cancelled" the request (by closing the browser, pressing "stop", or perhaps pressing Submit a second time) is to stop executing the script. This is undesirable if you're doing some sort of lengthy transaction. More details here.
I would think the best option is to let the PHP script first set a flag in the session array to indicate that it is processing a form. That way a second request can be set to wait until the original request has completed (use a sleep call server side waiting for the flag to clear).
It is important not to interfere too much with the submit button and process, because the nature of the web is one of uncertainty; the user may want to click a second time if no answer has arrived, and you don't want to lose their data. That could occur if the first request is lost and you have disabled their only way to submit (and therefore store) the data.
One cleaner solution is to submit the request, and use javascript to display a message saying 'Processing', so that the user can see that something is happening, but they are not prevented from re-submitting the data.
One solution is to immediately disable the button on click using Javascript. This obviously relies on javascript being on on the client browser.
The server side trick is better since it will catch race conditions between multiple browser windows if the user is editing the same record twice.
I've done a simple version of this with javascript when I was working with ASP.NET AJAX but it should work in any case where your button has an actual ID.
I take the following steps in the button onclick event:
Disable the button that triggered the onclick event
Store the button id in a magic variable closureId that I can reference later via closure
Use the setTimeout function to execute a dynamically defined callback after the specified number of milliseconds (5000ms = 5 seconds)
In the callback function I can reference the magic closureId and re-enable the button after the timeout
Below is a simple HTML button you can throw into a test.html file by itself to play with:
<input id="btnTest" type="button" value="test" onclick="var closureId=this.id; this.disabled = true; setTimeout(function(){document.getElementById(closureId).disabled = false;}, 5000);>
You should still be doing server-side checks as others have suggested but in my own instance the submit also did a server side validation of business logic. The user would submit their form and then have to wait to see if the business logic on the server-side would actually allow that entry or not. It also helped out during development when I could take my server down and still have the form submission fail decently.
Note I call that closureId variable 'magic' because I don't have a firm grasp of how it works--
I just realized that calling this.id didn't work because this is a reference to the timeout function that is executing the dynamic callback function and doesn't have any sort of DOM id.
I couldn't find any other way to get a reference to the original event (this.this.id doesn't work) but lexical scoping is somehow allowing me to still access the closureId variable as it was defined at the time of the original button click.
Feel free to fix/comment if you know of a better way!
I usually disable the submit button after it's pressed. Session throttling is good against direct attacks, but I do not want to mix interface logic where it doesn't belong.

Categories