javascript auto submit result in a loop - javascript

A php page (let's call it page_one) checks certain values on DB and echoes different questions on screen depending on those values. The user sets some radios and click submit. The code send the radio values to another php file (let's call it page_two) where they are written in the DB and then the code puts new values in hidden fields of a hidden form and submits them loading again page_one, where new questions are presented. And so on till the number of questions-set is finished.
To auto-submit to page_one I use the following javascript inside the php file page_two.
<script>
var auto_refresh = setInterval(function() { submitform(); }, 50);
function submitform()
{
/*alert('test');*/
document.getElementById("hidden-form").submit();
}
</script>
On Firefox (Mac) and Safari (Mac) and iOS(Safari) everything goes right: page_two writes the values in the db and calls back page_one.
Instead of doing the same, Chrome enters in a loop, and continues to call page_two every 50 ms, for thousands of times till something breaks all that.
Any help?

Thats what setInterval is made for.. it will run for every 50 mili seconds and submit the form.. if you need it to call it once then use setTimeout.
The setInterval() method calls a function or evaluates an expression
at specified intervals (in milliseconds). The setInterval() method
will continue calling the function until clearInterval() is called, or
the window is closed.
reference: setInterval
The setTimeout() method calls a function or evaluates an expression
after a specified number of milliseconds.
reference: setTimeout

Related

onkeyup Event Firing delay

I have a input textbox for people to enter a username, it has a onkeyup event attribute attached which fires off an AJAX request to check if the username is taken.
What is the delay between the first key to the second ? Meaning if I type a 5 letter word one letter after the other. Does the AJAX fire 5 times ?
If there is no delay, would this be "computationally expensive" since there would so many database queries ? Or would there be no noticeable difference ?
If there is a difference in performance, what methods could I take using Javascript to check if the user is actually "done" typing. I still want it to automatically check after typing. Thus ruling out onblur attributes etc.
My Code: http://pastebin.com/hXfgk7nL
(code indentation wasn't working for me on stack overflow)
Yes it will fire EVERYTIME you type a character and you're not going to like that in terms of your page performance. You can implement delays on executing the call back if you like ie. it will not be executed until the user stopped typing. Here's an example:
$(document).ready(function(){
$('#txtboxid').keyup(function(){
clearTimeout(timer);
timer = setTimeout(function(){
//call your function here
}, 250) // you can change the 250 here to a higher number if you want the delay to be longer. In this case, 250 means a quarter of a second.
});});
Following are my replies/suggestion for your queries:
Yes , it will fire 5 fives because 5 times key-up event will be triggered.
it will be a performance issue, resulting in slow response from server,also since your making multiple ajax request sequentially, the response from each request may not be sequential.your code will suffer from logic issue.
instead of making ajax call for key-up, you can use it for blur event.
Suggestion: before making a ajax call validate the field for basic errors like blank string, numbers etc.,(depending on your requirement).
Yes it will fire multiple times, one for each keystroke. You are triggering multiple AJAX calls, so you are wasting network and server resources.
Additionally, you are not guaranteed on the order in which the calls will return, so if for some network reason, the first call issued return last, it will overwrite the results of the most recent request.
To tackle the problem, you are looking for something like this plugin: https://github.com/cowboy/jquery-throttle-debounce.
From the plugin usage example:
function ajax_lookup( event ) {
// Perform an AJAX lookup on $(this).val();
};
// Console logging happens on keyup, for every single key
// pressed, which is WAAAY more often than you want it to.
$('input:text').keyup( ajax_lookup );
// Console logging happens on window keyup, but only after
// the user has stopped typing for 250ms.
$('input:text').keyup( $.debounce( 250, ajax_lookup ) );
Note that despite the name the plugin can also be used stand alone, without jquery.
Yes, it will fire every key-up event. You can reduce the performance hit using following approach.
I am sure you must have a minimum character length for username. Wait until user type that number of characters to query the database.
You could always bring all the usernames starting with user typed username and process in local memory. This may not be real time but would reduce the number database queries. Also it would depend on the size of your current user list.
Double check the existence of the username before saving it to the database.
yes it will fire. if you don't need that means, you have to check conditions with a flag. check the given value with the previous value which is stored in a variable.
You can try to check if your input is modified in 500 ms. Is is not, then make only one ajax request. If the input is modified again than you must repeat the process again.
I suggest to use setInterval for that.

jQuery setInterval from getScript

I am trying to get a script from one page and get it again after a certain period of time. But, the time varies each time. On the main page I have
function varcontent() {
$.getScript("custom.php");
}
varcontent();
Then on the custom.php I have my script and
setInterval(varcontent, 20000);
at the end. Each time it may not be 20 seconds. It seems to work at first, but then the old ones are fired again too. I don't know how to get it out of this loop and they keep multiplying.
You probably want setTimeout, not setInterval. setInterval will keep invoking the callback (until you cancel it), whereas setTimeout will only invoke the callback once after the specified delay.
So in your custom.php, you should have instead:
setTimeout(varcontent, 20000);

Javascript table on the fly

I've got some issues with javascript. Which causes some problems.
I'm using DevExpress MVC GridView, ASP.Net MVC 3 and javascript.
This my problem:
I've got a gridview, with for example customers.
I want them to select the customers, and show them in a table generated by javascript so we dont get all those refreshes. And they can then add other information so that they can be saved again to another table, but thats not really important.
I perform some calculations before generating the table row from the selected customer. Another problem is, the devexpress gridview has an event that calls on each selection change instead of a nice ~100 ms wait so that the user can multiselect quick without triggering method 3/4 times.
Im keeping track of my own table through an array. And the GridView from DevExpress got his own events that can give me the right information, so no need to worry about that.
So I got a method receiveSelectionFields(Values){ //do something } where I receive that information from the gridview on every selection.
Then I check my array to see if they added or removed a selection, and which.
Then I call addtablerow(customer) or removetablerow(customer). Which removes the customer from my table and then from my array.
Because I make some heavy calculations in between, there is a ~60ms delay before the calculation is done (on mine computer). So if the users makes 2 selections in 60 ms. My array will have the wrong value (not being modified by the first call that adds/removes a customer) and my javascript will cause an error e.g. the table row is not deleted. I check on length of my own array and on the length of the received array to see if something has been added or removed.
So what did I try?
Making my method a recursive method, that when the problem occurs it waites 60 ms and then redo the method. But this isn't working properly.
I tried adding a global variable busy, which is true when the method is still busy. And false when it ends. But my browser just quits when doing that. This was the code:
while (true) {
setTimeout(function () {
if (busy === false) {
break;
}
}, 50);
}
But I got the feeling it just endlessly loops.
And these are all workarounds, there must be a nice way to solve this. Any thoughts?
In short:
I want a way to let the functions go off in synch. even if their being called asynch. by the user so that my array doesn't mess up.
Found the answer why my problem exists:
Since javascript is a synch. language (1 thread). the functions should've triggered at the right time. The problem is the callback from DevExpress Gridview for MVC Extensions. It makes a callback to the server, which responds in for example ~150ms with the selected field values. This will give an error if you quickly trigger the devexpress function twice. The second trigger has a window to return FASTER then the first trigger. Which would mean my coding of the table get ruined since I check if something has been added or removed. So when the first trigger (which returns after the second trigger) and my table gets updated. It shows the table prior to my last selection. Thus missing 1 row or has 1 more row then it should've.
So I got to make a function that retrieves all the events, and then place them in an order ~200 ms after each order. To make sure there is enough time for the callback to retrieve. Though this is ofcourse still not reliable, I think I will just change the requirements on this.
Your while loop condition is true, therefore the loop will just continue endlessly. You may want to try the following:
var int = setInterval(function () {
if(busy === false) {
clearInterval(int);
}
}, 50);
Try this instead of looping through the setTimeout over and over. If I had to guess, the break is breaking the if statement but not the while loop causing your browser to get stuck in an endless loop. With the above code, you can set an interval at which to run the code. In this instance, the code runs every 50ms. Once the condition inside the if statement is true, the setInterval is cleared causing the browser to continue executing its normal functionality.
Hope this helps.

What's the algorithm behind stack overflow's ajax tag search field

I want to make an ajax auto complete field like stack overflow's tag search box(used to add favorite tags and add tags to your question). I used to call ajax every time key's up,but I think it's not efficient.
I find stack overflow does it well. I guess it would only call ajax when key's up and some time has passed. I then wrote these lines to test:
$("#a").keyup(function(){
clearTimeout(c);
var c=setTimeout(alert("keyup and 0.5s have passed"),500);
})
it does alert after key up and after 0.5 seconds, but it alert several times as key up times. Does clearTimeout() suppose to stop setTimeout() to be executed? Why it doesn't work? What's the right way to do this?
c is a local variable and its value is lost as soon as function returns. Try something like this:
var timeoutId = null;
$("#a").keyup(function(){
clearTimeout(timeoutId);
timeoutId = setTimeout(alert("keyup after 0.5s"),500);
})

onChange for dropdown and timeouts

I have a dropdown menu which basically sends some data back to the server via onchange. The data is stored in the database and the primary table using seconds to avoid duplicates. What happens is if I scroll the dropdown via my keyboard, for example, using the up/down keys, my script returns an error because there is a duplicate entry now in the database.
here is part of the code for the dropdown in html
onchange="GetmySQLData();"
My question is can i just do a setTimeout and would it be correct to use it in this format:
onchange="setTimeout('GetmySQLData();', 1750);"
If you have a better approach, please feel free to let me know.
Thanks
The following versions are interchangeable:
setTimeout('myFunction()',1750);
setTimeout(myFunction,1750)
setTimeout(function() { /* some anonymous function */ },1750)
What you might want is
<script>
var tId = ""; // create a global var
</script>
and have
onchange="clearTimeout(tId); tId=setTimeout('GetmySQLData()',1750)"
which will only execute the onchange after the user does not change the dropdown for the duration of the timeout, but if the user changes within the timeout period, a new timeout is triggered
If you are planning to use the setTimeOut then it has to called in the following way:
onchange="setTimeout(GetmySQLData(), 1750);" providing single quotes aroung the arguments makes it to be treated as a string. and the timeout value is in milliseconds.

Categories

Resources