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

发布于 2024-11-29 21:27:50 字数 5362 浏览 4 评论 0原文

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

我基本上需要反转 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>

在控制器(扩展)中:

//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;
}

这是我尝试更改的 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();
                },
            });
        }
    }

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.

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?

   <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...

        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();
                },
            });
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泼猴你往哪里跑 2024-12-06 21:27:50

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

  1. 验证文件
  2. 将文件上传到 amazon s3
  3. 将文件令牌保存到 salesforce

不要破坏您的计划,但您可以尝试在 apex 中完成整个例程。这是一些伪代码。 Salesforce 还开发了一个用于使用 Amazon S3 的工具包,因此您不必开发一切从头开始。

Visualforce 页面:

<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 控制器:

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;
    }
  }
}

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

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 toolkit for working with Amazon S3 so you shouldn't have to develop everything from scratch.

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;
    }
  }
}
就此别过 2024-12-06 21:27:50

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

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

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

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

But to continue with a potentially successful hack, try using apex:actionPoller for 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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文