How to set location of form element?
I'm using a load event on a form section and a collection to add form elements.
This is working but the elements are added at the top of the form. Wondering how to set them to be added further down the form?
-
Hi Richard,
You need to set the "index" property on the form elements you are adding.
One other thing to check is that you are setting the "Element ID" of the added form element to a unique string value that doesn't start with a number. For example, "addedElement1" would be good. If you just give it an "Element ID" of "1" it can cause problems.
--Ryan
0 -
Thanks Ryan,
I've tried every syntax permutation I can think of. Currently.
=["index",5]
Isn't working. What should be placed in that field? An array of objects doesn't seem to be valid.
--> gcx:wf:forms::AddFormElement (1554)
{…}
?
inputs: {…}
??
element: Array [ "index", 5 ]
??
elementName: "txtSectorCom0"
??
elementType: "TextBox"
??
form: Object { actor: {…}, state: {…}, route: false, … }
??
<prototype>: Object { … }
?
outputs: Object { }
?
<prototype>: Object { … }
bundle.js:1:286782
0 -
I don't understand your syntax here... you need to be providing an element object to the AddFormElement activity and not some array. This is an object with properties such as "enabled", "section", "type", "autoActivate", and "index". This is the index property is what Ryan was instructing you to set, for example in an evaluateExpression activity where you set someElement.index = 5.
0 -
If you're unsure of how to structure your element, here's what I would do. Make a form and add the element that you want to dynamically place into it, then run the form with your dev console open. Then, submit the form and look at it's "state" output. Find the element that you created earlier and expand it to see the properties that it needs, then create your object with the properties that your deem important e.g.
{
index: 5,
section: {name: 'Section1'},
wrap: 'soft'
}
0 -
I've attached an example.
0 -
@Ryan Cooney? I have a similar issue with image form elements. They are always appearing at the top of the form, regardless og the index being set higher than other elements such as a text element in the example below.

In dev mode, I can see that the text element actually loads first, but the images are added above the text element... Any ideas? I am adding image elements based on how many attachments a feature has. The index of the text element that I want at the top of the form is given index 1. The image elements are given index from 2 and up adding 1 for each pass in the attachment-loop...
I can actually see that the image with index 3 is placed above the image with index 2...
0 -
@Kristine Smaadal? I think the problem you are having occurs when the Element ID input of the Add Form Element activity is a number. Try setting this input to an expression like ="element" + $someValue. I was able to reproduce what you are seeing and this fixed it for me.
Form element IDs are supposed to be JavaScript identifiers. This means that numbers, or text that starts with a number is not valid. You can see this in the form editor if you try to rename an Element ID to something that starts with a number. It seems that the Add Form Element activity does not enforce this and you get unexpected behaviour. We'll look into this to see if it can be handled better.
--Ryan
0 -
Thank you, @Ryan Cooney? - this worked perfectly. Saved my day :)
0 -
@...
Do you have a sample workflow that shows how to add elements in a certain order? Even with the instructions in this thread, I cannot get it working. Does it matter in which event Add Form Element is called?
Let's say I have a form with two elements, and I want to insert a dynamic element in between those two, how do I do that?
No matter what I set the indexes to, the dynamic element is always added at the top. I also tried to change the indexes of the two fixed elements, but that didn't help. The element ID's do not start with a number.
If I use sections, the dynamic element is added to the correct section, but then the entire section will be moved to the bottom. For example, I have section1, section2 and section3, and try to add a text to section2, like this:
={
"title": {
"markdown":"dynamic text"
},
"section": {
"name": "section2"
}
}The form will show section1, section3 and then section2
0 -
@Berend Veldkamp did you figure this out?
I'm also trying to find a way to insert new elements at specific positions in a form. Assigning element index doesn't seem to work for me either, but with rowNumber I can add an element to the row I want. Then I can bump existing elements down by recalculating their row numbers.
But I'm also experiencing that the section then is moved down in the form, although not always and not necessarily to the bottom. Would be nice to see some examples of how this is supposed to work.
0 -
Unfortunately not, I ended up going with wherever the workflow decided the form elements should go :-(
0 -
In the example Kristine is refering to, we insert different elements at a certain order in the footers “load” event.
How ever as Berend Veldkamp said, if a element is added the normal way it goes straight to the bottom.0 -
The index property was deprecated when we added support for side-by-side form elements and is now not used.
The properties that determine the position of an element are rowNumber and rowIndex. Those are the row of the form and the position within the row respectively.
I did a quick test using Add Form Element and here's what I observed:
- If rowNumber is an existing row, the element will be added to that row. It does not insert a row.
- If rowNumber is not an existing row, a new row is added at the end. (but before the footer)
- The value of rowIndex is ignored. The element is always appended to the end of the row.
0 -
Ken Lyon Do you think this information could be added to the documentation?
I'd also like to know if there's an easier way to insert an element between two existing elements. It seems that I have to increase rowNumber for all elements below the new one first, and then call Add Form Element.
Example: Say I have existing elements with rowNumber 1, 2, 3 and 4, and want to insert a new element between 2 and 3. I first have to set the existing numbers to some higher value: 1, 2, 13 and 14, and then insert element(s) with a number between 3 and 12.
0 -
Berend Veldkamp I suspect we didn't consider specifying a location when this activity was first written. We probably just added it to the end of the form. Then we added support for side-by-side elements and had to have a roughly intelligent guess as to the best location to put it.
I'm inclined to think this would best be resolved by adding some new inputs to the Add Form Element activity. I think that Row Number and Row Index should be supplied directly. (Likely needing to fall back to inspecting the element when absent, for backwards compatibility.)
We'd likely also need an input called something like Insert Row (boolean) to make it explicit whether you're adding to an existing row (false) or pushing all existing rows down (true).
The documentation would then describe these new inputs.
Do you think that would address the issue? Do you have any other thoughts about the proposed behaviour?
1 -
That sounds good. We don't use dynamically generated forms often, but if we do, it's usually to insert elements between existing ones, and not to the end of the form.
Rather than setting the row number, I think is would make sense to specify an existing element where the new element should be inserted after (or before) instead . If, at a later moment, we insert a new element somewhere at the top of the form, we won't have to recalculate the insert position.
And a small thing, would it be possible to rename ‘row index’ to ‘column’? I know I'm going to mix up number and index.
1 -
Berend Veldkamp That's an interesting idea. I could see how “above textBox1” or “left of textBox3” would be more robust as a form evolves over time.
I find the index properties confusing too, despite being the one who added them. :) I deliberately avoided the use of “column” because that would convey a grid layout, which it is not. In a workflow form, elements in the same “column” are not aligned together. It's more so just the order within the row. I couldn't think of a more descriptive name so we're kind of stuck with it now.
0 -
Oh well, if something like “above textBox1” gets implemented, the number/index problem is no longer there anyway. Maybe only in some edge case.
0 -
I've added a few work items related to this.
Firstly, I've planned an update to add a few more inputs to Add Form Element to specify a target element and target position, like the “above textBox1” I mentioned earlier. To ensure we don't paint ourselves into a corner with left-to-right vs. right-to-left, I'll use “before” and “after” rather than left/right. Since that might confuse people with before/above and after/below sounding similar, I'll recommend we have these options:
- Above
- Below
- Beside (Before)
- Beside (After)
I think that should be clear enough.
In addition to this, I noticed a bug in that activity. It might be an uncommon use case, but if you don't specify an Element (or if the Element you specify does not have the relevant properties) it does not add rowNumber/rowIndex/section to the new element. These should always be present. This has been logged.
0 -
Berend Veldkamp I'm trying to address a legacy use case that currently seems broken. What do you think would be a good default behaviour if you added an element that did not have rowNumber or rowIndex present, and also didn't use this new logic we're discussing? As it stands, it seems to add at the top of the form, always pushing everything else down. Weirdly, still after the other newly added ones, though:
Before:- Existing 1
- Existing 2
Add one:
- New 1
- Existing 1
- Existing 2
Add another:
- New 1
- New 2
- Existing 1
- Existing 2
I don't know if this is just because of the ids I used (maybe they're appearing alphabetically?) but I think there should be a consistent behaviour.
Adding to the bottom of the form if no position information is given would be the easiest.
0 -
Hi Ken Lyon
I'd expect that if no position information is present, behavior would be the same as the Add Item activity, i.e. the element would be added at the end of the collection. The footer Button Bar would always be the last element, though.
I also noticed that if you set a rowNumber but no rowIndex, new elements will be added at the end of the row. To me this seems logical, but it is not consistent with rowNumber at this moment, and maybe another reason to change that.
Changing this behavior could of course break existing workflows, but personally, I'd have no problem with that, as long as the new behavior is more consistent and predictable.
1 -
Berend Veldkamp Thanks for your thoughts on this. I've finished work on this and it will be in VSWF 5.44. The new behaviour will be as follows:
- If you use new inputs to specify a target element and a target position, the new element will be added to the relative position, and subsequent elements will have their position and section updated as necessary.
- Adding above or below always inserts a new row.
- Adding before or after adds to an existing row.
- If you specify rowNumber and rowIndex, the element will be positioned there and subsequent elements will have their position and section updated as necessary.
- If you don't specify any of these, the new element will be positioned at the end of the form, above the footer.
These constraints are enforced:
- Nothing goes above/beside the header.
- Nothing goes below/beside the footer.
- A section element cannot share a row with another element.
If the activity encounters one of these scenarios, the new element is placed in the closest valid location that makes sense.
1 - If you use new inputs to specify a target element and a target position, the new element will be added to the relative position, and subsequent elements will have their position and section updated as necessary.
-
Hi Ken Lyon ,
Updating to VSWF 5.44 (5.44.1) has broken one of our workflows that was based on inserting form elements by specifying rowNumber and rowIndex. Neither rowIndex or rowNumber seem to be respected anymore, and the elements end up in one column in a weird order.
Attached screenshot shows the result of trying to make a 3x3 matrix of text elements in an empty form. Elements are added in sequence (increasing rowIndex and rowNumber).
Any idea why it's not working? Has anything changed with the way rowNumber and rowIndex should be specified?
0 -
Emil Solbakken Yes, the Add Form Element activity has been changed to include two new inputs for “Target Element” and “Target Position”. Otherwise, the element is added to the end of the form.
https://docs.vertigisstudio.com/workflow/latest/help/add-form-element.html?anchor=inputs_..1510
There was some irregular behaviour with the rowIndex and rowNumber properties, so we opted for this approach.
1 -
Ken Lyon thanks for the quick reply.
Can you please inform better before making such breaking changes? The What's New post for 5.44 state that "The Add Form Element activity has additional inputs to improve positioning of new elements. You can now specify relative positions, such as "above textBox1". And in your previous post describing the planned changes, you specifically say that the rowIndex/rowNumber method will be kept and improved. It's very hard to deduce from this that the existing method will actually be removed.
I think the new method is a nice addition, but I also think the rowIndex/rowNumber method make a lot more sense for building complex forms on load-time. Wish we could have both.
0 -
Hi Emil Solbakken . I just gave this a closer look as I don't think we intentionally broke backwards compatibility.
According to the code, it looks like we do try to retain the supplied values in certain circumstances:

The condition prior to this would be executed when targetElement and targetPosition are provided.
So, if you don't provide either of them and the element you provided had both a rowNumber and rowIndex, it should still behave as before.
1 -
Hi Ken Lyon. Good to hear that you intend to keep that functionality.
After some testing it seems like providing a rowNumber works as intended. I'm able to insert an element on a specific row, resulting in all subsequent elements being moved down.
Providing a rowIndex, however, seems to have no effect on the positioning of the new element. No matter what the rowIndex is, adding a new element to an existing row still leads to the existing elements being moved down and the new element ending up on its on row.
Before the update, we successfully used the rowIndex to position new elements on the same row as existing elements. So the behaviour must have changed in some way.
0 -
Emil Solbakken Thanks for the details. Sorry about this - it sounds like that's a regression, which was unintentional. I have logged a bug for us to follow up on this. You can look out for it in the release notes. The bug id is 329279.
I can't guarantee it'll be in the next release, but it's certainly on our radar.
1 -
Ken Lyon No worries, thanks for following up.
0 -
Emil Solbakken You may be interested to know this bug was a one-line fix:

The initial value of this variable was wrong.
We're just testing the change now, but it'll be in VSWF 5.46, coming in July.
0
Please sign in to leave a comment.
Comments
30 comments