具有渲染属性的文件上传问题XPages

时间:2018-11-02 12:11:36

标签: javascript file-upload xpages

我有一个脚本可以将文件上传到页面。另外,我有一个自定义控件对此负责。在此CC中,有以下代码:

<div style="height:0px;overflow:hidden">
            <input type="file"
                id="${javascript:compositeData.ID+'_files_input'}"
                onchange="#{javascript:
      var currentCustomID = compositeData.ID; 

      var filesInput = '\'' + currentCustomID + '_files_input' + '\'';
      var filesUpload = '\'' + currentCustomID + '_files_upload' + '\'';
      var filesButton = '\'' +  currentCustomID + '_files_button' + '\'';
      var filesProgress = '\'' +  currentCustomID + '_files_progress' + '\'';

      return 'files_onchange(' + filesInput + ',' + filesUpload + ',' + filesButton + ',' + filesProgress + ')';
      }"
                multiple="true" uploadOnSelect="true" name="uploadedfile" />

            <xp:fileUpload
                id="${javascript:compositeData.ID+'_files_upload'}"
                useUploadname="true">
                <xp:this.value><![CDATA[#{doc_source[compositeData.FieldName]}]]></xp:this.value>
            </xp:fileUpload>

            <xp:button value="Refresh"
                id="${javascript:compositeData.ID+'_files_button'}">
                <xp:eventHandler event="onclick" submit="true"
                    refreshMode="partial" refreshId="${javascript:compositeData.ID+'refresh'}" disableValidators="true"
                    >
                    <xp:this.action>

                        <xp:actionGroup>


                            <xp:saveDocument></xp:saveDocument>
                            <xp:executeScript>
                                <xp:this.script><![CDATA[#{javascript:
if (compositeData.postUpload!=null)
{
compositeData.postUpload.getScript().invoke(facesContext, null)
}}]]></xp:this.script>
                            </xp:executeScript>
                        </xp:actionGroup>
                    </xp:this.action>

                </xp:eventHandler>
            </xp:button>
        </div>

代码非常简单。在输入块中,有一个onchange属性,该属性调用称为files_onchange(filesInputP, filesUploadP, filesButtonP, filesProgressP)的客户端函数(该函数的参数只是应该更新的DOM元素。它使该函数具有多功能性,可以多次使用)。

该函数本身如下:

function files_onchange(filesInput, filesUpload, filesButton, filesProgress) 
{
    var urfiles = document.getElementById(filesInput).files;
    files_upload(filesInput, filesUpload, urfiles, 0, filesButton, filesProgress);
}           

function files_upload(filesInput, uploadID, files, counter, refreshID, filesProgress)
{
    var url = window.location.href;

    var formData = new FormData();
    var file = null;
    var form = XSP.findForm(filesInput);
    //console.log(form);
    if (!files) return;
    var numberOfFiles = files.length;
    file = files[counter];
    var max = files.length;
    if (counter >= max) return;


    formData.append(document.querySelector('[id$=' + uploadID + ']').id, file);
    formData.append("$$viewid", dojo.query("input[name='$$viewid']")[0].value);
    formData.append("$$xspsubmitid", dojo.query("input[name='$$xspsubmitid']")[0].value);
    formData.append("$$xspsubmitvalue", dojo.query("input[name='$$xspsubmitvalue']")[0].value);
    formData.append("$$xspsubmitscroll", dojo.query("input[name='$$xspsubmitscroll']")[0].value);
    formData.append(form.id, form.id);

    console.log(form.id);

    var xhr = new XMLHttpRequest();

    /* event listners */

      xhr.upload.addEventListener("progress", function(e) 
      {
          if (e.lengthComputable)

           {
                var percentComplete = Math.round(e.loaded * 100 / e.total);
                document.getElementById(filesProgress).innerHTML = percentComplete.toString()+'%, ( '+(counter+1).toString()+' / '+numberOfFiles.toString()+' )';
           }
              else 
              {
                document.getElementById(filesProgress).innerHTML = '...';
              } 
      }, false);


      xhr.addEventListener("load", function()
      {
          counter++; 
          if (counter >= max)
          {
              document.getElementById(filesInput).value = "";

              if (refreshID) 

              {
                  console.log(refreshID);
                  console.log(document.querySelector('[id$=' + refreshID + ']')); 
                  document.querySelector('[id$=' + refreshID + ']').click(); // Here's the problem
              }

          } 
        else 
              { 
                files_upload(filesInput, uploadID, files, counter, refreshID, filesProgress) 
              }

      }, false);


     xhr.addEventListener("error", function(e) 
     {
         document.getElementById(filesProgress).innerHTML = "Error: "+e;

     }, false);

     xhr.addEventListener("abort", function()
     {
         document.getElementById(filesProgress).innerHTML = "Upload cancelled.";

     }, false);

      xhr.open("POST", url, true);
      xhr.send(formData);

     // document.querySelector('[id$=' + refreshID + ']').click();

      document.querySelector('[id$=' + uploadID + ']').value = '';

}

它工作得很好,但是如果将fileComponent放在 rendered 块中,则会非常棘手。确实会将文件上传到文档。但是,如果我尝试单击刚刚上传的文件,则服务器会显示404错误。

问题是document.querySelector('[id$=' + refreshID + ']').click();侦听器中的代码load无法在具有动态渲染属性的块中执行。单击后,将执行id="${javascript:compositeData.ID+'_files_button'}"中的操作,因此,我必须手动执行相同的单击。 基本上,refreshID元素只是一个用于保存文档的按钮。 尽管页面上存在带有'_files_button'的元素,但是除非我手动调用该函数,否则它不会起作用。完成后,一切正常。有什么问题?预先感谢

0 个答案:

没有答案