How to upload multiple documents in repeat table

Hello Guys,

I request your help in uploading multiple images/PDF files in the repeat table as below. I know how to upload & save single document by selecting the document name using Select element, however, it won’t be convenient when the list of documents to be uploaded increases.

I have this update form with upload document element. I want to be able to upload documents which are listed in the repeat table.

This is the DB table in which i want to save the details of the uploaded document.

Let me know if you need more information.

Are you using form repeater?
Please see https://community.wappler.io/t/using-app-connect-form-repeater-with-update-record-forms/41651

2 Likes

Thanks, let me check if I can get it working.

Hey @franse ,

I went through the tutorial you shared and feel that I will have to Add new document detail eveytime to upload. It is fine when the number of documents to be uploaded is less, but will be somewhat problematic if the list of documents to be uploaded is large.

Is there a way where the list of documents is returned and document is uploaded against each item & by single click the files are uploaded & DB updated with name & path, similar to shown in the previous screenshot.

This is the way to go I guess.
The form repeater will repeat on server side, one after other, not all at once.

English is not my main language, so maybe I’m not understand you correctly, sorry about that.
Do you mind to explain a little more?

Hey,

As shown in the screen shot below, there are 2 documents each having its own separate upload bar. What i am looking to achieve is, to be able to choose files for each document & then upload it upon click of Save button. Both the files/images will be saved in the folder & DB will be updated with the uploaded name & URL of the document.

It will always be 2 files? Or the number of items (files to upload) need to be dynamically assigned?

The number of files to be uploaded will change depending on the page. So, yes, it needs to be dynamically assigned.

Unless I’m wrong, you need to use a form repeater. You can get the number of items on your form repeater (in this case 2) by doing a query like you use on the table.

On the server connect side, the repeat will starting to upload the files one by one using the repeat action.

On the client side you will see it exactly as you have now.
One save button.

@miu I suppose your Institute table structure has the main fields/columns (e.g. institute_id, institute_name, institute_code, institute_year etc…)
AND you have added a subtable to hold the documents details for each institute…

Right?
If yes, then the link that Francisco shared has all the required information.
The subtable (document details) will be handled inside a repeat in your server action.

Can you please share with us a screenshot of your table structure AND it would be nice to show us how you implemented the form of your above picture on your page (the form code or a screenshot of your from code)…
So we can understand what you have so far and if it is correct

@franse & @famousmag thanks for explaining the steps.
Yes, the table structure is same as you mentioned. I am working to implement the solution as per the doc shared by Franse & I will share the screenshots shortly.

1 Like

@franse, @famousmag

Hey guys,

It took time implementing the solution as I am new to development & still learning.

I followed the tutorial which works fine if I have to update text input fields. If I change the text input field with File Upload element, it uploads only 1 file & does not update the DB with filename.

Sharing the steps followed implementing the solution:

  1. Prepared the page for update records using form repeater

     <div class="container">
     <div class="row">
         <div class="col">
             <div class="table-responsive">
                 <table class="table">
                     <thead>
                         <tr>
                             <th scope="col">Inst iD</th>
                             <th scope="col">Institute Name</th>
                             <th scope="col">Year</th>
    
                         </tr>
                     </thead>
                     <tbody dmx-on:click="data_detail1.select(sc_nestedInstDocs.data.query[0].instituteID)">
                         <tr dmx-on:click="">
                             <th scope="row">{{sc_nestedInstDocs.data.query[0].instituteID}}</th>
                             <td>{{sc_nestedInstDocs.data.query[0].instituteName}}</td>
                             <td>{{sc_nestedInstDocs.data.query[0].estYear}}</td>
    
                         </tr>
    
    
                     </tbody>
                 </table>
             </div>
         </div>
         <div class="col-12" is="dmx-data-detail" id="data_detail1" dmx-bind:data="sc_nestedInstDocs.data.query" key="instituteID">
             <form is="dmx-serverconnect-form" id="frm_instDetails" method="post" action="/api/testAPIs/update_docs_copy" dmx-generator="bootstrap5" dmx-form-type="vertical" dmx-populate="sc_nestedInstDocs.data.query" dmx-on:success="notifies1.success('Form Updated')">
                 <div class="form-group mb-3">
                     <label for="inp_instituteID">Institute</label>
                     <input type="number" class="form-control" id="inp_instituteID" name="instituteID" dmx-bind:value="data_detail1.data.instituteID" aria-describedby="inp_instituteID_help" placeholder="Enter Institute">
                 </div>
                 <div class="form-group mb-3">
                     <label for="inp_instituteName">Institute name</label>
                     <input type="text" class="form-control" id="inp_instituteName" name="instituteName" dmx-bind:value="data_detail1.data.instituteName" aria-describedby="inp_instituteName_help" placeholder="Enter Institute name">
                 </div>
                 <div class="form-group mb-3">
                     <label for="inp_universityCode">University code</label>
                     <input type="text" class="form-control" id="inp_universityCode" name="universityCode" dmx-bind:value="data_detail1.data.universityCode" aria-describedby="inp_universityCode_help" placeholder="Enter University code">
                 </div>
                 <div class="form-group mb-3">
                     <label for="inp_estYear">Est year</label>
                     <input type="text" class="form-control" id="inp_estYear" name="estYear" dmx-bind:value="data_detail1.data.estYear" aria-describedby="inp_estYear_help" placeholder="Enter Est year">
                 </div>
                 <div class="row">
                     <label class="form-label">Upload Documents</label>
                     <div is="dmx-form-repeat" id="formRepeat1" dmx-bind:items="data_detail1.data.instDocs">
                         <div class="row">
                             <div class="col">
                                 <input id="inp_docID" name="docID" type="text" class="form-control" placeholder="Doc ID" dmx-bind:value="docID">
                             </div>
    
                             <div class="col">
                                 <input id="file_uploadDocs" name="uploadedDoc" type="file" class="form-control">
                             </div>
                             <div class="col">
                                 <button id="btn1" class="btn btn-danger" dmx-on:click="formRepeat1.remove($index)">Del</button>
                             </div>
                         </div>
                     </div>
    
                 </div>
                 <div class="row">
                     <div class="col"><button id="btn2" class="btn btn-primary" dmx-on:click="formRepeat1.add()">Add</button>
                         <button id="btn3" class="btn btn-success" type="submit">Save</button>
                     </div>
                 </div>
             </form>
         </div>
     </div>
     </div> 
    
  2. Update API

image image

  1. DB Entry

If you need any more details, let me know.

I think its more clear now…
You get the main instirute info fine.
But you have to add a repeat in order to loop through your documents…
(and of course adjust the values in your database updater accordingly with the repeat values)

If you need more help tell us

Hey @famousmag,

I am getting error while running the API (“message”: “image.load: path is required.”,)
What Works: Both the images are uploaded in the correct path.
What’s not working: Unable to Update the DB table

Steps for creating API:

  1. Added Repeat & used $_POST formRepeat as the Expression
    image

  2. Under repeat added the remaing 4 steps
    2.1) File Upload: Selected the same $_POST formRepeat for the Upload Fields.

2.2) Load Image: Chose the Image Path from the Repeat Section

2.3) Save Image

2.4) DB Update: Column values are selected from Repeat section.

Hey @miu,

Maybe I have missed something…
Let me check my friend and come back

1 Like

Hi AJ,

The Step 2 - File Upload looks incorrect. Instead of selecting the formRepeat1, you need to select the uploadedDoc, which is the input field for the uploaded file.

1 Like

OK… Let’s see.

First I supposed you have already understood that the main institute info are not updated because you update only the documents inside the repeat (I FORGOT TO TELL YOU THAT, I apologize).
For that you need an extra database update OUTSIDE the repeat (before or after the repeat, does’t matter) that will do exactly that: Update the institute main info (id, name, code, year).

Now on the files upload…
EDIT: first change the file upload to what @guptast said!! Thanks @guptast!
IF THIS SOLVING THE ERROR JUST IGNORE ALL THE REST

  1. where are you getting that error message? On your browser? Can you share a screenshot?
  2. Can you please disable only the database update step and try again? Do you still get that error?
1 Like

@famousmag @guptast, Thanks for your inputs.

I did the changes as suggested by @guptast, however, I am still getting image.load path is required. Out of the 2 image files I try to upload, the first file is uploaded in the folder path.

File Upload >>Upload Fields

Upload Path:

What i Tried: I tried by deleting the Load & Save Image steps after which I can see the path is generated for only 1 image as below screen shot.

Requesting your suggestions on solving this issue.

OK, I see.

In the Upload step the POST.formRepeat1[0] is selected so it always picks the 1st row of the POST…

Scroll down and pick the uploadedDoc fron inside the repeat

Try and tell us

@famousmag
Ohhh, finally!!
Both the images are uploaded & saved in the folder path.
Now, I will try to update the DB table & check if it is updating properly.
Thanks my friend for helping yet again. :slightly_smiling_face:

2 Likes