What's the technique for looping form fields and sending them to the API script?

I’m venturing slightly further than normal with repeats and arrays, etc. but need a steer from someone.

Here’s my page code:

<div class="container">
    <form id="formQuestionnaire" is="dmx-serverconnect-form" method="post" action="/dmxConnect/api/AddEditQuestionnaire.php">
        <div is="dmx-repeat" id="repeatquestions" dmx-bind:repeat="connQuestions.data.queryQuestions">
            <div class="form-row">
                <div class="col">
                    <h4 class="mt-3">{{$index + 1}}. {{questionText}}</h4>
                    <select dmx-bind:id="response{{$index}}" name="response[]" class="custom-select mb-2">
                        <option value="answered">See answer</option>
                        <option value="na">Not applicable</option>
                        <option value="rathernotsay">Would rather not say</option>
                    </select>
                    <div dmx-show="(response.value == 'answered')">
                        <input type="range" class="form-range" dmx-bind:id="customRange_{{$index}}" name="scalevalue[]" min="0" max="10" style="width: 50%;"> <span class="ml-3" style="font-size: 2em;">{{scalevalue.value}}</span>
                        <input type="hidden" dmx-bind:id="questionid_{{$index}}" name="questionid[]" dmx-bind:value="QuestionID">
                        <textarea dmx-bind:id="comments_{{$index}}" name="comments[]" class="form-control" placeholder="Comments"></textarea>
                    </div>
                </div>
            </div>
        </div>
        <div class="form-row mt-2 mb-2">
            <div class="col">
                <button id="btn1" class="btn btn-primary" type="submit">Submit</button>
            </div>
        </div>
    </form>
</div>

But I don’t think I’ve got it right. I have a table containing loads of questions and the page has a query to get a relevant batch of those questions so they can be answered. So I will end up sending the question ID and the answer fields to my API script which will then repeat through them and insert/update the database.

Am I on the right track? Could someone just confirm I’m doing this right or correct me if I’m wrong?

Many thanks all.

Are there any @wappler_ambassadors able to give me a steer?

@sitestreet, What does your ServerConnect look like? As in the post fields?

If you’re submitting an array, you’ll need to bind to the name. For example:
dmx-bind:name="comments[{{$index}}][message]"

Thanks @mikkime23. I’ve not built the SC yet. I want to make sure the front end is set up correctly to avoid spending ages getting SC to work when the fault will likely lie with the page!

1 Like

Thanks again @mikkime23. You gave me a very key part which I’d overlooked so now the form is sending all the data in an array nicely.

I have one bit that’s not working as a result of the change:

<div dmx-show="(response[$index].value == 'answered')">

This is on line 12 of my original code snippet. I’ve added the $index to it and have tried with {} and {{}} but none of them are working. What’s the correct way to access the array variable?

1 Like

Are you using $index inside the square brackets response[$index]? Or response{{$index}}?

I’ve tried…

response[$index]
response[{$index}]
response[{{$index}}]

and none of them work.

Try and remove the square brackets and use response{{$index}}.

Otherwise, set a static ID as well and use that. This usually works for me when I’m working in loops.

E.g:
<select id="response" dmx-bind:id="response{{$index}}" name="response[{{$index}}][property]" class="custom-select mb-2">

If you are using a dmx attribute the value will be parsed by App Connect already and therefore you shouldn’t be using {{}}

dmx-bind:id="'response'+$index"

1 Like

Brilliant. The static ID solved it.

Genius. I’ve learned a lot more and it all makes sense so huge thanks @mikkime23.

  1. Use the dmx-bind:name=var[{{$index}}] so the array is posted correctly
  2. Create a static ID as well as the dynamic one (so dmx-bind:id= and also id=)

Those two points solved it all completely.

1 Like

Aah, excellent point @JonL. What about arrays?

dmx-bind:name="'response['+$index+']'" ?

Would this also mean I don’t need the static ID?

<div dmx-show="('response_'+$index.value == 'answered')"> ?

Great! Glad I could help.

For array and objects you should use {{}} to parse them actually.

Have you tried with:

dmx-bind:name="{{response[$index]}}”

Would you say that’s a hard rule. Off the top of my head, there are generators that produce curly brackets as well where you could go without. If it works, are there downsides to using the curly brackets?

If there are objects or arrays involved it gets trickier indeed. And if you are using a mix of array/objects, strings, plain js and are also trying to parse app connect expressions at the same time it becomes hell :joy:

I’ve definitely come across that. I sometimes got to the point of, if it finally works, don’t even breathe on it. Just leave the damned thing alone. :joy:

2 Likes

Nope, that doesn’t work.

I have everything working with the previous suggestions and I’ve changed the fields…

from
dmx-bind:name=response[{{$index}}]

to
dmx-bind:name="'response['+$index+']'"

I’ve kept the static ID in there but am wondering if that’s poor practice because every ID should really be unique. It works so I’m not overly fussed but would appreciate any thoughts on that.

Hi Jon,
You can have both static and dynamic IDs on an item
e.g.

<input type="text" id="staticid" dmx-bind:id="dynamicid{{$index}}" dmx-bind:name="dynamicname[{{$index}}]">

When referring to this for another item’s show/hide use the static ID. Wappler will use this and then change the id to satisfy the browser’s unique ID requirement (or other jQuery/JS you might use to identify an element)

i.e. I could look at the above input value with:

<div dmx-show="staticid.value"></div>
2 Likes