B4J Question [ABMaterial]: [SOLVED] How to get ABMUploadHandler to work with a custom file uploading component?

Mashiane

Expert
Licensed User
Hi there

I'm creating a custom component and just need to be advised in terms of how I can get it to work with ABMUploadHandler and thus trap the Page_FileUploaded sub.

Working Examples (update)


In both examples you can upload multiple files with the components to your server.

Both the ABMUpload and ABMFileInput components have a public property called UploadHandler, logging this returns "abmuploadhandler"

So far, I have been able to trap the change event which returns the selected files.

B4X:
Dim onchange As String = $"$('#${compid}files').change(function(){
var ${compid}files = document.getElementById('${compid}files');
var ${compid}list = [];
for (var x = 0; x < ${compid}files.files.length; x++) {
var eachName = ${compid}files.files[x].name;
${compid}list.push(eachName);
};
var output = JSON.stringify(${compid}list);
this.value=null;
b4j_raiseEvent('${ABMComp.ID}_changed', {'value':output});
});"$
So I guess following the same suit, I could read the selected files, save them and perhaps use Ajax to upload to the server. I guess I could use PHP but there is already functionality to upload files with ABMUploadHandler which calls Page_FileUploaded, which is my ultimate goal.

Thanks in advance for your help.

Regards

Mashy
 
Last edited:

Mashiane

Expert
Licensed User
Found it...

After studying how everything works..

formData: https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData
xmlReq: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
upload handler: abmuploadhandler - property from FileInput
https://www.sitepoint.com/html5-ajax-file-upload/
https://www.linkedin.com/pulse/upload-multiple-files-html-5-javascript-progress-bar-cancel-hewage

So the ABMUploadHandler needs a formData object with keys 'upl'
On the components, I realized that I was clearing the contents on change and this was causing the upload error.

B4X:
'upload the selected files
Sub Upload
Dim script As String = $"var ${compid}files = document.getElementById('${compid}files')
for (var i = 0; i < ${compid}files.files.length; i++) {
var file = ${compid}files.files[i];
var fileName = ${compid}files.files[i].name;
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", function (e) {
var percent = (e.loaded / e.total) * 100;
percent = Math.round(percent);
}, false);
ajax.addEventListener("load", function (e) {
}, false);
ajax.addEventListener("error", function (e) {
}, false);
ajax.addEventListener("abort", function (e) {
}, false);
ajax.open("POST", "abmuploadhandler", true);
var uploaderForm = new FormData();
uploaderForm.append('upl',file,fileName);
ajax.send(uploaderForm);           
}"$
    Page.ws.Eval(script, Array As String(compid))
    Page.ws.flush
End Sub
So this will load each file and trap Page_FileUploaded.
 

Harris

Expert
Licensed User
Sweet...

Is there anything we CAN'T do here in ABM / B4J?

You sure are persistent in your discovery process - as well as expert to find a solution.
Wish I had half your knowledge in these coding regards.

Thanks
 

Don Oso

Active Member
Licensed User
Found it...

After studying how everything works..

formData: https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData
xmlReq: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
upload handler: abmuploadhandler - property from FileInput
https://www.sitepoint.com/html5-ajax-file-upload/
https://www.linkedin.com/pulse/upload-multiple-files-html-5-javascript-progress-bar-cancel-hewage

So the ABMUploadHandler needs a formData object with keys 'upl'
On the components, I realized that I was clearing the contents on change and this was causing the upload error.

B4X:
'upload the selected files
Sub Upload
Dim script As String = $"var ${compid}files = document.getElementById('${compid}files')
for (var i = 0; i < ${compid}files.files.length; i++) {
var file = ${compid}files.files[i];
var fileName = ${compid}files.files[i].name;
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", function (e) {
var percent = (e.loaded / e.total) * 100;
percent = Math.round(percent);
}, false);
ajax.addEventListener("load", function (e) {
}, false);
ajax.addEventListener("error", function (e) {
}, false);
ajax.addEventListener("abort", function (e) {
}, false);
ajax.open("POST", "abmuploadhandler", true);
var uploaderForm = new FormData();
uploaderForm.append('upl',file,fileName);
ajax.send(uploaderForm);          
}"$
    Page.ws.Eval(script, Array As String(compid))
    Page.ws.flush
End Sub
So this will load each file and trap Page_FileUploaded.
Thanks for your beautiful hack !! Well done!
 
Top