AJAX and callback function - javascript

I will try to explain my problem. I have 4 files index.html, event.js, start.js and form.php.
index.html
<head><script type="javascript/text" src="start.js></script></head>
<html>
<button id="bt" type="button">Click</button>
<div id="test"></div>
</html>
start.js
window.onload=init;
function init(){
document.getElementById("bt").onclick=function(){
getFile('form.php?x='+Math.random()*11, getPHP);
getFile('javascripts/event.js?x='+Math.random()*11,getJS);
}
}
function getFile(source,callFunc){
var xmlHttpR=false;
if (window.XMLHttpRequest)
xmlHttpR=new XMLHttpRequest();
else if (window.ActiveXObject)
xmlHttpR=new ActiveXObject("Microsoft.XMLHttp");
else
alert("Error");
if (xmlHttpR){
xmlHttpR.open("GET",source,true);
xmlHttpR.onreadystatechange=function(){
if (xmlHttpR.readyState==4 && xmlHttpR.status==200){
callFunc(xmlHttpR);
delete xmlHttpR;
xmlHttpR=null;
}
}
}
xmlHttpR.send(null);
}
function getPHP(response){
document.getElementById("test").innerHTML=response.responseText;
}
function getJS(response){
eval(response.responseText);
}
event.js
document.getElementById("firstName").onblur=function(){
validate(this.name,this.value);
}
form.php
<html>
<form>
<input type="text" id="firstName" value="">
</form>
</html>
OK, the problem now, when onblur event is triggered on firstName nothing happens but when I refresh the page sometimes once or twice, the event is working as it should be. Maybe I'm getting the response not at the right time?
Is there something wrong with the callback function and the eval and I use to assign onblur event to the firstName field?
is the problem with the AJAX asynchronous call? Should I use synchronous? What am I missing?
I hope I could explain clearly what the problem is.
Thanks in advance for any help.

yeah, it sounds like a race condition between the asynchronous calls. sometimes the JS returns first and sometimes the PHP returns first.
you could try loading the JS as part of the callback for the PHP ajax call.
something like this should work:
EDIT:
pass response through anonymous function and down to getPHP
getFile('form.php?x='+Math.random()*11, function(response) {
getPHP(response);
getFile('javascripts/event.js?x='+Math.random()*11,getJS);
});

Looks to me like your asynchronous calls are the problem.
You're making two getFile() calls. Since getFile() makes an asynchronous request, the browser will continue through the JavaScript code without waiting for a response (There's a way to force the browser to wait for the response, but I can't think of it right now). So, sometimes when you load the page, #firstName doesn't actually exist until AFTER event.js attempts to make the event binding.
I would suggest that you don't recreate the textbox every time someone clicks the button. Instead, it would be "static" on the page, and your JavaScript would simply check the value and make stylistic changes to show the user that their input does or does not validate.

Related

PHP not working in chrome properly

My PHP code is working fine in Firefox Mozilla but not in google chrome. My code is given below.
PHP:
$fee=0;
if($_POST['amount'])
{
$fee=$_POST['amount'];
}
else if($_POST['payprice'])
{
$fee=$_POST['payprice'];
}
else if($_POST['regfee'])
{
$fee=$_POST['regfee'];
}
else
{
$fee=0;
}
JavaScript Code
function submitpay()
{
document.forms[0].submit();
}
setInterval("submitpay()", 100));
HTML:
<form method="post" action="../customerpg/pg1/check.php">
<input type="hidden" name="showupdt" value="block" />
<input type="hidden" name="amount" value="<?php echo $fee; ?>" />
</form>
Use
setInterval(submitpay, 100);
instead of
setInterval("submitpay()", 100)
Firstly I don't think you can send the function call as a string. Secondly don't put () at the end of the function - that will execute the function immediately, and it will be the result of the function which is passed into setInterval (and unless that result is itself a reference to a function, it won't work). What you should pass is a reference to the function, by using its name.
And in future, check your browser console (press F12 for the developer tools) for errors before you do anything else. This will give you a big clue as to what is happening in cases like these. Usually you can even click on the line number of the code which is failing and see exactly where the problem is.
Lastly, a technical point regarding your question wording. It's not the PHP which isn't working, since PHP runs on the server, it's the JavaScript (which may, or may not, have been generated by some PHP that you wrote, but that's irrelevant in this case) which is the problem.
This is actually possible.
One case which I had encountered, and might as well fix your problem.
Case: The code is run on subdomain in localhost, like http://subdomain.localhost/project/ and some proxy plugin (Browsec, Ultrasurf) is running.
In this case, the code won't run. You can stop the plugin, in order for it to work.

Javascript synchronous loop in browser

Trying to automate a task in the browser with Greasemonkey.
Requirement: load a web page which contains a table displaying 15 out of 340+ results, with button controls to see the next page worth of results, go back, go to the end and so forth.
Collect the first 15 results --> got this working
Click on the 'Next' button --> got this working
Wait until the page loads the next set of results --> dont know how
Repeat until the next button is disabled --> got this working
Cant show pictures cuz its a corporate app.
So far if I loop with setTimeouts, the timeouts get queued up and executed at the same time I think. Instead, the requirement is for the code to run the info collection, click next, wait, then collect info again.
You could try a utility function waitForKeyElement, a greasemonkey utility script. It is essentially doing what you were trying to do before. It sets a timeout to continuously checks to see if an element is loaded. Executing it would look something like this:
waitForKeyElements (
"div.comments",
commentCallbackFunction
);
Where comment callback function would be the function that collects results.
It would help also to understand why setTimeout in a loop doesn't work. setTimeout does not block execution of a script to run your callback function. It queues up that function to be executed no earlier than the time that you pass in as a second parameter. Because of this, the loop runs very quickly and instead of getting function calls at 3000ms, 6000ms, and 9000ms... as you might expect you get something closer to function calls at 3000ms, 3001ms, 3002ms.
You can execute arbitrary JS logic mixed with API calls, recursion and timeouts sequentially via synchronous executor nsynjs:
function synchronousCode() {
var i=0;
while(true) {
console.log("waiting 1 sec, iteration", i++);
$('#myDiv').toggle();
nsynWait(nsynjsCtx,1000);
};
}
var ctx;
function btnStopClicked() {
ctx.stop();
ctx=null;
}
function btnStartClicked() {
ctx=nsynjs.run(synchronousCode,{},function(){
console.log("Synchronous Code done");
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>
<script src="https://rawgit.com/amaksr/nsynjs/master/wrappers/nsynWait.js"></script>
<body>
<button id="buttonStart" onclick="btnStartClicked()">Start</button>
<button id="buttonStop" onclick="btnStopClicked()">Stop</button>
<div id="myDiv">Flashing div</div>
</body>
See more examples here: https://github.com/amaksr/nsynjs/tree/master/examples
Thanks people, found this post to be the best answer
Synchronous setTimeout + Loop
This way the page loads, the first values are read, the next button is clicked, next results appear and are read, until the last page.
Thanks again for the input and ideas
you can use it
for(const elment of arrayElements) {
await yourFunc(elment)
await yourOtherFunc('somePatameter')
}

Onclick function doesn't work for calling javascript

I have try this on jsfiddle,
here's the html :
<input onclick="masuk(10);" type="radio" name="myRadio1" value="Yes"/>1<br/>
<input onclick="alert(10);" type="radio" name="myRadio1" value="Yes"/>2<br/>
here's the js :
function masuk(a) {
alert(a);
}
here's the link : http://jsfiddle.net/codingsolver/MsYqx/
the point is, why if click the first radio button which call function masuk() it doesn't want to show the alert. But if I directly call the alert, it works. Does any one know why?? Thanks lots
It should work. Make sure you are loading javascript after the DOM has been loaded. Place javascript above </body>
Your jsFiddle is gone, but in order to call from HTML like that, your variable would have to be globally defined, which it probably isn't (but can't say for sure without the full source).

jQuery ready firing before custom behavior script initializes

Background
I've inherited an ancient web application that has input controls with custom behaviors defined with an old-fashioned HTC (HTML Component) script, e.g.:
<input name="txtFiscalYearEndDay" type="text" value="30"
maxlength="2" size="5" id="txtFiscalYearEndDay" class="Text1"
style="behavior:url(/path/js/InFocus.htc);" />
Here are the relevant parts of this HTC file to illustrate the issue:
<PUBLIC:COMPONENT tagName="InFocus">
<PUBLIC:METHOD NAME="setValid" />
<PUBLIC:ATTACH EVENT="ondocumentready" HANDLER="initialize" />
<SCRIPT LANGUAGE="javascript">
function initialize() {
// attaches events and adds CSS classes, nothing fancy
}
function setValid(bInternal) {
// checks some flags and changes a label
}
</SCRIPT>
</PUBLIC:COMPONENT>
So, nothing out of the ordinary so far. Additionally, I have some JS that runs on DOM-ready:
$(function() {
txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
});
And the validation function:
function txtFiscalYearEndDay_Validate(el) {
...
}
Note: I'm not using $('#txtFiscalYearEndDay') because then I really can't try to call setValid(true); on the element, nor do I want to have to do $('#txtFiscalYearEndDay')[0].setValid(true);.
The problem
At one point in the validation function, I'm attempting to call a method on the element, the one added by the HTC script:
el.setValid(true);
However, the IE debugger gets sad and complains that setValid() is not a function. Inspecting it in the debugger confirms this:
typeof el.setValid // "unknown"
Of course, once the page has completed rendering (or whatever period of time is needed for the document to actually be ready has passed), the validation function works as expected (because I'm calling the same validation function on change and blur events as well). That is, when the function is called outside of jQuery's on-DOM-ready function, it works just fine.
Do any of you have any ideas at to what might be happening here? Is jQuery's "ondomready" being registered before the HTC script's "ondomready"? Can I somehow change that order?
I'm currently seeing this behavior in all versions of IE.
EDIT: WORKAROUND
I discovered a workaround. If you take the function call out of the jQuery ready function and throw it at the end of the page, it works (i.e.:)
...
<script type="text/javascript">
txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
</script>
</body>
</html>
I do not know if HTC counts toward page ready but i suspect they do not.
What you might try is check something that only is tru after the HTC hase finished.
You own script should then start something like this:
function MyFunction() {
if(!HTCIsreadyTest()) {
setTimeout(MyFunction, 100);
return;
}
//the rest of your code
}
This basically makes you function check and restart in 100 milliseconds if conditions are not met untill the test succeds.
You could also ad a counter argument increasing it by one for each attempt to have some timeout code trigger if HTC sciprts has not loaded after 2 seconds
The easiest workaround I could find was to move the validation function call out of the jQuery ready() callback and move it to the end of the page:
...
<script type="text/javascript">
txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
</script>
</body>
</html>
However, I found a more elegant solution. Because I seemingly need to wait for all page resources to be loaded, I simply needed to move the function call out of the jQuery ready() callback and instead put it in a window load() callback:
$(window).load(function() { // instead of $(function() {
txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
});
I'm using the latter so I can keep all of the JS code together.

function onclick not working .. ... not showing alert box

html code
<input type="button" value="+" onclick="alert()" />
In chrome after inspecting it showing this error Uncaught RangeError: Maximum call stack size exceeded.
javascript
<script type="text/javascript">
function alert() {
alert("Hello! I am an alert box!!");
}
</script>
help me by telling how to solve this
You override the existing function definition with new definition, which in addition is calling itself, causing too much recursion.
As other users mentioned you just need to create your function with a different name than alert() which is an already defined function in javascript, you shouldn't be using that.
I would rather use the standard addEventListener, will make your code cleaner as well as your html
You can do something like this, also you can try it right from this page:
function myDefinedAlert() {
alert("Hello! I am an alert box!!");
}
var el = document.getElementById("yourButton");
el.addEventListener("click", myDefinedAlert, false);
<input id="yourButton" type="button" value="+" />
Press the button, try it, and copy it to your code, let me know if it works :)
that's because you call alert() in alert(), so it turns out in recursion.
The alert() is a built-in function, which is not meant to be redefined. Although you redefine, you are calling the same function inside the new function, which is wrong. So, in simple terms, give a different name like myAlert() or something:
function myAlert() {
alert("Hello! I am an alert box!!");
}
So recursively the alert() function gets called and it overflows the stack.
Solution Snippet
function myAlert() {
alert("Hello! I am an alert box!!");
}
<input type="button" value="+" onclick="myAlert()" />
You can not have a recursive function such as what you have done here in Javascript as it would continue to loop out of control and consume more memory in the browser. When you call a function from within a function you need to make sure that you are not calling the same function.

Categories

Resources