I have a Custom Control for uploading files to a page. And it works so well but only when it's not inside xp.this.rendered property. If it is, it gives me very unexpected results. Here's the code for the div which I use:
<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:actionGroup>
<xp:executeScript
script="#{javascript:print('But server side executes only without RENDERED')}">
</xp:executeScript>
<xp:saveDocument></xp:saveDocument>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
if (compositeData.postUpload!=null)
{
compositeData.postUpload.getScript().invoke(facesContext, null)
}
//print("сука");
}]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:actionGroup>
</xp:this.action>
<xp:this.script>
<xp:executeClientScript
script="console.log('CSJS works so well')">
</xp:executeClientScript>
</xp:this.script>
</xp:eventHandler>
</xp:button>
</div>
Inside the code above there's the refresh button which is supposed to saveDocument in order for the document to save the file which it has just received.
Also, there's the code which sends XHR requests with form data:
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);
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);
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)
{
document.querySelector('[id$=' + refreshID + ']').click(); // it's supposed to trigger the refresh button
}
}
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$=' + uploadID + ']').value = '';
}
I have no idea why CSJS code in document.querySelector('[id$=' + refreshID + ']').click()
does ALWAYS get executed. Regardless of xp.this.rendered
property, I always get 'CSJS works so well'
printed in the browser console, while But server side executes only without RENDERED
is printed in the server console only without the rendered property (or if it's permanently set to true). What's the reason behind it? Thanks in advance.
Ensure a "Display Errors" component is in the refresh area and check for validation errors. This is the most common cause for CSJS running but SSJS not running.