I’ve done this a few ways before.
The first, was to simply ignore the best practice (or perhaps even requirement) that the form element had to be outside the table. I have a working project where I manually placed a <form ...>
inside a table cell, and then inside that form, I created another table with inputs, etc. This can work, but really is not ideal and may even break in some browsers.
The second way is to use css grids instead of tables. You can google all sorts of solutions on this, but there isn’t anything in wappler natively. I really like CSS grids, but it becomes manual work at this stage.
However, I think the best solution for Wappler today is…
To maintain your forms outside of the the table structure altogether. Your inputs would be inside the table, but your form would not. Each of the inputs then gets a form attribute that points to the id of the intended form.
Take this working example.
There is a server connect that has the items we want to repeat over.
Inside the first container, there is all the content that will be displayed to the user. There is a row that repeats using the serverconnect data array of “cars”. It has inputs inside the table structure, but there is no form.
In the second container, there is another repeat of the same data “cars”, but this time we are creating a form with nothing inside of it.
The inputs inside the table get a dynamic form attribute that matches the dynamic form id. I’m using the index of the repeats to keep everything in sync.
<dmx-serverconnect id="serverconnect1" url="api/output_repeat"></dmx-serverconnect>
<div class="container">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">Text input</th>
<th scope="col">Select</th>
<th scope="col">File upload</th>
<th scope="col">Submit button</th>
</tr>
</thead>
<tbody>
<tr dmx-repeat:each_car="serverconnect1.data.cars">
<td>
<input id="text1" name="text1" type="text" class="form-control" dmx-bind:form="my_form_{{$index}}">
</td>
<td>
<select id="select1" class="form-select" dmx-bind:form="my_form_{{$index}}" name="select">
<option value="1">Option One</option>
<option value="2">Option Two</option>
<option value="3">Option Three</option>
</select>
</td>
<td class="text-center">
<input type="file" class="form-control visually-hidden" dmx-bind:id="file_input_{{$index}}" name="myfile" aria-describedby="input1_help" dmx-bind:form="my_form_{{$index}}">
<label dmx-bind:for="file_input_{{$index}}" class="form-label">
<i class="fas fa-cloud-upload-alt"></i>
</label>
</td>
<td>
<a href="#" class="btn" dmx-on:click="data_forms[$index].my_form.submit(true)">Save</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="container visually-hidden">
<div dmx-repeat:data_forms="serverconnect1.data.cars">
<form dmx-bind:id="my_form_{{$index}}" id="my_form" is="dmx-serverconnect-form" method="post" action="api/form_save">
</form>
</div>
</div>
EDIT: I added a file input into the mix.