Domanda

The company I work for takes Credit Applications over the phone for clients. We already have most of their info before they call in to do the application, so I wrote some AJAX to pre-populate the form.

As the operator types their info into the form, onKeyUp, JavaScript checks against the server to see if it can narrow down the results to one match. Once there is a single match, Javascript shows a confirm box with the user's info. If the info is correct, operator hits OK and the fields are pre-populated with the data from the server.

My code works, but sometimes the server doesn't respond immediately and with the AJAX being called onKeyUp we often get multiple pop-up (confirm) boxes consecutively and have to hit OK over and over to get back to the form.

I have tried several things to prevent this. I have a drop-down which allows the Operator to choose between synchronous JavaScript and Async Js, (when set to sync, we only get one confirm, but the user is not able to type in the input fields until the server is done sending responses). I've tried some other things but none of them work 100%.

Here is the current version of what is implemented, heavily commented just for SO :) What suggestions can the SO community offer to prevent multiple confirm boxes from showing?

var showPopUp = true; // set to false once confirm is chosen to prevent additional pop ups
var stopPop = 0; // count the number of pop-ups prevented

function startAjax(){
    if(document.getElementById("flag").value == "yes" && showPopUp){ // preliminary check to avoid unnecessary calls
        if (window.XMLHttpRequest){ xmlhttpp=new XMLHttpRequest(); }else{ xmlhttpp=new ActiveXObject("Microsoft.XMLHTTP"); }

        //do stuff with server response..
        xmlhttpp.onreadystatechange=function(){
            if(xmlhttpp.readyState==4 && xmlhttpp.status==200){

                //get values from XML response..
                var status = xmlhttpp.responseXML.getElementsByTagName('status')[0].firstChild.nodeValue;
                var fname = xmlhttpp.responseXML.getElementsByTagName('fname')[0].firstChild.nodeValue;
                var addr = xmlhttpp.responseXML.getElementsByTagName('addr')[0].firstChild.nodeValue;
                var lname = xmlhttpp.responseXML.getElementsByTagName('lname')[0].firstChild.nodeValue;
                var city = xmlhttpp.responseXML.getElementsByTagName('city')[0].firstChild.nodeValue;
                var state = xmlhttpp.responseXML.getElementsByTagName('street')[0].firstChild.nodeValue;
                var zip = xmlhttpp.responseXML.getElementsByTagName('zip')[0].firstChild.nodeValue;
                var email = xmlhttpp.responseXML.getElementsByTagName('email')[0].firstChild.nodeValue;

                //show the status of the request in the status box
                document.getElementById("ajax_status").innerHTML=status;

                //if the status is "bingo" then the correct result was found, do stuff with it
                if(status == "Bingo"){

                    //make sure confirm box wasn't already shown before showing another one
                    if(showPopUp){

                        //ask user if the result returned is the correct one before populating the fields
                        var confirmMsg = "*User Found*\n\nName: "+fname+" "+lname+"\nAddress: "+addr+"\nCity: "+city+"\nState: "+state+"\nZip: "+zip+"\nEmail: "+email+"\n\nClick 'OK' To populate fields or click 'Cancel' if this is not the correct info.";
                        var fillOrNot = confirm(confirmMsg);

                        //after the user has confirmed the info from the server, set showPopUps to false to prevent additional confirm boxes, populate input values
                        if(fillOrNot){
                            showPopUp = false;
                            document.getElementById('first_name1').value = fname;
                            document.getElementById('last_name1').value = lname;
                            document.getElementById('flag').value="no";
                        }else{
                            showPopUp = false;
                            document.getElementById('flag').value="yes2";
                            document.getElementById("ajax_status").innerHTML="Aborted";
                        }
                    }else{

                        //If server returns a response after a user confirms a previous response, count the number of responses and show it in the AJAX status box
                        stopPop++;
                        document.getElementById("ajax_status").innerHTML = "Stopped "+stopPop+" pop ups";
                    }
                }                   
            }
        }

        //get parameters for request
        var param1 = document.getElementById('first_name1').value;
        var param2 = document.getElementById('last_name1').value;
        var param3 = document.getElementById('address').value;
        var url = "ajaxhandler.php?fname="+param1+"&lname="+param2+"&addr="+param3;

        //determine sync or async from drop down menu
        var e = document.getElementById("async");
        var strUser = e.options[e.selectedIndex].value;
        var asy = true;
        if(strUser == "false"){
            asy = false;
        }

        //Do request
        xmlhttpp.open("GET",url,asy);
        xmlhttpp.send(null);
    }
}

Thanks for looking

È stato utile?

Soluzione

Two things can help:

  • Don't start the AJAX operation immediately upon "keyup". Set a timer for a short time in the future (100 milliseconds or so), cancelling any previously-set timer on each "keyup".
  • Keep track of whether there's an AJAX operation "in flight", and ignore AJAX results that are stale.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top