0

I have a list of items that I iterate over as cards w/ thymeleaf:

<div th:each="show,iter : ${shows}" class="col-sm-6 col-xl-4 mb-5">
  <div class="card">
    ...
   </div
</div>

I want after every nth card to show an ad instead of the regular card but NOT skip the item in the list. I can't find a way to add the ad code as its own card without it skipping one of the items OR just messing up the UI.

My best thought is to add "dummy" items to the list itself, but that feels wrong.

Any ideas?

gunygoogoo
  • 641
  • 2
  • 7
  • 19
  • are the ads already in the list of shows? – riddle_me_this Dec 22 '19 at 14:16
  • Also, are you accessing the ads on the client-side only? If not, you can do the manipulation and unit test it all on the server-side, cache it, and simply add the list when you're done. This could be a better way depending on how your team and env are set up and your specific requirements. – riddle_me_this Dec 22 '19 at 14:45

1 Answers1

0

The main answer to this is that you want to do the manipulation on the server-side, NOT on the view. Then you can unit-test, cache, and simply display the results without a UI designer caring about any complicated code. All you're really doing is inserting the ad at every nth position and then displaying the full list, one-by-one.

If that is somehow not an option, you can do something like the following. Let's say you have:

    List<String> shows = new ArrayList<>(Arrays.asList("Game of Thrones",
            "Daniel Tiger's Neighborhood",
            "The Mandalorian",
            "Breaking Bad",
            "RugRats",
            "Big Bang Theory",
            "Knight Rider",
            "Quantum Leap",
            "Friends",
            "Gilligan's Island"));
    model.addAttribute("shows", shows);
    model.addAttribute("ad", "StackOverflow");
    model.addAttribute("cardsToDisplay", new ArrayList<>()); //ignore a capacity for simplicity for now

Then you can do:

    <th:block th:with="cardsToDisplay = ${cardsToDisplay}">
        <th:block th:each="show : ${shows}">
            <!-- add the first show and every 3 thereafter, add the ad -->
            <th:block th:if="${showStat.index % 2 == 0 && showStat.index != 0}">
                <th:block th:text="${cardsToDisplay.add(ad)}" th:remove="all"></th:block><!-- or however you are getting your ad -->
            </th:block>
            <th:block th:text="${cardsToDisplay.add(show)}" th:remove="all"></th:block>
        </th:block>
        <!-- display the manipulated list -->
        <div th:each="theCard : ${cardsToDisplay}" class="col-sm-6 col-xl-4 mb-5">
            <div th:text="${theCard}" class="card"></div>
        </div>
    </th:block>

Then your output would be:

Game of Thrones
Daniel Tiger's Neighborhood
StackOverflow
The Mandalorian
Breaking Bad
StackOverflow
RugRats
Big Bang Theory
StackOverflow
Knight Rider
Quantum Leap
StackOverflow
Friends
Gilligan's Island

Thymeleaf implicitly gives you this construct of showStat because we declare a variable called show. You need th:remove="all" to hide the output of the add operation.

Change the number 2 as needed to represent n.

You can alternatively do this work in Javascript, but doing so introduces another skill that someone on your team would maintain.

riddle_me_this
  • 8,575
  • 10
  • 55
  • 80