1

I have list of objects, that I would like to render using Play Framework templates.

@(cats: List[Category])

@category(cat: Category) = {
    <td><button class="btn btn-info">@cat.name</button></td>
}

<div class="modal-body">
    <table class="table">
        <tbody>
            @cats.map { case cat =>
                @category(cat)
            }
        </tbody>
    </table>
</div>

So if I will have 9 elements in the list, they all will be in a single row.

What I want to have is a row with maximum of 3 elements. So it'll be like:

A B C 
D E F 
G H I

I thought I can zip my list with index list and set every third element as a new row. But I'm not sure how to do it.

Ideas?

Thanks.

psisoyev
  • 2,118
  • 1
  • 25
  • 35

2 Answers2

2

You can group the list using grouped, it will return a list of lists:

scala> List(1,2,3,4,5,6).grouped(3).toList
res13: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6))

In your case should be like this:

@(cats: List[String])

@category(groupedCats: List[String]) = {
    @groupedCats.map { cat =>
        <td><button class="btn btn-info">@cat</button></td>
    }
}

<div class="modal-body">
  <table class="table">
    <tbody>
      @cats.grouped(3).toList.map { grouped =>
        <tr>@category(grouped)</tr>
      }
    </tbody>
  </table>
</div>

In this way you pass to the @category a list of 3 elements which is aready wrapped in a td tag.

Ende Neu
  • 15,581
  • 5
  • 57
  • 68
1

Of course you can zipWithIndex and you don't need to group it, use module comparison instead:

<table>
  <tr>
    @for((cat, index) <- cats.zipWithIndex) {
        <td>@cat</td>
        @if((index+1) % 3 == 0){</tr><tr>}  @* Close old row if has 3 elements and open new *@
    }
  </tr>
</table>
Community
  • 1
  • 1
biesior
  • 55,576
  • 10
  • 125
  • 182