Here's an alternative approach I discovered to solve the issue: using jQuery, hidden fields, and form fields (hidden through CSS).
1.Create an additional field called "filedata" to store the data URL of the uploaded file.
- data type -Long text
- form control - text box.
- Control CSS class - filedata
- input style= display:none;to hide it (during development, you can leave it blank to test the data URL value coming through the jQuery code).
2.Create another extra field called "filename" to store the filename of the uploaded file.
- Control CSS class - filename
- input style= display:none;to hide it (during development, you can leave it blank to test the data URL value coming through the jQuery code).
( classnames are the same for all extra fields for multiple file uploads)
3.Add the "uploadgroup" class to the form div enclosing the fileupload control. Here's a sample code snippet from form layout:
<div class="form-row uploadgroup">
<div class="form-element">
**$$input:filedata$$$$input:filename$$** *(extra fields)* ( note only add the input)
$$label:uploadfile$$ $$validation:uploadfile$$ $$input:uploadfile$$ (file upload)
</div>
</div>
4.Add the following script tag for the jQuery script at the bottom of the form layout:
<script type="text/javascript" src="/assets/js/RetainFileUploadForForms.js"></script>
Below is the jQuery code (which could be improved):
// Retain fileupload form custom Jquery.
; (function ($) {
retainfile();
var prm2 = Sys.WebForms.PageRequestManager.getInstance();
prm2.add_endRequest(function (source, args) {
retainfile();
});
function retainfile() {
$(".uploadgroup").each(function () {
var reader = new FileReader();
var filedataControl = $(this).find($('.filedata'));
var filenameControl = $(this).find($('.filename'));
var uploadfilecontrol = $(this).find($('input[type="file"]'));
// Get a reference to our file input
const fileInput = uploadfilecontrol.get(0);
var setfilename = filenameControl.val() == "" ? "No file chosen" : filenameControl.val();
fetch(filedataControl.val())
.then(response => response.blob())
.then(blob => {
const svfile = new File([blob], setfilename, { type: blob.type })
//File object
var mytempFile = svfile;
// Now let's create a DataTransfer to get a FileList
const dataTransfer = new DataTransfer();
dataTransfer.items.add(mytempFile);
if (blob.type != "text/html") {
fileInput.files = dataTransfer.files;
}
if (svfile) {
reader2 = new FileReader();
reader2.onload = function (e) {
filedataControl.val(e.target.result);
}
reader2.readAsDataURL(svfile);
}
})
uploadfilecontrol.change(function () {
myFile = new File([this.files[0]], this.files[0].name, {
type: this.files[0].type,
lastModified: this.files[0].lastModified,
});
filenameControl.val(this.files[0].name);
if (this.files && this.files[0]) {
reader = new FileReader();
reader.onload = function (e) {
filedataControl.val(e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
filedataControl.val(this.files[0]);
});
});
}})(jQuery);
Sample of this working in a form - Sample form
Important checks if code doesn’t work:
- filedata – DataType is set to Long Text ? and Form control is set to TextBox
- filedata and filename have the correct corresponding css class and display:none set in style ( see screenshots above)
- in Layout the fileupload and the extra fields are under same div with class=”uploadgroup”