# Formatting to be 50/50

**URL:** <https://forum.inductiveautomation.com/t/formatting-to-be-50-50/108616>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [July 17, 2025, 2:13pm UTC](https://forum.inductiveautomation.com/t/formatting-to-be-50-50/108616 "2025-07-17T14:13:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![chaerrydairy](https://avatars.discourse-cdn.com/v4/letter/c/35a633/32.png) [@chaerrydairy](https://forum.inductiveautomation.com/u/chaerrydairy)\
**Post date:** [July 17, 2025, 2:13pm UTC](https://forum.inductiveautomation.com/t/formatting-to-be-50-50/108616/1 "2025-07-17T14:13:33Z")

</div>

Hello,  
I am trying to format this in a way so that the two components here will always adjust and grow so that they share the width equally. I was thinking of wrapping them in another contained but found that I couldn't wrap the label and dropdown into its own flex column after they are made. Any ideas?

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/6/1/61043693c391c23c34cbd6128c4b0b4973a606dd.png)  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/e/fe948ac2dd239fcfe156112307de7589d8a743bf.png)

```python
[
  {
    "type": "ia.container.flex",
    "version": 0,
    "props": {
      "justify": "space-between"
    },
    "meta": {
      "name": "LocationCategoryContainer"
    },
    "position": {
      "shrink": 0,
      "basis": "46px"
    },
    "custom": {},
    "children": [
      {
        "type": "ia.display.label",
        "version": 0,
        "props": {
          "text": "Location:",
          "style": {
            "color": "#FFFFFF",
            "fontFamily": "Helvetica",
            "fontWeight": "bold"
          }
        },
        "meta": {
          "name": "LocationLabel"
        },
        "position": {
          "shrink": 0,
          "basis": "78px"
        },
        "custom": {}
      },
      {
        "type": "ia.input.dropdown",
        "version": 0,
        "props": {
          "placeholder": {
            "text": "Select a location..."
          },
          "style": {
            "color": "#000000",
            "marginBottom": 10,
            "marginRight": 20,
            "marginTop": 10
          }
        },
        "meta": {
          "name": "LocationDropdown"
        },
        "position": {
          "basis": "160px"
        },
        "custom": {},
        "propConfig": {
          "props.enabled": {
            "binding": {
              "type": "property",
              "config": {
                "path": "...../LocationCategoryContainer/AssetDisplay.custom.Editable"
              }
            }
          },
          "props.options": {
            "binding": {
              "type": "property",
              "config": {
                "path": "session.custom.userPermissions"
              },
              "transforms": [
                {
                  "code": "\tpermissions = value.split(',')\n\t\n\toptions = [{'value': 1, 'label': 'Port City', 'isDisabled': True}, {'value': 3, 'label': 'Keating', 'isDisabled': False}, \n\t\t\t\t\t{'value': 4, 'label': 'Olthoff', 'isDisabled': True}, {'value': 5, 'label': 'Saranac', 'isDisabled': False}]\n\t\t\t\t\t\n\tif '3' in permissions or '4' in permissions or '5' in permissions or '2' in permissions: # port city admins\n\t\toptions[0]['isDisabled'] = False\n\t\n\tif '6' in permissions or '7' in permissions or '8' in permissions or '9' in permissions or '2' in permissions: # keating admins\n\t\toptions[1]['isDisabled'] = False \n\t\n\tif '10' in permissions or '11' in permissions or '2' in permissions: # olthoff admins\n\t\toptions[2]['isDisabled'] = False\n\t\t\n\tif '12' in permissions or '13' in permissions or '14' in permissions or '2' in permissions: # saranac admins\n\t\toptions[3]['isDisabled'] = False\n\t\t\n\treturn options",
                  "type": "script"
                }
              ]
            }
          },
          "props.value": {
            "binding": {
              "type": "property",
              "config": {
                "path": "...../LocationCategoryContainer/AssetDisplay.props.selection.selectedRow"
              },
              "transforms": [
                {
                  "code": "\tif value > -1:\n\t\treturn self.parent.parent.parent.parent.getChild(\"LocationCategoryContainer\").getChild(\"AssetDisplay\").props.data[value]['Plant_Location_Name']\n\treturn ''",
                  "type": "script"
                }
              ]
            },
            "onChange": {
              "script": "\t# set available lines to choose from\n\tdata = self.parent.parent.parent.parent.getChild(\"LocationCategoryContainer\").getChild(\"AssetDisplay\").props.data\n\t\n\tcategoryID = self.getSibling(\"CategoryDropdown\").props.value\n\tlocationID = self.props.value\n\t\n\tlines = []\n\tcheck_for_duplicates = set()\n\tfor row in data:\n\t\tline = row['Line']\n\t\tlineID = row['LineId']\n\t\trowLocation = row['LocationID']\n\t\trowCategory = row['CategoryId']\n\t\tif line not in check_for_duplicates and rowLocation == locationID and rowCategory == categoryID:\n\t\t\tnew_entry = {'label': line, 'value': lineID}\n\t\t\tlines.append(new_entry)\n\t\t\tcheck_for_duplicates.add(line)\n\tself.parent.parent.getChild(\"LineNameandIDContainer\").getChild(\"NameDropdown\").props.options = lines",
              "enabled": null
            }
          }
        }
      },
      {
        "type": "ia.display.label",
        "version": 0,
        "props": {
          "text": "Category:",
          "style": {
            "color": "#FFFFFF",
            "fontFamily": "Helvetica",
            "fontWeight": "bold"
          }
        },
        "meta": {
          "name": "CategoryLabel"
        },
        "position": {
          "shrink": 0,
          "basis": "81px"
        },
        "custom": {}
      },
      {
        "type": "ia.input.dropdown",
        "version": 0,
        "props": {
          "placeholder": {
            "text": "Select a category..."
          },
          "style": {
            "color": "#000000",
            "marginBottom": 10,
            "marginTop": 10
          }
        },
        "meta": {
          "tooltip": {
            "text": "value"
          },
          "name": "CategoryDropdown"
        },
        "position": {
          "basis": "161px"
        },
        "custom": {},
        "propConfig": {
          "meta.visible": {
            "binding": {
              "config": {
                "path": "../LocationDropdown.props.value"
              },
              "transforms": [
                {
                  "code": "\treturn True",
                  "type": "script"
                }
              ],
              "type": "property"
            }
          },
          "props.enabled": {
            "binding": {
              "config": {
                "path": "...../LocationCategoryContainer/AssetDisplay.custom.Editable"
              },
              "type": "property"
            }
          },
          "props.options": {
            "binding": {
              "config": {
                "path": "../LocationDropdown.props.value"
              },
              "transforms": [
                {
                  "code": "\tpermissions = self.session.custom.userPermissions.split(',')\n\t\t\n\tif value == 1: # Port City\n\t\toptions = [{'value': 1, 'label': 'Molding', 'isDisabled': True}, {'value': 2, 'label': 'Paint', 'isDisabled': True}, \n\t\t\t\t\t{'value': 3, 'label': 'Assembly', 'isDisabled': True}]\n\t\tif '3' in permissions or '2' in permissions: # molding admin\n\t\t\toptions[0]['isDisabled'] = False\n\t\tif '4' in permissions or '2' in permissions: # paint admin\n\t\t\toptions[1]['isDisabled'] = False\n\t\tif '5' in permissions or '2' in permissions: # assembly admin\n\t\t\toptions[2]['isDisabled'] = False\n\t\t\t\n\telif value == 3: # Keating\n\t\toptions = [{'value': 1, 'label': 'Molding', 'isDisabled': True}, {'value': 2, 'label': 'Paint', 'isDisabled': True},\n\t\t\t\t{'value': 3, 'label': 'Assembly', 'isDisabled': True}, {'value': 4, 'label': 'Warehouse', 'isDisabled': True}]\n\t\tif '6' in permissions or '2' in permissions: # molding admin\n\t\t\toptions[0]['isDisabled'] = False\n\t\tif '7' in permissions or '2' in permissions: # paint admin\n\t\t\toptions[1]['isDisabled'] = False\n\t\tif '8' in permissions or '2' in permissions: # assembly admin\n\t\t\toptions[2]['isDisabled'] = False\n\t\tif '9' in permissions or '2' in permissions: # warehouse admin\n\t\t\toptions[3]['isDisabled'] = False\n\t\t\t\n\telif value == 4: # Olthoff\n\t\toptions = [{'value': 3, 'label': 'Assembly', 'isDisabled': True}, {'value': 4, 'label': 'Warehouse', 'isDisabled': True}]\n\t\tif '10' in permissions or '2' in permissions: # assembly admin\n\t\t\toptions[0]['isDisabled'] = False\n\t\tif '11' in permissions or '2' in permissions: # warehouse admin\n\t\t\toptions[1]['isDisabled'] = False\n\t\t\t\n\telif value == 5: # Saranac\n\t\toptions = [{'value': 1, 'label': 'Molding', 'isDisabled': True}, {'value': 3, 'label': 'Assembly', 'isDisabled': True},\n\t\t\t\t{'value': 4, 'label': 'Warehouse', 'isDisabled': True}]\n\t\tif '12' in permissions or '2' in permissions: # molding admin\n\t\t\toptions[0]['isDisabled'] = False\n\t\tif '13' in permissions or '2' in permissions: # assembly admin\n\t\t\toptions[1]['isDisabled'] = False\n\t\tif '14' in permissions or '2' in permissions: # warehouse admin\n\t\t\toptions[2]['isDisabled'] = False\n\t\t\t\t\t\n\telse:\n\t\toptions = []\n\t\t\n\treturn options",
                  "type": "script"
                }
              ],
              "type": "property"
            }
          },
          "props.value": {
            "binding": {
              "config": {
                "path": "...../LocationCategoryContainer/AssetDisplay.props.selection.selectedRow"
              },
              "transforms": [
                {
                  "code": "\tif value > -1:\n\t\treturn self.parent.parent.parent.parent.getChild(\"LocationCategoryContainer\").getChild(\"AssetDisplay\").props.data[value]['Production_Category_ID']\n\treturn ''",
                  "type": "script"
                }
              ],
              "type": "property"
            },
            "onChange": {
              "enabled": null,
              "script": "\tself.refreshBinding('props.options')\n\t\n\t# set available lines to choose from\n\tdata = self.parent.parent.parent.parent.getChild(\"LocationCategoryContainer\").getChild(\"AssetDisplay\").props.data\n\t\n\tlocationID = self.getSibling(\"LocationDropdown\").props.value\n\tcategoryID = self.props.value\n\t\n\tlines = []\n\tcheck_for_duplicates = set()\n\tfor row in data:\n\t\tline = row['Line']\n\t\tlineID = row['LineId']\n\t\trowLocation = row['LocationID']\n\t\trowCategory = row['CategoryId']\n\t\tif line not in check_for_duplicates and rowLocation == locationID and rowCategory == categoryID:\n\t\t\tnew_entry = {'label': line, 'value': lineID}\n\t\t\tlines.append(new_entry)\n\t\t\tcheck_for_duplicates.add(line)\n\tself.parent.parent.getChild(\"LineNameandIDContainer\").getChild(\"NameDropdown\").props.options = lines"
            }
          }
        }
      }
    ]
  }
]

```

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [July 17, 2025, 2:19pm UTC](https://forum.inductiveautomation.com/t/formatting-to-be-50-50/108616/2 "2025-07-17T14:19:45Z")

</div>

> [@chaerrydairy](#):
>
> I couldn't wrap the label and dropdown into its own flex column after they are made

Why not?

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/c/1/c1fb46ec6e9f0ba2955bfec4b6efd3b79fe05482.png)

---

<div class="post-metadata">

**Author:** ![chaerrydairy](https://avatars.discourse-cdn.com/v4/letter/c/35a633/32.png) [@chaerrydairy](https://forum.inductiveautomation.com/u/chaerrydairy)\
**Post date:** [July 17, 2025, 2:22pm UTC](https://forum.inductiveautomation.com/t/formatting-to-be-50-50/108616/3 "2025-07-17T14:22:14Z")

</div>

I couldn't wrap both the label and dropdown into one. Only one or the other

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [July 17, 2025, 2:23pm UTC](https://forum.inductiveautomation.com/t/formatting-to-be-50-50/108616/4 "2025-07-17T14:23:37Z")

</div>

There's no need for further containers.  
Set the label position props to  
`grow : 0`  
`shrink : 0`  
`basis : auto`  
They will then take up as much space as required.

Set the dropdown position props to  
`grow : 1`  
`shrink : 0`  
`basis : 200px`  
They will then share the available space with a minimum width of 200px.

**Homework marking**  
You have lost points for the following:

1. No use of style classes anywhere. Everything is hard-coded. You should define styles classes for everything you can. [-20 marks]
2. Hard-coded colors. You should be using [Built-in Theme Colors](https://docs.inductiveautomation.com/docs/8.1/ignition-modules/perspective/styles/perspective-built-in-themes#built-in-theme-colors) where possible. When I posted your JSON into a view the labels didn't show up on my light theme because you've hard-coded the label color as #ffffff. Instead use `--neutral-90` to get a contrasting label on a `--neutral-10` background. (You need to use `var(--neutral-90)`, etc., when defining them in style classes. [-5 marks]
3. No left or right padding in the flex container so the components are jammed up against the edges. Again, define a style for left-right and top-bottom padding (I use `paddingLR` and `paddingTB`) and select these in the container classes.) [-5 marks]
4. You've set margins individually on the various components to open up gaps between them. Just add `gap : 8px` into the flex-container's style. This will give consistent spacing between all items. (I haven't figured out how to do this in a style class yet.)
5. You've used `fontWeight : bold` on the labels. Why? Look at all your Windows applications. Labels are normal font weight. Again, if you really need this, define a style, `captionWeight` and you can adjust the weight of every caption in your application in one go. [-5]
6. Same for `font : Helvetica`. Use a style.

That's enough for now! Make elegant GUIs. Read up on good GUI design and its psychology! Have fun.

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [July 17, 2025, 2:24pm UTC](https://forum.inductiveautomation.com/t/formatting-to-be-50-50/108616/5 "2025-07-17T14:24:30Z")

</div>

Yeah I hope they improve that in a future version. For now what I always do is wrap one of the components, then cut/paste the others into the new wrapper component (make sure you "Deep Select" it first).

@Transistor is right, though, there is another way. It won't be exactly 50/50 as the two labels aren't the exact same length, but you could force them to be with a specific basis and grow/shrink of 0.
