Loop through form elements

Hi, I have a page with form on it. The form is linked to collection and able to add data to the database. Now, I want to do something with my data, before it actually gets submitted to the DB, send an Email for example. I know how to add a hook, but not sure how can I loop through all my items on the form to get their name and value. I don’t want to hard code the names in my code, because there could be many input elements on the form and the form may change frequently.
Any ideas?

Your question is not clear enough. Maybe you’d like to add a screenshot and to explain in details.


Here is the screenshot of my form. As you can see, it is long and with multiple pages.

In my code, instead of refering to each item by name, i just want to loop through all the items and get their value.

Instead of this:

export function PotentialClients_beforeInsert(item, context) {
item. firstName = toUpperFirst(item.firstName);
item. lastName = toUpperFirst(item.lastName);
return item;
}

I want something like this:

export function PotentialClients_beforeInsert(item, context) {
foreach item in items {
item. name = XXX
}
return item;
}

Hope this is clear now.

@michaeldemb , actually it’s still not clear to me. Maybe someone else…

I think I get what you mean. I would create a backend module instead so you can pass an array to it with all the entered data. Then use wixData.update() to do whatever you want to the database in backend.

import { functionname } from 'backend/modulename';

export function submit_click(event) {
    let arr = [];
    for (let i = 0; i < enteredItems.length; i++) {
        arr.push([$w('#nameInput' + i).value, $w('#email' + i).value]);
        if (i === enteredItems.length - 1) { functionname(arr); }
    }
}

@skmedia In your example, you using #nameInput, which means I have to hard code all the input element names into my code. This is exactly what I don’t want to do, because I may have hundreds of elements.

In regular JavaScript, this is what I would do:

var elements = document.getElementById("my-form").elements; 

for (var i = 0, element; element = elements[i++];) {             
     console.log(element.value) 
} 

Here since, Wix form page does not have name (my-form), I cannot refer to it and get all the sub elements. i.e. I cannot use getElementById method.

Any ideas how to handle it?

@jonatandor35 Simply trying to find a way to save form data into csv and email it, before submitting data into DB.

@michaeldemb No, that’s precisely the point of putting the i in the identifier. You don’t have to hardcode anything, you just have to name all your input elements whichever way you want while putting a 0, 1, 2, 3, etc at the end of each name based on its row. If your inputs are named name0, email0, date0, etc0 on the first row, you can name them name1, email1, date1, etc1 on the second and the code will do its job automatically.

If you wanted to hardcode anything here it might just be to replace enteredItems.length so you could change it to x if you have x rows of inputs.

You can think of this as assigning a class name to each column of inputs and then looping through all appended children, since although you could probably code something looping through $w(‘TextInput’).value, you would be going through all of them regardless of where that data will be inserted to your database and any errors might throw off the whole thing.

@skmedia Ok, got it. What is enteredItems? I get an error saying it is not defined.

@michaeldemb If you have some function that returns however many rows have data, that would be enteredItems. Otherwise, you can do as I said before and hardcode the number while adding a condition to handle blank items.

@skmedia I think found an easier way to do it. I am just going to loop through children list of my main element and then just ignore texts and buttons

$w(‘#slideshowSlide4’).children.forEach( function (element) {
if (element.type !== “$w.Text” && element.type !== “$w.Button”) {
console.log(element.id);
}
});

What I can’t figure out, is how to get the value of each child element. I can get the type and ID, but not the value. Any idea?

@michaeldemb I would guess it’s probably because you haven’t handled falsy values. All items have an id, and type by default, but not a value.
if (element.type !== “$w.Text” && element.type !== “$w.Button” && element.value) {

@skmedia Actually, element does not have value property.

@michaeldemb How many other types of inputs do you have setup outside of button and text?

@skmedia Input fields, date pickup, dropbox, multiplechoice.

@michaeldemb Are you manually attaching dozens of these input groups to a slideshow?

@skmedia Yes, I am building the form using Wix editor.

@michaeldemb If I were you, I would save myself a lot of hassle and use a repeater instead. If you want pagination for it, it’s easy to connect. Each repeater container can hold an entire row of these input elements and if you wanted to add your own custom tab-based pagination you could save the repeater data for each page and concatenate it all when the submit button is clicked. The huge upside is you only have one container, and infinite children.