Developer forum

Forum » Templates » Razor grouping

Razor grouping

Jacob Storgaard Jensen
Reply

Hi guys,

I've tried to search the forums to find a way to group items, but with no luck... so here it goes:

I've got a bunch of Items (Paragraph items) which are employees at a company. I would like to group these by department, which is a field set on each item.

So what I would like as a result is something like this:

<h3>Department 1</h3>
<ul>
    <li>Employee 1</li>
    <li>Employee 3</li>
</ul>
<h3>Department 2</h3>
<ul>
    <li>Employee 4</li>
    <li>Employee 4</li>
    <li>Employee 6</li>
</ul>

Replies

 
Nicolai Høeg Pedersen
Reply

Hi Jacob

You can use OrderBy in Linq: http://developer.dynamicweb.com/forum/templates/razor-groups-orderby-with-linq.aspx

 
Jacob Storgaard Jensen
Reply

Hi Nicolai, this only orders them as far as I can see... How do I split them into seperate groups? (I know I might just be plain stupid here...)

@{
var groups = GetLoop("ItemPublisher:Items.List").OrderBy(g => g.GetString("ItemPublisher:Item.Afdeling")).ToList();
<ul>
    @foreach (var g in groups) {
        <li>
            @g.GetString("ItemPublisher:Item.Afdeling")<br/>
            @g.GetString("ItemPublisher:Item.Navn")
        </li>
    }
</ul>
}

 

Results in:

<ul>
		<li>
			1<br/>
			Jacob
		</li>
		<li>
			1<br/>
			Mads
		</li>
		<li>
			2<br/>
			Lars
		</li>
		<li>
			2<br/>
			Henry
		</li>
		<li>
			2<br/>
			Alf
		</li>
</ul>
 
Nicolai Høeg Pedersen
Reply

Then you can do something like this:

var currentDepartment = "";
 @foreach (var g in groups) {
    if(currentDepartment!=g.GetString("ItemPublisher:Item.Afdeling")){
        currentDepartment = g.GetString("ItemPublisher:Item.Afdeling");
        <li><h2>@g.GetString("ItemPublisher:Item.Afdeling")</h2></li>
    }
        <li>
            @g.GetString("ItemPublisher:Item.Afdeling")<br/>
            @g.GetString("ItemPublisher:Item.Navn")
        </li>
    }

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

You could also look into LINQ's GroupBy method which expect a lambda with the key to sort on: https://msdn.microsoft.com/en-us/library/vstudio/bb534304%28v=vs.100%29.aspx

That givvs you an IEnumerable<IGrouping<TKey, TElement>> that in turn has a Key (that you used to group on) as well as an enumerable that you can loop over.

Not sure if this works directly with the template objects. I think it does; but if it doesn't, you could loop over your template data and for each item create a temporary object that you store in a list that you can then group  by on.

Hope this helps,

Imar

 
Jacob Storgaard Jensen
Reply
@{
var groups = GetLoop("ItemPublisher:Items.List").OrderBy(g => g.GetString("ItemPublisher:Item.Afdeling")).ToList();
<ul>
    var currentDepartment = "";
    @foreach (var g in groups) {
        
        if(currentDepartment!=g.GetString("ItemPublisher:Item.Afdeling")){
            currentDepartment = g.GetString("ItemPublisher:Item.Afdeling");
            <li><h2>@g.GetString("ItemPublisher:Item.Afdeling")</h2></li>
        }
            <li>
                @g.GetString("ItemPublisher:Item.Afdeling")<br/>
                @g.GetString("ItemPublisher:Item.Navn")
            </li>
        
       }
</ul>
}

this throws this error:

The name 'currentDepartment' does not exist in the current context
 
Jacob Storgaard Jensen
Reply

Hi Imar,

I've stumbeled upon this too, but my c#, razor, linq capabilities are so damn limited. :-(

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

For that error message, try replacing these two lines:

var currentDepartment = "";
@foreach (var g in groups) {
 

with:

@ {
  var currentDepartment = "";
  foreach (var g in groups) {
 

and add an additional } at the end of the loop to close the code block. Does that help?

Imar

var currentDepartment = ""; @foreach (var g in groups) { - See more at: http://developer.dynamicweb.com/forum/templates.aspx?ThreadID=41758#sthash.Z6gI05Qe.dpuf
 
Jacob Storgaard Jensen
Reply

Thanks Imar, that removed the error :-)

Now my final challenge is to have each department in it's own UL.

Found some examples here: http://www.codeproject.com/Articles/35667/How-to-Use-LINQ-GroupBy

But I can't figure out to make anything fit into a ItemPublisher context...

 
Gaetan Di Caro
Reply

Hi Jacob,

I have used this several times. Try this :

@{
    var departments = GetLoop("ItemPublisher:Items.List").GroupBy(x => x.GetString("ItemPublisher:Item.Afdeling"));

    foreach (var dpt in departments)
    {
        <h3>@dpt.Key</h3>
        <ul>
                @foreach (var employee in dpt)
                {
                    <li>@employee.GetString("ItemPublisher:Item.Navn")</li>
                }
        </ul>
    }
}

 
Jacob Storgaard Jensen
Reply

Exactly what I need!

So dead simple that I ought to have been able to do it!

Thanks!

 

You must be logged in to post in the forum