VBscript síncrono alterado para Javascript assíncrono incorretamente [duplicado]

Oct 09 2020

Então, meu chefe me pediu para examinar um problema em que eles estão portando scripts VBscript antigos para scripts Javascript, mas o Javascript tem fluxo de programa incorreto. O único problema é que sou realmente ignorante sobre os dois, mas se seu chefe perguntar, então você tem que fazer um plano. ;-)

No VBscript, o usuário tinha uma escolha e, se "Não", a próxima tela / visualização não era mostrada. No entanto, com o Javascript, a próxima tela / visualização é carregada independentemente de o usuário escolher "Não / Cancelar" ou não. Isso não deveria acontecer.

Aqui está o VBscript, a parte importante está entre //:

vEffectiveDate  = ScreenForm("smoke.Effective Date").Value
vLastRunDate    = ScreenForm("smoke.Last Run Date").Value
sStatus         = ScreenForm("smoke.Calc Status").Value

vMsg = ""

If Len(sStatus) = 0 Then
    sStatus = "SUCCESFUL"
    ScreenForm("smoke.Calc Status").Value = sStatus
End If

If Len(vEffectiveDate) > 0 Then

    If Not IsDate(vEffectiveDate) Then 
        vMsg = vMsg & "[Effective Date] Is not a date." & Chr(13)
    
    ElseIf cdate(vEffectiveDate) <= cdate(vLastRunDate) Then
        vMsg = vMsg & "[Effective Date] cannot be on/before " & vLastRunDate &"." & Chr(13)
    End IF

End If

//////////////////////////////////////////////////////////////////////////////
If UCASE(sStatus) <> "SUCCESFUL" Then
    sResponse = MsgBox ("Forecast calculation still busy. Results might not be accurate. Continue?", (vbYesNo), "WARNING")
    If sResponse = vbNo Then
        MsgBox cstr("Screen will refresh. Please click on Update to try again."), (vbOKOnly), "INFORMATION"
        ScreenForm("smoke.Calc Status").Value = "REFRESH"
        'msErr = "ABORT"
    End If
End If
//////////////////////////////////////////////////////////////////////////////

If vMsg <> "" Then
MsgBox (vMsg)
msErr = "ERROR"
End If

Aqui está o Javascript, a parte importante está entre //:

 var vEffectiveDate="";
var vLastRunDate="";
var sStatus="";
var vMsg="";
var sResponse="";
vEffectiveDate = document.getElementById("Smoke.Effective Date").value;
vLastRunDate = document.getElementById("Smoke.Last Run Date").value;
sStatus  = document.getElementById("Smoke.Calc Status").value;
vMsg = "";
if ((sStatus).length == 0  ){
    sStatus = "SUCCESFUL";
    document.getElementById("Smoke.Calc Status").value= sStatus;
}
if ((vEffectiveDate).length > 0  ){
    if (!isDate(vEffectiveDate)  ){
        vMsg = vMsg+"[Effective Date] Is not a date." + ";\r\n";
    } else if (  moment( toDate(vEffectiveDate)).isBefore(toDate(vLastRunDate)) ){
        vMsg = vMsg+"[Effective Date] cannot be on/before "+vLastRunDate+"." + ";\r\n";
    }
}
///////////////////////////////////////////////////////////
if ((sStatus).toUpperCase() != "SUCCESFUL"  ){
 $.confirm({title: "Confirmation",columnClass: 'col-md-6 col-md-offset-3', content:"Forecast calculation still busy. Results might not be accurate. Continue?", buttons: {confirm: function() { sResponse= 1;}, cancel: function() {sResponse= 2;return;}}}); if (sResponse == 2 ){ $.alert({title:  "INFORMATION",columnClass: 'col-md-6 col-md-offset-3', content:("Screen will refresh. Please click on Update to try again.").toString(),});
        document.getElementById("Smoke.Calc Status").value= "REFRESH";
  msErr = "ABORT";
    }   
}
//////////////////////////////////////////////////////////


if (vMsg != ""  ){
$.alert({title: 'Validation Message',columnClass: 'col-md-6 col-md-offset-3', content:(vMsg),});
msErr = "ERROR";
}

Então, eu vi que existe um conceito de promessas de espera assíncrona em Javascript, mas parece que ele não é compatível com o Internet Explorer , e precisamos ter em mente que alguns de nossos usuários ainda usam o IE ... suspiro ... Parece que não vou conseguir usar um conceito de espera assíncrona, não que eu tenha certeza de que seria necessário nessa situação.

Então, também li aqui sobre o botão de envio de um formulário e que esse também pode ser o meu problema?

Eu sou tão ignorante sobre Javascript que nem sei como mudar o comportamento padrão do botão se esse for o problema.

Eu gostaria que alguém me ajudasse na direção certa para que eu pudesse aprender e crescer.

Respostas

1 trincot Oct 09 2020 at 19:58

Na verdade, a segunda parte do código (com o alerta) é executada independentemente do resultado do prompt de confirmação.

A principal diferença com $.confirme VBA MsgBox, é que MsgBoxestá bloqueando a execução posterior do código, enquanto $.confirmnão faz isso. Isso significa que o código que o segue (a if (sResponse == 2)parte) é executado imediatamente. Naquela época, nenhuma alteração foi feita em sResponse(já que nenhum botão foi clicado), então isso vem muito cedo.

No entanto, $.confirmaceita algumas funções como argumentos, que serão chamados quando um botão for pressionado no pop-up. Na verdade, seu código já passa por tais funções, mas eles não fazem nada além de configurar sResult. Portanto, você deve mover a segunda parte do código (com o alerta) em tal função.

Primeiro, vamos formatar seu código um pouco para que fique mais legível e você possa identificar melhor essas funções de retorno de chamada:

if ((sStatus).toUpperCase() != "SUCCESFUL") {
    $.confirm({
        title:  "Confirmation",
        columnClass: 'col-md-6 col-md-offset-3', 
        content:"Forecast calculation still busy. Results might not be accurate. Continue?",
        buttons: {
            confirm: function() {
                // This executes when button is clicked
                sResponse= 1;
            },
            cancel: function() {
                // This executes when button is clicked
                sResponse= 2;
                return;
            }
        }
    });
    // This executes immediately (without waiting for button click)
    if (sResponse == 2  ){
        $.alert({ title: "INFORMATION", columnClass: 'col-md-6 col-md-offset-3', content:("Screen will refresh. Please click on Update to try again.").toString(), }); document.getElementById("Smoke.Calc Status").value= "REFRESH"; msErr = "ABORT"; } } // Also this executes too early when confirm was executed: if (vMsg != ""){ $.alert({
        title: 'Validation Message',
        columnClass: 'col-md-6 col-md-offset-3',    
        content:(vMsg),
    });
    msErr = "ERROR";
}

Eu adicionei comentários para mostrar onde estão as partes importantes do código.

Agora mova a segunda parte dentro da função de retorno de chamada que se relaciona à resposta nº 2:

if (sStatus.toUpperCase() != "SUCCESFUL") {
    $.confirm({ title: "Confirmation", columnClass: 'col-md-6 col-md-offset-3', content:"Forecast calculation still busy. Results might not be accurate. Continue?", buttons: { confirm: function() { sResponse= 1; processMessage(); // <--- added this }, cancel: function() { sResponse= 2; // Moved code here, as it needs to execute when Cancel is clicked $.alert({
                    title: "INFORMATION",
                    columnClass: 'col-md-6 col-md-offset-3',
                    content: "Screen will refresh. Please click on Update to try again.",
                    // Code that should execute when alert is closed:
                    onAction: function () {
                        document.getElementById("Smoke.Calc Status").value= "REFRESH";
                        msErr = "ABORT";
                        processMessage(); // <--- added this
                    }
                });
            },
        }
    });
} else { // <-- added
    processMessage();
}

function processMessage() {
    // Moved code in a function, as it should only execute after confirm/alert is closed 
    if (vMsg != "") {
        $.alert({
            title: 'Validation Message',
            columnClass: 'col-md-6 col-md-offset-3',    
            content: vMsg,
        });
        msErr = "ERROR";
    }
}

Não testei esse código, pois ele tem dependências que não conheço.