0

This is related to a question I posted a couple of days ago. The answer there led me to find this problem.

I have the following code in a Submit button

if (validateFields(document.forms[0])==true){
    if (validateAdditionalFields(document.forms[0])==true){         
        document.getElementById("Status").value = "Submitted for RFP";      
        getRespParty('ResponsibleParty');                   
        document.forms[0].submit();
    }
}

I have the following code in the getRespParty function in the JSHeader

function getRespParty(x) {
var noEmployees = document.getElementById('NoEmployees').value;
var stateName = document.getElementById('State').value  
var url = 'http://' + window.location.host + 
'/ebsprospects.nsf/(GetResponsiblePerson)?OpenAgent&NoEmployees=' + 
 noEmployees + '&State=' + stateName;     
var xhttp = new XMLHttpRequest();
xhttp.open("GET", url);
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {    
        document.getElementById(x).value = xhttp.responseText;  
    }
};
xhttp.send();
}

The (GetResponsiblePerson) agent ends with this code (I am doing a series of dbLookups to return a specific person which is why it has to be in LS)

Dim nam As NotesName
Set nam = session.Createname(respParty)
Print "Content-type:text/plain"    
Print nam.Abbreviated

The field ResponsibleParty field is text, visible, editable, and the ID field on the HTML tab is ResponsibleParty. When the code returns, the field shows the name I am expecting to see. However, it does not appear to really be saving it because the client side document does not contain anything in the matching ResponsibleParty field. There is no code in the WQS. The ResponsibleParty field in the client is hidden and editable as is the Status field which does get saved so at least I know that the save is working?

Why will the field value that is returned from the agent not save? Is type of logic even doable or do I need to do it a different way?

Richard Schwartz
  • 14,463
  • 2
  • 23
  • 41
RoyRumaner
  • 769
  • 1
  • 9
  • 29
  • 1
    Hi , this could be a timing issue. Your xmlhttp is probably asynchronous. The field gets updated, after the page has been submitted. One solution could be to submit the form in the readystatechange function... – umeli Oct 18 '18 at 11:37
  • Unbelievable! That is the answer. Thank you so much for that. – RoyRumaner Oct 18 '18 at 13:39

1 Answers1

0

As @umeli said, it is a timing issue. You are calling getRespParty(), but as soon as the XMLHttpRequest is called, the code continues, exits the function and performs the submit before the Ajax call is finished.

One solution, which IMHO is more elegant, would be to use a callback from getRespParty(), and call submit there:

document.getElementById("Status").value = "Submitted for RFP";      
getRespParty('ResponsibleParty', function() { document.forms[0].submit() }); 

Then you modify getRespParty():

function getRespParty(x, callback) {
    var noEmployees = document.getElementById('NoEmployees').value;
    var stateName = document.getElementById('State').value  
    var url = 'http://' + window.location.host + 
    '/ebsprospects.nsf/(GetResponsiblePerson)?OpenAgent&NoEmployees=' + 
    noEmployees + '&State=' + stateName;     
    var xhttp = new XMLHttpRequest();
    xhttp.open("GET", url);
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {    
            document.getElementById(x).value = xhttp.responseText; 
            if (callback != null && typeof callback === "function") {
                callback();
            }
        }
    };
    xhttp.send();
}

To improve even more, you could call the callback function with different arguments, depending on if the XMLHttpRequest is successful or not:

if (this.readyState == 4) {
    if(this.status == 200) {    
        document.getElementById(x).value = xhttp.responseText; 
        if (callback != null && typeof callback === "function") {
            callback(true);
        }
    } else {
        if (callback != null && typeof callback === "function") {
            callback(true, this.status);
        }
    }
}

Now you can read that value and perform different actions in your main callback function:

document.getElementById("Status").value = "Submitted for RFP";      
getRespParty('ResponsibleParty', function(success, statusCode) { 
    if (success) {
        document.forms[0].submit();
    } else {
        alert("Ajax call failed with status "+statusCode);
    }
});

Any time you perform asynchronous calls, you should use callbacks if you plan to perform actions afterwards in a calling function.

Karl-Henry Martinsson
  • 2,770
  • 15
  • 25