Unpacking arrays

Tarby777

Member
Hi all,

I already have a Webspeed routine that successfully grabs a single image sent from the client - I do a GET-LONG-VALUE into a Longchar, BASE64-DECODE it into a Memptr and COPY-LOB it out to disc. All good.

I'm now hoping to develop something based on a multiple file select/upload capability in JavaScript. I have an input like this:

Code:
<input type="file" id="fileInput" accept="image/*" name="files[]" enctype="multipart/form-data" multiple />

and JS to copy the files into form data and post them, like this:

Code:
const fileInput = document.getElementById("fileInput");
const selectedFiles = fileInput.files;

const formData = new FormData();
for (let i = 0; i < selectedFiles.length; i++) {
    formData.append("files[]", selectedFiles[i]);
}

const xhr = new XMLHttpRequest();
xhr.open("POST", [myUrl], true);
xhr.send(formData);

The JS is fine - it comes from a website, and is proven - but I don't know how to unpack the array of files in WebSpeed. Would I start with GET-LONG-VALUE again and move it into something like a JsonObject / JsonArray that I could iterate through? Might it be better to split the images out into multiple POSTs in the JS so I don't have to deal with arrays?

TIA
Tarby
 
Last edited:

Cecil

19+ years progress programming and still learning.
I think you will have to make multiple file send requests. Because the get-binary-data() function can only handle one tag name at a time
OR
In your Javascript when appending form data, add a counter to the input name object, i.e. files[]0, files[]1, files[]2...files[]x,
and include the total file count in the form request. i.e. formData.append("totalFileCount", i);

Code:
const fileInput = document.getElementById("fileInput");

const selectedFiles = fileInput.files;

const formData = new FormData();for (let i = 0; i < selectedFiles.length; i++) {

    formData.append("files[]" + i, selectedFiles[i]);

}

formData.append("totalFileCount" , i);


const xhr = new XMLHttpRequest();

xhr.open("POST", [myUrl], true);


Code:
def var iFileCount as int no-undo.
def var iFileIndex as int no-undo.

iFileCount = int(get-value('totalFileCount')).

do iFileIndex = O to iFileCount:

memptr = get-binary-value('file[]'+ string(iFileIndex)).
blar blar bar.


end
 

Cecil

19+ years progress programming and still learning.
With a little bit of help from ChatGPT to write the HTML. I just included the ScriptScript code.

Code:
 <SCRIPT LANGUAGE="SpeedScript">
    create widget-pool.
 
    procedure output-Header :
 
        define var mFile as memptr no-undo.
        define var cfile as char   no-undo.
     
        if REQUEST_METHOD eq 'POST':U then
        do:
     
            set-size(mFile) = 0. 
      
            assign
                mFile = get-binary-data("file":U).
              
            if mFile <> ? then
            do:
                assign
                    cfile = get-value("file":U).
                  
                copy-lob from mFile to file cFile no-convert.
              
                set-size(mFile) = 0.
             
                output-http-header("Status":U, "200").
                output-content-type("plain/text":U).
             
                {&OUT} substitute("File Uploaded: &1", quoter(cFile)).
             
            end.
        end.
     
        return.
    end procedure.

    if REQUEST_METHOD ne 'GET':U then
        return.
 
</SCRIPT>

<!DOCTYPE html>
<html>
<head>
    <title>Multiple File Upload</title>
</head>
<body>
    <input type="file" id="fileInput" multiple>
    <button onclick="uploadFiles()">Upload Files</button>
    <progress id="progress" value="0" max="100"></progress>
    <div id="output"></div>

    <script>
        function uploadFiles() {
            var fileInput = document.getElementById('fileInput');
            var output = document.getElementById('output');
            var progress = document.getElementById('progress');

            // Get the selected files
            var files = fileInput.files;

            // Iterate through the selected files and upload each one
            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                var formData = new FormData();
                formData.append('file', file);

                var xhr = new XMLHttpRequest();
                xhr.open('POST', '`SELFURL`', false);

                xhr.upload.onprogress = function(e) {
                    if (e.lengthComputable) {
                        var percent = (e.loaded / e.total) * 100;
                        progress.value = percent;
                    }
                };

                xhr.onload = function() {
                    if (xhr.status === 200) {
                        output.innerHTML += 'File ' + file.name + ' uploaded successfully.<br>';
                    } else {
                        output.innerHTML += 'Error uploading ' + file.name + '.<br>';
                    }

                    if (i === files.length - 1) {
                        // Reset progress bar when all files are uploaded
                        progress.value = 0;
                    }
                };

                xhr.send(formData);
            }
        }
    </script>
</body>
</html>
 
Last edited:
Top