Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

DataObjectManager Module /

Discuss the DataObjectManager module, and the related ImageGallery module.

Moderators: martimiz, UncleCheese, Sean, Ed, biapar, Willr, Ingo, swaiba

Loop through many to many relationship in templates


Go to End


5 Posts   3563 Views

Avatar
updog

Community Member, 13 Posts

10 January 2011 at 1:59pm

I have a product comparison chart which is built as a html table and has the services along the top and the features down the left hand side. There is a tick placed in the cell where the two meet if the feature is applicable to the service otherwise it is blank.

I have already created the data objects (Services and Features) and built the backend using DataObject Manager. There is a many to many relationship between these two objects.

What i want to know is how i can loop through the features and then tick the correct boxes. Below is some sample code.

<% control Features %>
<tr>
<td">$Title</td>
// loop over global services here and inside each iteration, loop through the feature services array and check to see if id's match
<td class="normal-td "></td>
</tr>
<% end_control %>

Avatar
UncleCheese

Forum Moderator, 4102 Posts

10 January 2011 at 2:54pm

Ahh.. yeah, that's a tricky one. Let's see..

public function AllServices() {
return DataObject::get("Service");
}

public function AllFeatures() {
	$services = $this->AllServices();
	$set = new DataObjectSet();
	foreach(DataObject::get("Feature") as $feature) {
		$data = array(
			'Label' => $feature->Title
		);
		$feature_row = new DataObjectSet();
		foreach($services as $service) {
			$feature_row->push(new ArrayData(
				'Checked' => in_array($feature->ID, $service->Features()->column());
			));
		}
		$data['Features'] = $feature_row;
		$set->push(new ArrayData($data));
	}
}

<thead>
<tr>
<% control Services %>
<th>$Title</th>
<% end_control %>
</tr>
</thead>
<tbody>
<% control AllFeatures %>
<tr>
<td>$Label</td>
<% control Features %>
<td><% if Checked %>YES<% else %>&nbsp;<% end_if %></td>
<% end_control %>
</tr>
<% end_control %>
</tbody>

Can't promise it's free of errors, but that should get you pushed in the right direction.

---------------
Silverstripe tips, tutorials, screencasts, and more. http://www.leftandmain.com

Avatar
updog

Community Member, 13 Posts

10 January 2011 at 2:58pm

I see.

I was thinking of going down the path of calling a method on the page class and just generating the html to pass back to the template. Either way, it requires some sort of intermediate php development and can't be achieved within the template alone.

Avatar
UncleCheese

Forum Moderator, 4102 Posts

10 January 2011 at 3:24pm

Yeah, templates aren't smart enough to do all of that logic on their own. That's what controllers are for.

And controllers are NOT used to generate html. That's never the answer.

.. unless your site is a tribute to 2002. :)

---------------
Silverstripe tips, tutorials, screencasts, and more. http://www.leftandmain.com

Avatar
Nobrainer Web

Community Member, 138 Posts

29 August 2013 at 1:51am

Hi UC, thank you for this post (hope you still have it monitored) - it's so close to what i need - actually it does what i need except for one thing:
I'm using your Simple DataObject Translating (http://www.leftandmain.com/silverstripe-tips/2012/04/03/translatabledataobject-insanely-simple-translation/). When i try to do $T(Name) (using the $T function to translate, it does not generate any output.

I guess it has to do with the values beeing assigned as and array - but how can i fix it?