# Center and space items within template repeater based on number of templates within repeater

**URL:** <https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [December 6, 2024, 5:15pm UTC](https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537 "2024-12-06T17:15:22Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [December 6, 2024, 5:15pm UTC](https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537/1 "2024-12-06T17:15:22Z")

</div>

I am using a template repeater and I want to change the number of template instances within the repeater based on a tag. Is there a way to automatically center and space each template within the repeater? I see the horizontal gap parameter but outside of putting a binding on that property based on the number of templates I cant see a way to evenly space the templates within the repeater.

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [December 6, 2024, 6:26pm UTC](https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537/3 "2024-12-06T18:26:32Z")

</div>

Im using vision, any ideas on that?

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [December 6, 2024, 6:53pm UTC](https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537/4 "2024-12-06T18:53:52Z")

</div>

Sorry, I didn't notice the tag. I'll delete my answer.  
I don't know how to do it in Vision.

---

<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 6, 2024, 7:27pm UTC](https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537/5 "2024-12-06T19:27:02Z")

</div>

The template repeater doesn't really support this kind of customization.

The template canvas _sort of_ does, in that miglayout is inherently more flexible, though you'll need to know or determine ahead of time how many templates to put on each row. Once you've done that, you could use the `spanx` layout keyword, for one possibility, to make a template consume more than the fixed number of columns.

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [December 6, 2024, 7:56pm UTC](https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537/6 "2024-12-06T19:56:35Z")

</div>

Thanks for the suggestion though!

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [December 6, 2024, 7:57pm UTC](https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537/7 "2024-12-06T19:57:54Z")

</div>

Yes doesnt seem like it. If I had more time I would look into this, seems pretty cool.

---

<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 7, 2024, 11:46am UTC](https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537/8 "2024-12-07T11:46:26Z")

</div>

What kind of tag is this? Dataset?

My initial idea would be to take advantage of the absolute positioning option of the template canvas and simply script the positioning using a property change event.

**Example:**  
Take note of the parameters that are needed for rendering the specific template:

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

Position the template canvas in the window, right click on the canvas, and select **Customizers--\>Custom Properties** from the popup

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/9/298117950c73ad73dfb211438d4fec0e0b389e74.png)

Add a property called rawParameters:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/4/a45ab097d4b67b172bb203a636f4b7b2293bbeb1.png)

Bind the custom property to the parameters tag:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/4/043fc14abc3e0652999586a417b4f7b4fde14b78.png)

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

Right click on the template canvas again and select scripting:

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

Inside the component scripting window, select the propertyChange event handler:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/4/84dc4fa6964a4d076a4d6893f507743e9737bf76.png)

Develop a script that processes the data into a proper dataset for the templates property of the canvas and includes x coordinates that center as well as evenly space the templates:

```python
# When the raw parameters are updated,
# ...process them into proper template canvas parameters
if event.propertyName == 'rawParameters':
	
	# Assign the new parameters to a variable with human readable name
	rawParameters = event.newValue
	
	# Get the column headers from the template parameters for the new parameters dataset
	# [name, template, parameters, x, y, width, height, layout, z]
	headers = system.dataset.getColumnHeaders(event.source.templates)
	data = [] # Empty list for processed parameter row data
	
	# Assumes the templates will be square
	# Assumes a horizontal strip display where the template will take the full height of the canvas
	templateHeight = templateWidth = event.source.height
	
	# Calculate the total white space and divide it evenly between the sides and templates
	# Add 1 to the row count divisor, eliminates the possibility of dividing by zero
	# ...and acounts for the right side
	centeringValue = (event.source.width - (templateWidth * rawParameters.rowCount)) / (1 + rawParameters.rowCount)
	
	# Iterate through each row of the dataset and process the parameters
	for row in xrange(rawParameters.rowCount):
		motorNumber, status, speed = [rawParameters.getValueAt(row, column) for column in xrange(rawParameters.columnCount)]
		data.append(['Motor {}'.format(motorNumber), # Arbitrarily create an identifier for the specific template
			'TestTemplates/Motor', # The Vision template path for the template to be painted
			unicode({"motorNumber":motorNumber,"status":status,"speed":speed}), # Create a string that represents a dictionary of parameters
			centeringValue + (centeringValue * row) + (templateWidth * row), # The 1st side + all subseqent gaps and templates
			0, # Position the y coordinate at the very top of the canvas
			templateHeight,
			templateWidth,
			'n/a', # A custom layout is not needed for absolute positioning
			row]) # Arbitrarily assign the row index to the z parameter
	
	# Set the processed data to the templates dataset parameter of the canvas
	event.source.templates = system.dataset.toDataSet(headers, data)

```

**Result with two templates in the dataset tag** :  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/1/21ab1c98792a71b737b55c57d8767b9f0201b463.png)

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

**Result with three templates in the dataset tag** :

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/8/f8e14d78e92a4e602007d6cb84d83b6a147fda88.png)  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/6/1/615f13f006ab9b49ca35b82994c858aec7feab55.png)

**Result with only one template in the dataset tag** :  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/3/83cc6822c27e9ef6c89310995bb1ec60afcd86df.png)

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

**Edit:** Removed some overlooked debugging artifacts from the test script

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [December 11, 2024, 5:43pm UTC](https://forum.inductiveautomation.com/t/center-and-space-items-within-template-repeater-based-on-number-of-templates-within-repeater/99537/9 "2024-12-11T17:43:32Z")

</div>

Wow...looks like it would work! I'm sure I can use this in the future...thanks for the help!
