# Template Repeater with a check box in the template

**URL:** <https://forum.inductiveautomation.com/t/template-repeater-with-a-check-box-in-the-template/112692>\
**Category:** Ignition\
**Tags:** ignition81, vision\
**Created:** [December 9, 2025, 8:06am UTC](https://forum.inductiveautomation.com/t/template-repeater-with-a-check-box-in-the-template/112692 "2025-12-09T08:06:22Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lion\_Sun](https://avatars.discourse-cdn.com/v4/letter/l/3ab097/32.png) [@Lion\_Sun](https://forum.inductiveautomation.com/u/Lion_Sun)\
**Post date:** [December 9, 2025, 8:06am UTC](https://forum.inductiveautomation.com/t/template-repeater-with-a-check-box-in-the-template/112692/1 "2025-12-09T08:06:22Z")

</div>

Firstly, I make a vision template, with only one check box in it. and defined two Template Parameters which bidirectional binding to the Text property and Selected property of this check box.

Then I make a template repeater in a vision window, for this template repeater, I change the template path to above template, change repeat behavior to Dataset mode; binding the Template Parameters to a dataset which is a customer property of that window’s root container. This dataset is with only two columns, one column is the number to indicate the check box text, and the other column to indicate the check box is selected or not. I set them all unselected at beginning, Then in preview mode, I selected some of the check box, I thought the dataset will also changed, but they are not changing.

Seems the dataset can only be passed in a single direction from template repeater to template， when it is changed in template, it will not change back to template repeater.

I can only use script to access the inner template to get the information I want.

```python
templateRepeater = event.source.parent.getComponent('Template Repeater')
templates = templateRepeater.getLoadedTemplates()

for template in templates:
    print 'text is ',template.getComponent('CheckBox').text, '; selected is ', template.getComponent('CheckBox').selected

```

```python
`

```

I’m not sure if there is any other method to pass the information back from template back to template repeater.

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

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

---

<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:** [December 9, 2025, 5:29pm UTC](https://forum.inductiveautomation.com/t/template-repeater-with-a-check-box-in-the-template/112692/2 "2025-12-09T17:29:37Z")

</div>

> [@Lion\_Sun](#):
>
> Seems the dataset can only be passed in a single direction from template repeater to template， when it is changed in template, it will not change back to template repeater.

Correct.

> [@Lion\_Sun](#):
>
> I’m not sure if there is any other method to pass the information back from template back to template repeater.

You can use scripting to 'reference' the parent component (the template repeater) and/or the window above it, either by chaining successive parent calls or importing `SwingUtilities`. There are some examples on the forum if you search for 'template access parent' or similar.

---

<div class="post-metadata">

**Author:** ![Lion\_Sun](https://avatars.discourse-cdn.com/v4/letter/l/3ab097/32.png) [@Lion\_Sun](https://forum.inductiveautomation.com/u/Lion_Sun)\
**Post date:** [December 10, 2025, 3:29am UTC](https://forum.inductiveautomation.com/t/template-repeater-with-a-check-box-in-the-template/112692/3 "2025-12-10T03:29:38Z")

</div>

Thank you. I tested that I can access back to the template repeater, or the windows’ root container by repeat .parent several times.

```python
print '\nlevel1:'
print event.source
print type(event.source)

print '\nlevel2:'
print event.source.parent
print type(event.source.parent)

print '\nlevel3:'
print event.source.parent.parent
print type(event.source.parent.parent)

print '\nlevel4:'
print event.source.parent.parent.parent
print type(event.source.parent.parent.parent)

print '\nlevel5:'
print event.source.parent.parent.parent.parent
print type(event.source.parent.parent.parent.parent)

print '\nlevel6:'
print event.source.parent.parent.parent.parent.parent
print type(event.source.parent.parent.parent.parent.parent)

print '\nlevel7:'
print event.source.parent.parent.parent.parent.parent.parent
print type(event.source.parent.parent.parent.parent.parent.parent)

print '\nlevel8:'
print event.source.parent.parent.parent.parent.parent.parent.parent
print type(event.source.parent.parent.parent.parent.parent.parent.parent)

```

And it prints out the details of the hierarchy. I can use it to access back to template repeater or root container.

```python
level1:
com.inductiveautomation.factorypmi.application.components.PMICheckBox[CheckBox,0,0,43x18,alignmentX=0.0,alignmentY=0.5,border=javax.swing.border.EmptyBorder@2fad08a2,flags=352,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=1]
<type 'com.inductiveautomation.factorypmi.application.components.PMICheckBox'>

level2:
Cavity Selector
<type 'com.inductiveautomation.factorypmi.application.components.template.VisionTemplate'>

level3:
com.inductiveautomation.factorypmi.application.components.TemplateRepeater$FlowVerticalView[,0,0,375x180,layout=com.inductiveautomation.ignition.client.util.gui.VerticalScrollingFlowLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@26657e3d,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
<type 'com.inductiveautomation.factorypmi.application.components.TemplateRepeater$FlowVerticalView'>

level4:
javax.swing.JViewport[,0,0,375x186,layout=javax.swing.ViewportLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=25165824,maximumSize=,minimumSize=,preferredSize=,isViewSizeSet=true,lastPaintPosition=java.awt.Point[x=0,y=0],scrollUnderway=false]
<type 'javax.swing.JViewport'>

level5:
com.jidesoft.swing.JideScrollPane[,0,0,375x186,layout=com.jidesoft.swing.JideScrollPaneLayout$UIResource,alignmentX=0.0,alignmentY=0.0,border=,flags=16777536,maximumSize=,minimumSize=,preferredSize=,columnHeader=,horizontalScrollBar=javax.swing.JScrollPane$ScrollBar[,0,0,375x0,hidden,layout=javax.swing.plaf.synth.SynthScrollBarUI,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@57905cca,flags=4194560,maximumSize=,minimumSize=,preferredSize=,blockIncrement=10,orientation=HORIZONTAL,unitIncrement=1],horizontalScrollBarPolicy=HORIZONTAL_SCROLLBAR_AS_NEEDED,lowerLeft=,lowerRight=,rowHeader=,upperLeft=,upperRight=,verticalScrollBar=javax.swing.JScrollPane$ScrollBar[,0,0,0x0,hidden,layout=javax.swing.plaf.synth.SynthScrollBarUI,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@5604662e,flags=4194560,maximumSize=,minimumSize=,preferredSize=,blockIncrement=10,orientation=VERTICAL,unitIncrement=1],verticalScrollBarPolicy=VERTICAL_SCROLLBAR_AS_NEEDED,viewport=javax.swing.JViewport[,0,0,375x186,layout=javax.swing.ViewportLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=25165824,maximumSize=,minimumSize=,preferredSize=,isViewSizeSet=true,lastPaintPosition=java.awt.Point[x=0,y=0],scrollUnderway=false],viewportBorder=javax.swing.plaf.synth.SynthScrollPaneUI$ViewportBorder@1d13024f]
<type 'com.jidesoft.swing.JideScrollPane'>

level6:
com.inductiveautomation.factorypmi.application.components.TemplateRepeater[Template Repeater,4,48,375x186,layout=com.inductiveautomation.ignition.client.util.gui.FillingLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
<type 'com.inductiveautomation.factorypmi.application.components.TemplateRepeater'>

level7:
Root Container
<type 'com.inductiveautomation.factorypmi.application.components.BasicContainer'>

level8:
javax.swing.JLayeredPane[null.layeredPane,0,0,384x297,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true]
<type 'javax.swing.JLayeredPane'>

```

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [December 10, 2025, 5:19am UTC](https://forum.inductiveautomation.com/t/template-repeater-with-a-check-box-in-the-template/112692/4 "2025-12-10T05:19:32Z")

</div>

> [@paul-griffith](#):
>
> importing `SwingUtilities`

I find this approach looks cleaner, and it will continue to work even if the internal template component gets moved around:

```python
from javax.swing import SwingUtilities
from com.inductiveautomation.factorypmi.application.components import TemplateRepeater

repeater = SwingUtilities.getAncestorOfClass(TemplateRepeater, event.source)

```

---

<div class="post-metadata">

**Author:** ![Lion\_Sun](https://avatars.discourse-cdn.com/v4/letter/l/3ab097/32.png) [@Lion\_Sun](https://forum.inductiveautomation.com/u/Lion_Sun)\
**Post date:** [December 10, 2025, 6:46am UTC](https://forum.inductiveautomation.com/t/template-repeater-with-a-check-box-in-the-template/112692/5 "2025-12-10T06:46:30Z")

</div>

Awesome! `SwingUtilities.getAncestorOfClass(Class c, Component comp)` is a good method to find the first parent instance of a specific class. I only need remember and import the correct class.

for my case, I want to get the Root Container (the parent of template repeater), I just need to change the second import.

```python
from javax.swing import SwingUtilities

from com.inductiveautomation.factorypmi.application.components import BasicContainer

rootContainer = SwingUtilities.getAncestorOfClass(BasicContainer, event.source)   

```

It also works well.

And use this method, it will not break the chain if the components move around.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [December 10, 2025, 6:50am UTC](https://forum.inductiveautomation.com/t/template-repeater-with-a-check-box-in-the-template/112692/6 "2025-12-10T06:50:22Z")

</div>

> [@Lion\_Sun](#):
>
> `BasicContainer`

If the source component is ever nested in a container, this script will not find the root container first. However, if the root container is all you need, the code is much simpler and doesn't require any imports:

```python
# Get the root container the event occured in from the parent window
rootContainer = system.gui.getParentWindow(event).rootContainer

```

---

<div class="post-metadata">

**Author:** ![Lion\_Sun](https://avatars.discourse-cdn.com/v4/letter/l/3ab097/32.png) [@Lion\_Sun](https://forum.inductiveautomation.com/u/Lion_Sun)\
**Post date:** [December 10, 2025, 7:12am UTC](https://forum.inductiveautomation.com/t/template-repeater-with-a-check-box-in-the-template/112692/7 "2025-12-10T07:12:57Z")

</div>

Yes, you are right. Your script provides another method for my use case.

Now I understand both:

1. How to access the internal instance of templates when I’m outside in a template repeater/ canvas / window
2. How to access the outside template repeater / canvas when I’m in a template instance
