# Dropdown width that accommodates longest string in its options?

**URL:** <https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [June 28, 2024, 3:24pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536 "2024-06-28T15:24:05Z")\
**Posts on this page:** 12\
**Page:** 1

<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:** [June 28, 2024, 3:24pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/1 "2024-06-28T15:24:05Z")

</div>

When I set the basis for my dropdown to "auto" it:

- Changes size when the selected option changes
- Doesn't even size to fit the whole label, but clips it with '...'

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/5/5/55ae9664b8e67291250ed05acb872f54daeb910f.png)

I could fix this by not using "auto," but then I'd have to figure out what the longest option label is, and it seems like there should be a better way (or that "auto" should just work better?)

Figuring out how to size a dropdown has to be a pretty common thing, so I'm just wondering how others go about it, or if I'm missing something that can make it work better. I'm designing for a system that will have very short labels in some cases, and much longer ones in others, so setting it to a fixed size isn't very desirable.

---

<div class="post-metadata">

**Author:** ![Bushmatic](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bushmatic/32/87014_2.png) [@Bushmatic](https://forum.inductiveautomation.com/u/Bushmatic)\
**Post date:** [June 28, 2024, 3:40pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/2 "2024-06-28T15:40:46Z")

</div>

You could bind the dropdown's `basis` property to `this.props.options` and use a script transform to iterate through the options, find the longest one, translate the character length into a pixel value, and return a string in the form "###px".

Or, set the basis to a very high pixel value that can accommodate most of your possible options, and just set the `shrink` value to 1. Not sure if that would solve the problem of the selected value getting cut off at all.

---

<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:** [June 28, 2024, 3:44pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/3 "2024-06-28T15:44:12Z")

</div>

> [@Bushmatic](#):
>
> You could bind the dropdown's `basis` property to `this.props.options` and use a script transform to iterate through the options, find the longest one, translate the character length into a pixel value, and return a string in the form "###px".

That's what I've decided to do, except using 'em' instead of pixels since that's a unit relative to the font size. Seems to work fine, just feels like overkill, and that "auto" should just work that way...

---

<div class="post-metadata">

**Author:** ![Bushmatic](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bushmatic/32/87014_2.png) [@Bushmatic](https://forum.inductiveautomation.com/u/Bushmatic)\
**Post date:** [June 28, 2024, 3:47pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/4 "2024-06-28T15:47:36Z")

</div>

Huh, I never knew you could use 'em' as a unit here. I learned something new today.

I did mess around with one of my dropdowns set to 'Auto' and it is working as you would expect -- not clipping my labels or anything. Weird that yours is exhibiting that behavior.

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/6/f/6f43dc4ff4527a3b78b010c358223316e9daddfd.png)

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/6/a6cf2a780de553fecc21c3935d2aee3afef4089f.png)

---

<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:** [June 28, 2024, 3:52pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/5 "2024-06-28T15:52:13Z")

</div>

Yeah that's strange, I thought at first maybe something in my stylesheet was causing the '...' but when I removed it, it still was doing it.

Does yours change size when options of different lengths are chosen?

---

<div class="post-metadata">

**Author:** ![Bushmatic](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bushmatic/32/87014_2.png) [@Bushmatic](https://forum.inductiveautomation.com/u/Bushmatic)\
**Post date:** [June 28, 2024, 3:55pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/6 "2024-06-28T15:55:31Z")

</div>

Yeah, it changes size to match the selected value. What are your `grow` and `shrink` values set to? Mine are at 0 and 1, respectively.

---

<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:** [June 28, 2024, 4:04pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/7 "2024-06-28T16:04:22Z")

</div>

Same, 0 and 1. Thought maybe it was unique to the browser, but I see the same thing in Chrome and Edge.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [June 28, 2024, 4:48pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/8 "2024-06-28T16:48:22Z")

</div>

As a workaround, I would use this expression:

```python
concat(len(max({this.props.options})) * 12.045, 'em')

```

---

<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:** [June 28, 2024, 5:52pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/9 "2024-06-28T17:52:33Z")

</div>

> [@lrose](#):
>
> `concat(len(max({this.props.options})) * 12.045, 'em')`

max({this.props.options}) returns null, so that doesn't seem to work, but it's essentially what I've done with scripting. I made it a library function as I anticipate reusing it in the future:

```python
def calculateDropdownBasisForLongestOption(options):
	widest = 0
	for val in options:
		if len(val.label) > widest:
			widest = len(val.label)
	return str(float(widest) * 0.8) + 'em'

```

It's not a perfect solution unless using a monospace font, which may be why we each came up with different multipliers...

I know that expressions are more efficient than scripts, but I'm assuming that's not the case when using the runScript() expression...?

---

<div class="post-metadata">

**Author:** ![Bushmatic](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bushmatic/32/87014_2.png) [@Bushmatic](https://forum.inductiveautomation.com/u/Bushmatic)\
**Post date:** [June 28, 2024, 6:03pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/10 "2024-06-28T18:03:20Z")

</div>

You can get the widest value in one line using list comprehension. Saves you from checking each value individually.

`widest = max([len(options[i].label) for i in range(len(options))])`

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [June 28, 2024, 6:10pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/11 "2024-06-28T18:10:45Z")

</div>

> [@Ryan\_Deardorff](#):
>
> I know that expressions are more efficient than scripts, but I'm assuming that's not the case when using the runScript() expression...?

I would have to default to @paul-griffith or @pturmel on this, I believe that there is a different penalty that you pay when using the `runScript()` expression.

`max()` won't work here, now that I'm looking because the objects in the array are all the same length. That's what I get for not testing.

If you have Phil's Integration Toolkit Module, then you could do this:

```python
concat(
    round(
        max(
            forEach(
                {this.props.options},
                len(it()['label'])
            )
        ) * 12.45,
    2),
"em")

```

This one is tested. 🤣

---

<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:** [June 28, 2024, 6:15pm UTC](https://forum.inductiveautomation.com/t/dropdown-width-that-accommodates-longest-string-in-its-options/92536/12 "2024-06-28T18:15:40Z")

</div>

> [@Bushmatic](#):
>
> widest = max([len(options[i].label) for i in range(len(options))])

Or even more simply:

```python
widest = max([len(opt.label) for opt in options])

```
