# Dropdown list separator

**URL:** <https://forum.inductiveautomation.com/t/dropdown-list-separator/16851>\
**Category:** Ignition\
**Created:** [February 2, 2018, 3:28pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851 "2018-02-02T15:28:19Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![JNelson](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@JNelson](https://forum.inductiveautomation.com/u/JNelson)\
**Post date:** [February 2, 2018, 3:28pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/1 "2018-02-02T15:28:19Z")

</div>

I need to create a dropdown list with (unselectable) separator lines. For example, in the Designer, if you expand the Project list in the menu bar, there are 3 sections in the list, separated by 2 lines: the top section has 3 choices at the top of the list (Comm Off, Comm Read-Only, and Comm Read/Write), then there is a separator line before the next section which has 3 choices (Properties, Gateway Event Scripts, and Client Event Scripts). This section is followed by yet another separator line before the last section with 2 choices (Preview Mode and Preview Language).

I don’t need to have expandable selections, radio buttons, or check boxes in my dropdown - just separator lines.

Is there a way to do this?

---

<div class="post-metadata">

**Author:** ![bfuson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bfuson/32/4597_2.png) [@bfuson](https://forum.inductiveautomation.com/u/bfuson)\
**Post date:** [February 2, 2018, 3:36pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/2 "2018-02-02T15:36:27Z")

</div>

You can add a propetyChanged event script to the dropdown which, if a user selects your separator line, you revert the selected index back to its old value. Like this:

Dropdown Contents:  
 ![](https://us1.discourse-cdn.com/inductiveautomation/original/2X/8/86affaf5dd7bde82898d60eacc30d13663fcf1fa.png)  
  
  
propertyChange script:

```auto
SEPARATOR_STR = "-----------------------------------"

if event.propertyName == "selectedIndex":
	if event.source.selectedStringValue == SEPARATOR_STR:
		event.source.selectedIndex = event.oldValue
```

---

<div class="post-metadata">

**Author:** ![JNelson](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@JNelson](https://forum.inductiveautomation.com/u/JNelson)\
**Post date:** [February 2, 2018, 3:41pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/3 "2018-02-02T15:41:54Z")

</div>

Yes I thought of that too, but I’m looking for a “cleaner”, more standard look.

---

<div class="post-metadata">

**Author:** ![bfuson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bfuson/32/4597_2.png) [@bfuson](https://forum.inductiveautomation.com/u/bfuson)\
**Post date:** [February 2, 2018, 4:04pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/4 "2018-02-02T16:04:49Z")

</div>

The standard look of a dropdown component is different than standard look of a menu component.

You might be able to write a module that grants access to a java.swing JMenu as a configurable Ignition component.  
Or you could hack together something out of a template canvas. You could wrap your ‘menu item’ into a template with mouse hover/click event scripts that gets painted into layout cells of the canvas, with different text parameters for each item.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [February 2, 2018, 4:19pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/5 "2018-02-02T16:19:16Z")

</div>

Interesting. Consider constructing a fake dropdown from a Label and a small Button. Have the button’s actionPerformed event construct and display a popup menu, but override its placement and size so it shows up below the Label. Have the menu items write to the Label .text property when selected (and whatever other functionality you need).

---

<div class="post-metadata">

**Author:** ![bfuson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bfuson/32/4597_2.png) [@bfuson](https://forum.inductiveautomation.com/u/bfuson)\
**Post date:** [February 2, 2018, 4:36pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/6 "2018-02-02T16:36:32Z")

</div>

I implemented the hacky template canvas approach, but with more of a “menu” style in mind. You could easily change the top label to look more like a dropdown.

https://i.imgur.com/r2Ur2fE.gifv?twitter#t

---

<div class="post-metadata">

**Author:** ![JNelson](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@JNelson](https://forum.inductiveautomation.com/u/JNelson)\
**Post date:** [February 2, 2018, 4:39pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/7 "2018-02-02T16:39:50Z")

</div>

I like that solution. I’m not quite sure how you implemented it though. Could you elaborate?

---

<div class="post-metadata">

**Author:** ![JNelson](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@JNelson](https://forum.inductiveautomation.com/u/JNelson)\
**Post date:** [February 2, 2018, 6:05pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/8 "2018-02-02T18:05:34Z")

</div>

Never mind … I figured it out. Thanks for your suggestions.

---

<div class="post-metadata">

**Author:** ![bfuson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bfuson/32/4597_2.png) [@bfuson](https://forum.inductiveautomation.com/u/bfuson)\
**Post date:** [February 2, 2018, 6:33pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/9 "2018-02-02T18:33:36Z")

</div>

EDIT: DON’T DO THIS. Use system.gui.createPopupMenu(). Unless you need to construct a menu with arbitrarily complex items.

Sure. Don’t say I didn’t warn you though: it’s hacky.

There are 2 templates needed (you could optionally add more to achieve the radio button/checkbox functionality)

1. **menubar\_item**  
  
A 200x18 template with a custom string parameter. The template contains only a label that fills the entire space, and has its text property bound to the templates string parameter. I implemented event scripts for mouseEntered and mouseExited, which merely set the event.source.background color to reflect if the option is highlighted or not.

2. **menubar\_separator**  
  
A 200x4 template with a grey line, that’s all.

  
To implement the above templates in a usable menu, you need a label and a template canvas. The label will act as the initial button (similar to the 'Project' menu item in the Designer), while the template canvas instantiates and formats the templates outlined above as an actual menu. I implemented both of these in another template, \*\*menubar\*\*, just for demonstration.\* 

The menubar template has a boolean custom parameter: menuOpened, which gets set when the user clicks the ‘Menu’ label and unset when they click off of it. menuOpened gets bound to the template canvases ‘visible’ property so it won’t show the menu unless they click the label. In the template canvas customizer you add the menu items along with seperators, and configure the parameters. Their position is determined by setting the Positioning to ‘Layout Positioning’: ‘cell 0 rowIndex’. Here’s a screenshot:

 ![](https://us1.discourse-cdn.com/inductiveautomation/original/2X/b/bf83400f0f69cf97c8f016d34c6d2d40b6e8d020.png)

  
Parametrizing the mouseClicked events of the menuItems is an exercise left for the masochistic reader. I'd be interested to see how you implement them.  
\_\*You'd probably just want to put the label and template canvas on the actual page and configure your menu as needed, otherwise you'd need to abstract the menuitem text parameters and generate the template canvas 'templates' dataset, which is a little more involved.\_

---

<div class="post-metadata">

**Author:** ![bfuson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bfuson/32/4597_2.png) [@bfuson](https://forum.inductiveautomation.com/u/bfuson)\
**Post date:** [February 2, 2018, 6:35pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/10 "2018-02-02T18:35:44Z")

</div>

Whoops, just saw your response. For future users you should report back with any improvements/further developments you come up with. 🙂👍

---

<div class="post-metadata">

**Author:** ![JNelson](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@JNelson](https://forum.inductiveautomation.com/u/JNelson)\
**Post date:** [February 2, 2018, 6:47pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/11 "2018-02-02T18:47:29Z")

</div>

Well I should say, “I _kind of_ figured it out…”  
I tried using system.gui.createPopupMenu which only seems to work with a right click. Is there a way to use/trigger that function with a left click?

I assigned the following script to the mouseReleased event of a label. (I would prefer that it worked with the actionPerformed event of a button).

from javax.swing import JMenuItem  
def item1(event):  
system.gui.messageBox(“You chose item 1”)  
def item2(event):  
system.gui.messageBox(“You chose item 2”)  
def item3(event):  
system.gui.messageBox(“You chose item 3”)

menu = system.gui.createPopupMenu([],[])  
menuitem1 = JMenuItem(“Item 1”,actionPerformed=item1)  
menuitem2 = JMenuItem(“Item 2”,actionPerformed=item2)  
menuitem3 = JMenuItem(“Item 3”,actionPerformed=item3)  
menu.add(menuitem1)  
menu.addSeparator()  
menu.add(menuitem2)  
menu.add(menuitem3)  
menu.show(event)

---

<div class="post-metadata">

**Author:** ![JNelson](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@JNelson](https://forum.inductiveautomation.com/u/JNelson)\
**Post date:** [February 2, 2018, 7:10pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/12 "2018-02-02T19:10:58Z")

</div>

Trying to find a way to trigger the mouseReleased event of a label through a script…

Then, I could get the actionPerformed event of a button to do the dirty work.

---

<div class="post-metadata">

**Author:** ![bfuson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bfuson/32/4597_2.png) [@bfuson](https://forum.inductiveautomation.com/u/bfuson)\
**Post date:** [February 2, 2018, 7:28pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/13 "2018-02-02T19:28:24Z")

</div>

TIL createPopupMenu is a thing. Can’t believe I haven’t needed that before, much more elegant than template abuse. But it’s never a bad time to show off the Turing-completeness of the template canvas 😉

I was able to implement your script with minor modifications on a buttons actionPerformed event:

https://i.imgur.com/yXTesCq.gifv?twitter#t

```auto
def item1(event):
	system.gui.messageBox("You chose item 1")
def item2(event):
	system.gui.messageBox("You chose item 2")
def item3(event):
	system.gui.messageBox("You chose item 3")

from javax.swing import JMenuItem

menu = system.gui.createPopupMenu([],[])
menuitem1 = JMenuItem("Item 1",actionPerformed=item1)
menuitem2 = JMenuItem("Item 2",actionPerformed=item2)
menuitem3 = JMenuItem("Item 3",actionPerformed=item3)
menu.add(menuitem1)
menu.addSeparator()
menu.add(menuitem2)
menu.add(menuitem3)
menu.show(event.source, 0, event.source.height)
```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [February 2, 2018, 7:32pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/14 "2018-02-02T19:32:30Z")

</div>

> [@bfuson](#):
>
> I was able to implement your script with minor modifications on a buttons actionPerformed event:

So, move the button to the right and restyle it to show just the "down arrow" of a dropdown. Place a label where the button was and style it to look like a text entry field. Then use the _label_ as the relative location for showing the menu.

---

<div class="post-metadata">

**Author:** ![JNelson](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@JNelson](https://forum.inductiveautomation.com/u/JNelson)\
**Post date:** [February 2, 2018, 7:41pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/15 "2018-02-02T19:41:21Z")

</div>

I just found the solution too … if you supply menu.show(event) with coordinates like this:

menu.show(event, x, y)

then the script will work with the mouseClicked event (hence, a left-click will run the script)  
Thanks to both bfuson and pturmel for your help.

---

<div class="post-metadata">

**Author:** ![Kyle\_Chase](https://avatars.discourse-cdn.com/v4/letter/k/9de0a6/32.png) [@Kyle\_Chase](https://forum.inductiveautomation.com/u/Kyle_Chase)\
**Post date:** [February 2, 2018, 8:14pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/16 "2018-02-02T20:14:06Z")

</div>

You don’t necessarily need to construct the menu like that. Using system.gui.createPopup, you can do this:

```auto
def item1(event):
	system.gui.messageBox("You chose item 1")
def item2(event):
	system.gui.messageBox("You chose item 2")
def item3(event):
	system.gui.messageBox("You chose item 3")
itemNames = ["item1","item2","","item3"]
itemFuncs = [item1,item2,None,item3]
menu = system.gui.createPopupMenu(itemNames,itemFuncs)
menu.show(event,event.x,event.y)

```

Placing None for the function works.

---

<div class="post-metadata">

**Author:** ![JNelson](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@JNelson](https://forum.inductiveautomation.com/u/JNelson)\
**Post date:** [February 2, 2018, 8:19pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/17 "2018-02-02T20:19:55Z")

</div>

Nice!  
I was looking for a way to do that too.

---

<div class="post-metadata">

**Author:** ![c.day](https://avatars.discourse-cdn.com/v4/letter/c/ea666f/32.png) [@c.day](https://forum.inductiveautomation.com/u/c.day)\
**Post date:** [February 6, 2018, 10:29pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/18 "2018-02-06T22:29:03Z")

</div>

Is there a way to pass arguments to these functions?

---

<div class="post-metadata">

**Author:** ![bfuson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bfuson/32/4597_2.png) [@bfuson](https://forum.inductiveautomation.com/u/bfuson)\
**Post date:** [February 6, 2018, 11:21pm UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/19 "2018-02-06T23:21:17Z")

</div>

I poked around a bit and found you can wrap the given event in a class that JPopupMenu.show() expects (something that inherits java.awt.event.ComponentEvent) along with whatever your custom data is.

Something like:

```auto
from java.awt.event import ComponentEvent

class EventWrapper(ComponentEvent):
	def __init__ (self, event):
		ComponentEvent. __init__ (self, event.getComponent(), event.getID())
		self.custom_parameter = ""

def item1(event):
	system.gui.messageBox("You chose item 1: " + wrapper.custom_parameter)
def item2(event):
	system.gui.messageBox("You chose item 2")
def item3(event):
	system.gui.messageBox("You chose item 3")
	
wrapper = EventWrapper(event)
wrapper.custom_parameter = "I'm a custom event parameter!"
	
itemNames = ["item1","item2","","item3"]
itemFuncs = [item1,item2,None,item3]
menu = system.gui.createPopupMenu(itemNames,itemFuncs)
menu.show(wrapper,event.x,event.y)

```

I suspect there’s a better or more specific way.

---

<div class="post-metadata">

**Author:** ![c.day](https://avatars.discourse-cdn.com/v4/letter/c/ea666f/32.png) [@c.day](https://forum.inductiveautomation.com/u/c.day)\
**Post date:** [February 7, 2018, 12:02am UTC](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851/20 "2018-02-07T00:02:33Z")

</div>

I meant to ask about having each menu option call the same function, but with different parameters. Something like this nonfunctional example code:

```auto
	def setHOA(event, value):
		system.tag.write("deviceHOA", value)
	
	names = ["Auto", None, "Off", "Hand"]
	functions = [setHOA(1), None, setHOA(0), setHOA(2)]
	menu = system.gui.createPopupMenu(names, functions)
	menu.show(event, event.x, event.y)

```

If I want to keep the code approachable, I’m guessing that it would probably be best for me to stick to defining three separate functions.

[Next page](https://forum.inductiveautomation.com/t/dropdown-list-separator/16851.md?page=2)
