Here is a demo file
Auto-place items in container.rp (87.6 KB)
Because your pills are chosen by droplist, each pill can be created in the editor and the width of each pill is known. To help with this, I set the first pill to “Fit to Text Width” in the STYLE panel. Then, when duplicated and the text label changed, the width of the pill is automatically set.
To keep things relatively simple and to demonstrate how this works, I created a few global variables. Default values are shown in parentheses. :
-
varPillWidth
//width of currently selected pill
-
varRowWidth
//available width of current row
-
varRowX (20)
//the x-position to place the next pill
-
varRowY (20)
//the y-position to place the next pill
-
varRowMargin (20)
//distance from edge of container to the pills
-
varRowPadding (10)
//distance between pills (and between rows)
A droplist has 10 items (plus the default “Select an item”). Choosing an item selects the associated pill in the dynamic panel container. When a pill is selected, the pill calculates where it should be placed, based on its own width (and height; all the same in this demo, but it supports pills of varying heights.)
A dynamic panel serves as the pill container, and has two states: “State1” and “blank”. Its Loaded event sets the available row width by calculating its width minus the padding, and it sets itself to the “blank” state, essentially hiding itself from view. Its “State1” contains 10 hidden pills plus a hotspot. The hotspot is just an invisible widget set to the height of the row margin and placed at the bottom of the dynamic panel to ensure there is a consistent bottom margin. This dynamic panel is set to the default “Fit to Content” so when a new row is added (by moving and then showing a pill) its height can automatically grow.
Now, when a pill’s state changes to “selected” it does a few things, which you can see in each pill’s Interaction code:
- There are two conditional cases, used to determine if this pill will fit on the current row, or if a new row is needed.
- The appropriate global variables are updated, so the current pill width, available row width, and the (x, y) location for this pill are known. (It turns out the varPillWidth is not really used, because each pill moves itself, which can use [[This.width]], but I kept varPillWidth anyway for demonstration purposes.)
- The pill moves itself to the appropriate location and then shows itself. It also updates the location to place the next pill (by setting varRowX, and if it is in a new row, also setting the varRowY value.)
If you need to “clear” or delete a pill, for example by clicking on it, you could set its selection state to “false”, hide it and move the pills after it accordingly. It may be a little tricky to handle moving pill(s) to a previous row, but the logic would involve checking the deleted pill’s y-location, whether the next pill could fit on that row, and if so, updating varRowY then move the next pill. For this, I would imagine another global variable could help, which would be essentially a list of the chosen pills in order. A kind of “pseudo array” of pill names or numbers, if you will, because Axure doesn’t support true arrays. The more interactions like this you need to support, the more a repeater approach will likely help save time and effort in the Interaction code.