VisualForce 页面中的 Javascript - 表单提交成功,触发顶点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7099495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 22:58:37  来源:igfitidea点击:

Javascript in VisualForce page - form submit success, trigger apex?

javascriptsalesforceapex-codevisualforce

提问by tsalb

Right now, the code below upon submit, first inserts a file THEN submits the form. This is problematic - I need for it to verify the form was successfully posted to Amazon S3 then insert the (token) file so it can link to it.

现在,下面的代码在提交时,首先插入一个文件然后提交表单。这是有问题的 - 我需要它来验证表单是否已成功发布到 Amazon S3,然后插入(令牌)文件以便它可以链接到它。

I basically need to reverse SubmitFile and InsertFile, but I'm not sure how to have (If form successfully sent, then run another javascript function). See very bottom for an attempt...Is this possible?

我基本上需要反转 SubmitFile 和 InsertFile,但我不确定如何使用(如果表单成功发送,则运行另一个 javascript 函数)。看到最底部的尝试......这可能吗?

   <apex:pageMessages id="pageErrors"></apex:pageMessages>
<form name="s3Form" action="https://s3.amazonaws.com/mybucket" method="post" enctype="multipart/form-data">   
    <input type="hidden" name="key"/> 
    <input type="hidden" name="AWSAccessKeyId" value="{!key}"/> 
    <input type="hidden" name="policy" value="{!policy}"/>
    <input type="hidden" name="signature" value="{!signedPolicy}"/> 
    <input type="hidden" name="acl" value="private"/> 
    <input type="hidden" name="x-amz-meta-FileId" value="{!File__c.id}"/>
    <input type="hidden" name="x-amz-meta-OrderId" value="{!OrderId}"/>
    <input type="hidden" name="x-amz-meta-CustomerId" value="{!CustomerId}"/>     
    <input type="hidden" name="success_action_redirect" value="{!serverUrl}{!OrderId}"/>           

    <apex:pageBlock title="New File Upload" mode="maindetail" tabStyle="File__c"> <!--  rendered="{!open}"-->
        <apex:pageBlockSection title="File Information" columns="2" collapsible="false" showHeader="false">                               
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Select File" for="selectFile"/>            
                <input id="selectedFile" type="file" size="25" name="file" onChange="setFileName(this.value)"/>                
            </apex:pageBlockSectionItem>                                         
        </apex:pageBlockSection>
        <apex:pageBlockButtons location="bottom">
            <input class="btn" type="button" value="Upload File" onClick="checkFile();return false;"/>                
            <input class="btn" type="button" value="Cancel" onClick="cancelFile();return false;"/>
            <input class="btn" type="button" value="Complete Order" onClick="completeFile();return false;"/>
        </apex:pageBlockButtons>          
    </apex:pageBlock>
    <apex:outputText styleClass="footer" value="Please click Complete Order when all the required files are uploaded. Thank you." />
</form> 

 <apex:form id="sfForm"><!--  rendered="{!open}"-->

    <apex:inputHidden id="hiddenServerURL"  value="{!serverURL}"/>
    <apex:inputHidden id="fileName" value="{!fileName}"/>
    <apex:inputHidden id="contentType" value="{!contentType}"/>
    <apex:inputHidden id="fileType" value="{!fileType}"/>
    <apex:actionFunction name="insertFile" action="{!insertFile}" oncomplete="submitFile();return false;"/>
    <apex:actionFunction name="completeOrder" action="{!completeOrder}"/>


    <script type="text/javascript">
    var sendFile = false;
    document.getElementById('{!$Component.hiddenServerURL}').value = '{!$Api.Enterprise_Server_URL_140}';       
    function setFileName(file) {
        var f = file.replace(/\/g, "");
        f = f.replace(/C\:fakepath/g, ""); <!--Required for IE8-->
        document.s3Form.key.value = "{!CustomerName}/{!OrderName}/" + f;
        document.getElementById('{!$Component.fileName}').value = f;
        suffix = f.lastIndexOf(".") + 1;
        contentType = f.slice(suffix);
        document.getElementById('{!$Component.contentType}').value = contentType;
    }
    function setFileType(type) {
        document.getElementById('{!$Component.fileType}').value = type;
    }
    function checkFile() {
        if (document.s3Form.file.value=="") {
            alert("Please, select a file.");
            return false;
        } 
        else if (document.s3Form.fType.value=="--None--") {
            alert("Please, select a file type.");
            return false;
        }
        else {     
            alert("Uploading...Please click OK and wait for page to refresh.");        
            insertFile();
            sendFile = true;
        }
    }
    function submitFile() {
        if(sendFile = false) {
        return false;
        }
        else {
        document.s3Form.submit();
        }
    } 
    function completeFile() {
        completeOrder();
    }   
    </script>

</apex:form>

In the controller (extension):

在控制器(扩展)中:

//SF File insert on an object (passed from page)
public PageReference insertFile() {
    this.file.Name = fileName;
    this.file.Type__c = fileType;
    this.file.Content__c = contentType;
    insert this.file;
    return null;
}

Here is the javascript section i tried to alter, but i can't find anything after extensive searches on if this works...

这是我尝试更改的 javascript 部分,但是经过广泛搜索后我找不到任何内容...

        function checkFile() {
        if (document.s3Form.file.value=="") {
            alert("Please, select a file.");
            return false;
        } 
        else if (document.s3Form.fType.value=="--None--") {
            alert("Please, select a file type.");
            return false;
        }
        else {     
            alert("Uploading...Please click OK and wait for page to refresh.");        
            document.s3Form.submit({
                success: function(){
                    alert("Testing!");
                    insertFile();
                },
            });
        }
    }

回答by Ralph Callaway

So if I'm understanding you correctly you want to:

因此,如果我正确理解您,您想:

  1. Validate file
  2. Upload file to amazon s3
  3. Save file token to salesforce
  1. 验证文件
  2. 上传文件到亚马逊s3
  3. 将文件令牌保存到 salesforce

Not to throw a wrench in your plans but you might try completing the whole routine in apex. Here's some pseudo code. Salesforce also has developed a toolkitfor working with Amazon S3 so you shouldn't have to develop everything from scratch.

不要在您的计划中投入扳手,但您可以尝试在顶点完成整个例程。这是一些伪代码。Salesforce 还开发了一个用于使用 Amazon S3的工具包,因此您不必从头开始开发所有内容。

Visualforce Page:

视觉力量页面:

<apex:page controller="MyController">
  <apex:form>
    <apex:inputFile value="{!file.body}" filename="{!file.name}"/>
    <apex:commandButton value="Submit" action="{!submitFile}"/>
  </apex:form>
</apex:page>

Apex Controller:

顶点控制器:

public class MyController {
  public Document file { get; set; } { file = new Document(); } // dummy object for storing binary file data

  public void submitFile() {
    if(!validateFile())
      return;
    String s3Token = submitToS3();
    if(s3Token != null) {
      File__c newFile = new File__c(name = file.name, s3_token__c = s3Token);
      insert newFile;
    }
  }
}

回答by Adam

+1 on doing the work in Apex as opposed to Javascript.

+1 在 Apex 中完成工作而不是 Javascript。

But to continue with a potentially successful hack, try using apex:actionPollerfor your form submit. When it wakes up it checks for success on your file insert. If after a few polls you still don't have success then flag a timeout.

但是要继续进行可能成功的黑客攻击,请尝试使用apex:actionPoller进行表单提交。当它醒来时,它会检查您的文件插入是否成功。如果经过几次民意调查仍然没有成功,则标记超时。

Javascript novelties in Visualforce can be perilous, unless time is not a factor for you. Best exhaust Visualforce/Apex options first and only then venture into custom JavaScript in special cases or for lightweight UI tweaks, imo.

Visualforce 中的 Javascript 新颖性可能是危险的,除非时间对您来说不是一个因素。最好先使用 Visualforce/Apex 选项,然后才在特殊情况下或轻量级 UI 调整中冒险使用自定义 JavaScript,imo。