這可能看起來像重複,但請首先閱讀並讓我知道你是否有問題。我有一個包含兩個數據源的xpage,其中一個表單用於信息,另一個用於圖像附件。現在,與典型的應用程序不同,我不想將圖像附加到現有的主數據源(第一個),我想異步上傳圖像併爲每個圖像創建單獨的文檔,並將主數據源的UNID作爲新圖像文檔的子標識。這是當前數據結構的唯一方式,我幾乎沒有任何改變這一點的發言權,所以這裏提出了挑戰。XPage ajax文檔創建
我已經成功地創建了xhr請求(帶有Julian和Sven以前的各種異步上傳工具的指導),並使用我編寫的自定義控件創建了帶有圖像的新文檔,但是一旦我將其嵌入到XPage中兩個數據源並嘗試上載並創建一個新文檔,它會創建主數據源的副本,並清除所有其他字段值(具有空字段的副本的預期行爲)。我懷疑這是因爲我使用$$ submitid和所有需要的表單值來處理我的上傳請求,並且它們以某種方式與第一個數據源綁定或共享,但我不能太確定。
我的自定義控件有它自己的數據源,xpage有一個包含數據源的面板作爲它的一部分。自定義控制下面。
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.data>
<xp:dominoDocument var="imgAttach" formName="mImageAttach"
concurrencyMode="force">
</xp:dominoDocument>
</xp:this.data>
<xp:inputText id="inputText2" style="width:657.0px"><xp:this.defaultValue><![CDATA[#{javascript:facesContext.getExternalContext().getRequest().getRequestURI();
context.getUrl()}]]></xp:this.defaultValue></xp:inputText>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:inputText id="parentId" value="#{imgAttach.ParUNID}"
style="width:333.0px">
<xp:this.defaultValue><![CDATA[#{javascript:var url = context.getUrl().toString();
/*
if(url.indexOf("createComponent.xsp") > 0 && context.getUrlParameter("documentId") != ""){
var doc:NotesDocument = newComponent.getDocument();
return doc.getUniversalID();
} else {
return "";
}
*/}]]></xp:this.defaultValue>
<xp:this.rendered><![CDATA[#{javascript:var url = context.getUrl().toString();
if(url.indexOf("createComponent.xsp") > 0){
return true;
} else {
return false;
}}]]></xp:this.rendered>
</xp:inputText>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:inputText id="inputText1"
defaultValue="#{javascript:imgAttach.getDocument().getUniversalID()}"
style="width:333.0px; display:none;">
</xp:inputText>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:inputText id="Created" style="width:297.0px; display:none;"
value="#{imgAttach.Created}"
defaultValue="#{javascript:@Created()}">
<xp:this.converter>
<xp:convertDateTime type="date" dateStyle="short"></xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
<xp:br></xp:br>
<xp:div styleClass="file-input">
<div class="file-preview ">
<div class="close fileinput-remove">×</div>
<div class="">
<div class="file-preview-thumbnails" id="file-thumbs">
</div>
<div class="clearfix"></div>
<div
class="file-preview-status text-center text-success">
</div>
<div class="fileinput-error file-error-message"
style="display: none;">
</div>
</div>
</div>
<div class="input-group-btn">
<button type="button" tabindex="500"
title="Clear selected files"
class="btn btn-default fileinput-remove fileinput-remove-button">
<i class="glyphicon glyphicon-trash"></i>
Remove
</button>
<button tabindex="500" id="upload-files"
title="Upload selected files"
class="btn btn-default fileinput-upload fileinput-upload-button">
<i class="glyphicon glyphicon-upload"></i>
Upload
</button>
<div tabindex="500" class="btn btn-primary btn-file"
id="files-container">
<i class="glyphicon glyphicon-folder-open"></i>
 Browse …
<input name="add-files[0]" id="add-files" type="file"
multiple="true" class="file-input">
</input>
<xp:fileUpload id="FileUploadCtrl"
value="#{imgAttach.Body}" useUploadname="true"
style="display:none">
</xp:fileUpload>
<xp:eventHandler event="onsaveDoc" submit="false"
refreshMode="norefresh" immediate="false" save="true" id="saveDoc" />
</div>
</div>
</xp:div>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:scriptBlock id="scriptBlock2" type="text/javascript">
<xp:this.value>
<![CDATA[
$(function() {
$("#files-container").delegate('input', "change", function() {
var files = !!this.files ? this.files : [];
if (!files.length || !window.FileReader){
//console.log("No file selected or no file reader suppport");
return; // no file selected, or no FileReader support
}
for(i=0; i<files.length; i++) {
if (/^image/.test(files[i].type)){ // only image file
var reader = new FileReader(); // instance of the FileReader
reader.readAsDataURL(files[i]); // read the local file
var img = document.createElement("img");
img.file = files[i];
img.name = 'no_'+ i;
img.classList.add("file-preview-image");
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
$("#file-thumbs").append(img);
}
}
/*
//add new upload button
var currentInput = $('#add-files');
var nextInput = $('#files-container');
var inputsCount = $('.file-input').length;
// now we change the 'id' attribute of said element because id's should be unique
currentInput.attr('id','add-files'+inputsCount);
// and finally we hide the old element
currentInput.hide();
// now, we append a new input element with an incremented array key defined by the length of already existing input elements
nextInput.append('<input type="file" name="add-files['+inputsCount+']" id="add-files" multiple="true" class="file-input" />');
*/
});
$("#upload-files").on("click", function(e) {
e.preventDefault();
e.stopPropagation();
var all_files = [];
try {
var files = document.querySelectorAll(".file-preview-image");
for(var i = 0; i < files.length; i++) {
//
a_uploader(files[i].file, "#{id:saveDoc}", 0, 10);
}
} catch(e) {
console.log(e);
}
});
function a_uploader(file, uploadID, counter, maxSize){
try {
var formData = new FormData();
formData.append("#{id:FileUploadCtrl}", file);
formData.append("#{id:Created}", document.getElementById("#{id:Created}").value);
formData.append("$$viewid", dojo.query("input[name='$$viewid']")[0].value);
formData.append("$$xspsubmitid", uploadID);
formData.append("view:_id1", "view:_id1");
if(document.getElementById("#{id:parentId}") != undefined){
formData.append("#{id:parentId}", document.getElementById("#{id:parentId}").value);
}
var xhr = new XMLHttpRequest();
/* event listners */
xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentComplete = Math.round(e.loaded * 100/e.total);
console.log("Uploading... " +percentComplete.toString() + "%)");
}
else {
console.log("Uploading...")
}
}, false);
xhr.addEventListener("error", function(e) {
//insert error between error div
console.log("error: " + e);
}, false);
xhr.addEventListener("abort", function() {
//insert cancelled between div
console.log("Upload cancelled");
}, false);
xhr.open("PATCH", "#{javascript:context.getUrl()}");
xhr.send(formData);
} catch (e) {
console.log("a_uploader: "+e);
}
}
function clear_inputFiles(){
try {
var files = document.querySelectorAll(".file-preview-image");
for(var i = 0; i < files.length; i++) {
}
} catch(e) {
}
}
});]]>
</xp:this.value>
</xp:scriptBlock>
<xp:this.resources>
<xp:script src="/x$.js" clientSide="true"></xp:script>
</xp:this.resources>
</xp:view>
我不是故意用「PATCH」請求發佈代碼。它應該是「POST」 – MichaelGee
我的預感是它與onSaveDoc有關。你有沒有嘗試改變使用onclick事件?如果從XPage綁定中刪除concurrencyMode = false,它也會執行相同的操作嗎? –
我將concurrencyMode更改爲false。如果我將該事件處理程序更改爲onclick,則會遇到運行上載腳本的JavaScript問題,但請讓我試試看。 – MichaelGee