S3 Multi Upload $_GET Inputs

Hi fellow Wappler users & team,

I’m wondering if anyone has any advice on how to get this working.

I am after creating a page called ‘additionaldocuments’ for uploading additional documents and images to a case in a case management system that I am developing. I have the id of the case ‘caseid’ passed via a query parameter to the page so that I will be able to keep track of which files are related to which case.

I would like to upload these additional documents to Amazon S3 using an S3 Multi Upload Control and have them uploaded to a subfolder in the bucket named after the caseid.

So essentially the file structure in s3 ideally should be <bucketname>/<caseid>/<filename>

As far as I know, this is done by modifying the Key in the S3 Sign Upload URL properties of the server action. Below is my server action:

It might be staring me in the face, but I cannot seem to be able to get my caseid to be passed to the server action, and so when I check S3, the file structure is just a folder called ‘/’ and the file is in there.

Unlike other server connects, the S3 Multi Upload Control doesn’t have an input in the properties to specify what caseid is after adding it to the $_GET inputs of the server action.

My end goal then would be that I would like to be able to show a list of uploaded files on the additionaldocuments page with links for each uploaded file in the folder that was named after the caseid which again is passed on the query parameter

If anyone had any suggestions on how I could get this to work, I would be extremely grateful!

You could attach the case ID to the Server Action URL:

/api/s3/signupload?caseid=123

If you post here the HTML code maybe we can help with that approach if you’re unable to figure out how to dynamically pass the caseid through that URL

1 Like

@Apple, thank you very much for your reply, I gave it a shot by trying url="/api/s3/signupload?caseid=query.currentcase" where query.currentcase should be the caseid passed over from the previous page the user was on.

I’ve tried various combos of url="'/api/s3/signupload?caseid='+query.currentcase" and url="/api/s3/signupload?caseid={{query.currentcase}}" but to no avail.

The last attempt yielded an empty folder with the following name:

<!-- Wappler include head-page="layouts/portal" jquery_slim_33="cdn" fontawesome_4="cdn" bootstrap4="local" is="dmx-app" id="additionaldocuments" appConnect="local" components="{dmxS3Upload:{}}" -->

<dmx-serverconnect id="querycurrentcase" url="/api/case/querycurrentcase" dmx-param:currentcase="query.currentcase"></dmx-serverconnect>

<div id="s3upload" is="dmx-s3-upload-multi" url="/api/s3/signupload" accept="" class="text-center border">

    <table class="table table-bordered">

        <tbody>

            <tr dmx-hide="files.length">

                <td>

                    No files selected

                </td>

            </tr>

            <tr dmx-show="files.length" dmx-repeat="files">

                <td width="50">

                    <img width="50" dmx-bind:src="dataUrl" dmx-show="ready">

                </td>

                <td>

                    <div>{{ name }}</div>

                    <small dmx-show="!uploading &amp;&amp; !error">Ready to Upload</small>

                    <small dmx-show="!uploading &amp;&amp; error" class="text-danger">{{ error }}</small>

                    <div class="progress" dmx-show="uploading">

                        <div class="progress-bar" dmx-style:width="percent+'%'"></div>

                    </div>

                </td>

            </tr>

        </tbody>

    </table>

    <p dmx-hide="state.uploading">

        <button class="btn btn-primary" dmx-on:click.stop="s3upload.select()" dmx-show="state.idle">Browse</button>

        <button class="btn btn-primary" dmx-on:click.stop="s3upload.upload()" dmx-show="state.ready">Upload</button>

        <button class="btn btn-danger" dmx-on:click.stop="s3upload.reset()" dmx-show="state.done">Reset</button>

    </p>

    <p dmx-show="state.uploading">

        <button class="btn btn-danger" dmx-on:click.stop="s3upload.abort()">Abort</button>

    </p>

</div>

<meta name="ac:route" content="/additionaldocuments">

Try this:

<div id="s3upload" is="dmx-s3-upload-multi" url="/api/s3/signupload" dmx-bind:url="'/api/s3/signupload?' + query.currentcase" accept="" class="text-center border">

I used dmx-bind to be able to use dynamic expressions, and built the expression by hand

I replaced the url with dmx-bind:url, but you could also use the url at the same time (maybe so the URL is preserved in the UI), dmx-bind:url should override url when the page runs

Edit: Fixed something in the code, check again, also put back the url attribute as well

1 Like

Weirder still, it is now just producing a folder named / and a subfolder called / in the S3 bucket and the filename is not passing anymore

Oh, that’s unfortunate. But, don’t worry, you still have a 2nd chance

You can use server-side rendering instead of client-side rendering, to inject the query.currentcase variable

If you’re using NodeJS, take a look at this bug report of mine where you can copy-paste the syntax:

If you’re using PHP, I’ve never tried it, you can try to click “Server-side binding” in the UI to see the syntax it generates. Test it on regular text (like in a <p> tag) first

Happy to help!

@Apple, I am extremely grateful for your advice up to now. You have been more than helpful.

However, as I am a bit of a smooth brain, I don’t quite understand what to do with the information you have provided above regarding the server side rendering.

I appreciate you have dedicated plenty of time to this already, but could I be as annoying as to ask if you could point me in the right direction to if there is further information or a guide on this topic so that I can understand how to implement this?

Because you asked so nicely, I did a video for you. Note I may have made a mistake in the variable names:

Note the variable name on the video may be wrong, I don’t have much experience with the front-end, so I couldn’t remember if it’s “$_GET”, “query” or “querydata” or if there are additional steps needed to access such data

Hope it works though!

1 Like

Hi @Apple, you have been extremely helpful. I tried the server-side rendering, however, I think the main issue I started having was that my server connect URL would be ...signupload?caseid='+query.currentcase" and dmxS3Upload was trying to append ?name=... at the end, so it would end up not working out.

What I settled on doing in the end is modifying dmxS3Upload.js (not ideal but now I know what I did) so that instead it reads as &name instead of ?name the line where it says t.open("GET",this.props.url+"?name="+encodeURIComponent(this.file.name)). I did this in two places on the file, and used <div id="s3upload" is="dmx-s3-upload-multi" dmx-bind:url="'/api/s3/signupload?caseid='+query.currentcase" accept="" class="text-center border" url="/api/s3/signupload"> as the code on the page itself.

2 Likes

I really appreciate the video by the way, it really helped me to understand what was meant! Thank you very much @Apple

No problem! Glad you sorted it out

Actually, I think I have a better fix for you:

dmx-bind:url="'/api/s3/signupload?caseid='+query.currentcase + '&'"

I apply some clever trick there based on what you said, it might work with the original files:

/api/s3/signuploader?caseid=123&?name=Hello

Not ideal but I think it might work

Just tried it. Does not work. Have to change the core file.
Will have to create an FR. This S3 upload component has too many shortcomings.