Formatting to be 50/50

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?


[
  {
    "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"
            }
          }
        }
      }
    ]
  }
]

Why not?

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

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 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.

3 Likes

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.