# Power Table with three dropdowns

**URL:** <https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874>\
**Category:** Ignition\
**Tags:** ignition79\
**Created:** [April 12, 2020, 4:36pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874 "2020-04-12T16:36:50Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 12, 2020, 4:36pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/1 "2020-04-12T16:36:50Z")

</div>

In the Power table is it possible to have ONLY, for example, THREE dropdowns in the column?  
Like in this example from somewhere else, not Ignition…

 ![table_with_three_dropdowns](https://us1.discourse-cdn.com/inductiveautomation/original/2X/c/c2e6558a911c4c6a84255a1371b534b6acaf2653.png)  
I can create dropdowns in the configureEditor, but only for the entire column.  
What I need is the dropdowns only in few rows in that column…?

---

<div class="post-metadata">

**Author:** ![DaveD24](https://avatars.discourse-cdn.com/v4/letter/d/8edcca/32.png) [@DaveD24](https://forum.inductiveautomation.com/u/DaveD24)\
**Post date:** [April 12, 2020, 8:05pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/2 "2020-04-12T20:05:22Z")

</div>

On occasions when I have needed functionality outside of that available in the table component, I have used a template repeater, you can take the drop-down options from either the driving dataset or a binding within the row template, to help keep the headers in alignment with the table columns I find it useful to create just one row template which displays as a header or table row depending on its index.

---

<div class="post-metadata">

**Author:** ![DavidWisely](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/davidwisely/32/10482_2.png) [@DavidWisely](https://forum.inductiveautomation.com/u/DavidWisely)\
**Post date:** [April 13, 2020, 7:31am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/3 "2020-04-13T07:31:40Z")

</div>

You can do this using the Extension Function: configureCell.  
Evaluate the conditions required to display the dropdown, then create the dropdown component and return it in the dictionary.

something like this:

> [@Power Table configureCell - DropDown List](http://forum.inductiveautomation.com/t/power-table-configurecell-dropdown-list/10265):
>
> Hello, I am trying to use the configureCell Extension Function in the Power Table to look at the value of one column and build a drop-down of relevant items in another column based on the first value for each row. Taking baby steps here as I haven’t ever really gotten into the java swing stuff. I can’t even get the combo box to render correctly and was hoping the fine folks on the forum could point me in the right direction. The following does put a combo box into my Value column with either…

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 13, 2020, 7:38am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/4 "2020-04-13T07:38:07Z")

</div>

That is exactly what I have in mind, but it doesn’t work in configureCell, only in configureEditor.  
But in configureEditor you don’t have rowIndex only cellIndex and cellName. So you can’t ‘evaluate’ in which row I want dropdown…

---

<div class="post-metadata">

**Author:** ![DavidWisely](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/davidwisely/32/10482_2.png) [@DavidWisely](https://forum.inductiveautomation.com/u/DavidWisely)\
**Post date:** [April 13, 2020, 8:33am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/5 "2020-04-13T08:33:04Z")

</div>

Oh yes, I see the problem.

You could create a custom editor.  
Paste this into the configureEditor and adjust as needed:

```auto
	from javax.swing import AbstractCellEditor,JComboBox, JTextField
	from javax.swing.table import TableCellEditor

	class myTableCellEditor(TableCellEditor, AbstractCellEditor):	
	
		def __init__ (self, tableComponent):
			self.table= tableComponent
			self.editor = None
			
		
		def getTableCellEditorComponent(self, table, value, isSelected, rowIndex, vColIndex):	
			
			if rowIndex in [23, 25, 26]:
				self.editor = JComboBox(["Line 1", "Line 2", "Line 3"])
			else:
				self.editor = JTextField()
	
			return self.editor
		
		def getCellEditorValue(self):
			if type(self.editor) is JComboBox:
				newValue = self.editor.getSelectedItem() 
			else:
				newValue = self.editor.getText()
		
			return newValue
			
	if colName == "Vrednost":
		m = myTableCellEditor(self)
		return {"editor":m}

```

I got the idea from here:

> [@Dynamic drop down values in table](http://forum.inductiveautomation.com/t/dynamic-drop-down-values-in-table/12354):
>
> Create a power table with test data and paste the following into the configureEditor extension function. Make the String Column editable. [code] from javax.swing import AbstractCellEditor,JComboBox from javax.swing.table import TableCellEditor class myTableCellEditor(TableCellEditor,AbstractCellEditor): def \_\_init\_\_(self, tableComponent): self.table= tableComponent self.cbValues = None def getTableCellEditorComponent(self, table, value, isSelected, rowIndex, vColIndex): # Conten…

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 13, 2020, 8:55am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/6 "2020-04-13T08:55:45Z")

</div>

Thank you. This now works… somehow…  
This last column (vrednost) is integer type. And in the db field there can be values 0, 1, or 2.  
What I need is in the dropdown to be text like OFF for 0, Hand for 1, AUTO for 2.  
And when the user selects for example ‘HAND’, the number one (1) must be writen to the field.

---

<div class="post-metadata">

**Author:** ![DavidWisely](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/davidwisely/32/10482_2.png) [@DavidWisely](https://forum.inductiveautomation.com/u/DavidWisely)\
**Post date:** [April 13, 2020, 9:49am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/7 "2020-04-13T09:49:55Z")

</div>

Ok, here I’ve added the options and a few comments for you:

```python
	from javax.swing import AbstractCellEditor,JComboBox, JTextField
	from javax.swing.table import TableCellEditor

	class myTableCellEditor(TableCellEditor, AbstractCellEditor):	
	
		def __init__ (self, tableComponent):
			self.table= tableComponent
			self.editor = None
			# defind the options for the drop down
			self.options = {"OFF":0, "Hand":1, "Auto":2}
		
		def getTableCellEditorComponent(self, table, value, isSelected, rowIndex, vColIndex):	
			
			# work out if the row should show a combobox or text box.
			if rowIndex in range(10):
				# create a combo box with the options
				self.editor = JComboBox(self.options.keys())
			else:
				# create a text field for default editor
				self.editor = JTextField()
	
			return self.editor
		
		def getCellEditorValue(self):
			# is the editor a combobox?
			if type(self.editor) is JComboBox:
				# get the combobox value
				selectedValue = self.editor.getSelectedItem()
				# convert back to the options value
				newValue = self.options[selectedValue]
			else:
				# get the text field value
				newValue = self.editor.getText()
		
			return newValue
			
	if colName == "Vrednost":
		m = myTableCellEditor(self)
		return {"editor":m}

```

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 13, 2020, 10:03am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/8 "2020-04-13T10:03:23Z")

</div>

Great. Thank you. 🙇‍♂️👍  
That is exactly what I need.  
I see you’re good with this. Can you please help me with another thing:  
The dropdown is now showing only when you click on the cell.  
Is it possible to show the dropdown all the time?

---

<div class="post-metadata">

**Author:** ![DavidWisely](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/davidwisely/32/10482_2.png) [@DavidWisely](https://forum.inductiveautomation.com/u/DavidWisely)\
**Post date:** [April 13, 2020, 11:04am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/9 "2020-04-13T11:04:08Z")

</div>

Sure, but it’s a bit of a hack.

First you need to update the getTableCellEditorComponent so the options are written explicitly. This ensures they are in the correct order. And set the selected index in the combobox.

```auto
def getTableCellEditorComponent(self, table, value, isSelected, rowIndex, vColIndex):	
			
			# work out if the row should show a combobox or text box.
			if rowIndex in [0,1,4,5]:
				# create a combo box with the options
				self.editor = JComboBox(["OFF", "Hand", "Auto"])
				self.editor.setSelectedIndex(value)
			else:
				# create a text field for default editor
				self.editor = JTextField()
	
			return self.editor

```

Then you need to add something like this to configureCell:

```auto
	from javax.swing import JComboBox

	data = {}

	if colName == 'Vrednost':
		if rowIndex in [0,1,4,5]:
			options = {0:"OFF", 1:"Hand", 2:"Auto"}
		
			if value in options:
				cb = JComboBox(["OFF", "Hand", "Auto"])
				cb.setSelectedIndex(value)
				data['renderer'] = cb 
	
	return data

```

This will create a combobox to display in the table, and a second combobox for editing. You need to make sure they are configured identically and then they will just look like one to the user.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [April 13, 2020, 1:39pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/10 "2020-04-13T13:39:46Z")

</div>

Kudos for some excellent Swing hacking, David!

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 13, 2020, 3:30pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/11 "2020-04-13T15:30:00Z")

</div>

That’s wonderful. Thank you very much. 👍  
Now I have a ‘tiny’ problem: when selecting the value in the dropdown and the dropdown closes, the table ‘onCellEdited’ event won’t fire, unless you click on another field in the table.  
If you click outside of the table or on another component, it wouldn’t fire either.  
Is that solvable?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [April 13, 2020, 3:32pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/12 "2020-04-13T15:32:19Z")

</div>

Try `self.putClientProperty("terminateEditOnFocusLost", True)` in `initialize`

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 13, 2020, 3:36pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/13 "2020-04-13T15:36:31Z")

</div>

I tried… nothing.  
Unless you click to another field in the table, it won’t fire

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [April 13, 2020, 3:37pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/14 "2020-04-13T15:37:49Z")

</div>

Try `self.table.putClientProperty`, it might need to be on the inner JideTable.

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 13, 2020, 3:47pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/15 "2020-04-13T15:47:57Z")

</div>

Yes, now it works when you click on another component.  
But not when the dropdown closes.  
And I would really need it after the dropdown close… Because I have the db update in the ‘onCellEdited’ event and I would like to update it immediately, like when you press enter on another field in the table…  
Is it even possible?

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 15, 2020, 4:57pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/16 "2020-04-15T16:57:34Z")

</div>

Bump…🚪

---

<div class="post-metadata">

**Author:** ![DavidWisely](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/davidwisely/32/10482_2.png) [@DavidWisely](https://forum.inductiveautomation.com/u/DavidWisely)\
**Post date:** [April 15, 2020, 11:30pm UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/17 "2020-04-15T23:30:05Z")

</div>

OK I’ve added an ItemListener to the Combobox to get the item changed event as soon as it’s changed:

In configureEditor use this:

```auto
	from javax.swing import AbstractCellEditor,JComboBox, JTextField
	from javax.swing.table import TableCellEditor
	from java.awt.event import ItemListener, ItemEvent
	
	# used to listen to item change events in the combobox
	class MyItemListener(ItemListener):
		
		# Constructor
		def __init__ (self, table, value, rowIndex, colIndex):
			self.table = table
			self.rowIndex = rowIndex
			self.colIndex = colIndex
			self.value = value
			self.options = {"OFF":0, "Hand":1, "Auto":2}
		
		# this is fired when the combobox changes
		def itemStateChanged(self, event):
			if (event.getStateChange() == ItemEvent.SELECTED):
				item = event.getItem()

				# convert the new value to the index. E.g. OFF -> 0
				if item in self.options:
					newValue = self.options[item]
					
					# create a new dataset with the updated value					
					newDS = system.dataset.setValue(self.table.data, self.rowIndex, self.colIndex, newValue)
					
					# write back to the source property
					# update this to whereever your master data is
					self.table.parent.DS = newDS
			

	class myTableCellEditor(TableCellEditor, AbstractCellEditor):	
	
		def __init__ (self, tableComponent):
			self.table= tableComponent
			self.editor = None
			# defind the options for the drop down
			self.options = {"OFF":0, "Hand":1, "Auto":2}
		
		def getTableCellEditorComponent(self, table, value, isSelected, rowIndex, colIndex):

			# work out if the row should show a combobox or text box.
			if rowIndex in [0,1,2,3]:
				# create a combo box with the options
				self.editor = JComboBox(self.options.keys())
				self.editor.setSelectedIndex(value)
				# add an Item changed listener
				self.editor.addItemListener(MyItemListener(self.table, value, rowIndex, colIndex))
			else:
				# create a text field for default editor
				self.editor = JTextField()
	
			return self.editor
		
		def getCellEditorValue(self):

			# is the editor a combobox?
			if type(self.editor) is JComboBox:
				# get the combobox value
				selectedValue = self.editor.getSelectedItem()
				# convert back to the options value
				newValue = self.options[selectedValue]
			else:
				# get the text field value
				newValue = self.editor.getText()
		
			return newValue
		

			
	if colName == "Vrednost":
		m = myTableCellEditor(self)
		return {"editor":m}

```

Keep this the same in configureCell:

```auto
	from javax.swing import JComboBox
	
	data = {}

	if colName == 'Vrednost':
		if rowIndex in [0,1,2,3]:
			options = {0:"OFF", 1:"Hand", 2:"Auto"}
		
			if value in options:
				cb = JComboBox(["OFF", "Hand", "Auto"])
				cb.setSelectedIndex(value)
				data['renderer'] = cb 
	
	return data

```

Now that the item is being updated in the configureEditor function, you need to prevent it from trying to update twice, so use this in the onCellEdited:

```auto
	if colName == 'Vrednost':
		if rowIndex not in [0,1,2,3]:
			self.parent.DS = system.dataset.setValue(self.data, rowIndex, colIndex, newValue)

```

I’ve tested it and it works pretty well for me.  
Good luck.

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 16, 2020, 6:31am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/18 "2020-04-16T06:31:10Z")

</div>

```auto
					# write back to the source property
					# update this to whereever your master data is
					self.table.parent.DS = newDS

```

I’m appreciating your effort to help and I’m very, very grateful.  
I put your code in mine but I’m getting an error  
`AttributeError: 'com.inductiveautomation.factorypmi.application.com' object has no attribute 'DS'`  
at this quoted line…  
I don’t understand what you mean by ‘ **update this to wherever your master data is** ’…

---

<div class="post-metadata">

**Author:** ![DavidWisely](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/davidwisely/32/10482_2.png) [@DavidWisely](https://forum.inductiveautomation.com/u/DavidWisely)\
**Post date:** [April 16, 2020, 8:27am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/19 "2020-04-16T08:27:02Z")

</div>

if you change it to:

```auto
self.data = newDS

```

it will update the dataset on the table itself.

But if you are wanting to update a database, you will need additional code. Basically you need to copy the code that you use in the onCellEdited.  
The ideas is that this updates the data source early, and then the onCellEdited code is not needed.

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [April 17, 2020, 6:24am UTC](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874/20 "2020-04-17T06:24:24Z")

</div>

Yes, I figured out that over time, playing with various bits of code…

Thank you again for your help. Greatly appreciated.

There is a barrel of beer waiting if you ever set foot in Slovenia… 🍻 🇸🇮

[Next page](https://forum.inductiveautomation.com/t/power-table-with-three-dropdowns/33874.md?page=2)
