英文:
Best approach using a list in Thymeleaf adding to a Bootstrap accordion by a nested value
问题
以下是翻译好的部分:
Data getAllRoundsByUserId (sorry if it looks complicated, a round has a date, total, score (List of Score) and a course(name, record, par, List of Hole)
我有一个用户的飞盘高尔夫回合列表,我想要为每个球场显示一个手风琴,然后当您选择球场时,显示并可折叠该球场的所有回合。我可以使手风琴工作,但问题是每个得分都是一个手风琴。问题是,我是否应该有一个回合列表的列表,或者只显示的回合列表会起作用?
以下是我的数据(getAllRoundsByUserId),我的控制器以及带有rounds/{id}(id=userId)方法和我的HTML。
数据getAllRoundsByUserId(如果看起来很复杂,一个回合包括日期,总分和分数(Score列表),以及一个球场(名称、记录、差点和Hole列表)。
Controller method
@GetMapping("/rounds/{id}")
public String roundsHome(@PathVariable(value = "id") Long id,
Model model) {
List<Course> courses = courseService.getAllCourses();
List<Round> rounds = userService.getUserById(id).getRounds();
model.addAttribute("courses", courses);
model.addAttribute("rounds", rounds);
return "/discgolf/round/rounds";
}
html
<div class="container">
<div>
<a>Rounds Played</a>
</div>
<div id="accordion">
<div th:each="round : ${rounds}" class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
<div>
<label>Course: </label>
<label th:text="${round.course.name}"></label>
</div>
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<div class="d-flex flex-row">
<div class="p-3">
<label>Date: </label>
<label th:text="${#dates.format(round.roundDate, 'dd-MMM-yyyy')}"></label>
</div>
<div class="p-3">
<label>Score: </label>
<label th:text="${round.total - round.course.par}"></label>
</div>
</div>
<br>
<div>
<table id="courseInfo" class="table table-bordered w-auto">
<th:block th:each="course : ${round.course}">
<tr>
<th th:text="${'Hole'}"></th>
<th th:each="hole : ${course.holes}" th:text="${hole.number}"></th>
<th th:text="${'Total'}"></th>
</tr>
<tr>
<td th:text="${'Par'}"></td>
<td th:each="par : ${course.holes}" th:text="${par.par}"></td>
<td th:text="${course.par}"></td>
</tr>
<tr>
<td th:text="${'Score'}"></td>
<th:block th:each="score : ${round.scores}">
<td th:style="${score.score > score.holePar ? 'background-color: red' : (score.score < score.holePar ? 'background-color: blue' : 'background-color: #eee' )}" th:text="${score.score}"></td>
</th:block>
<td th:text="${round.total}"></td>
</tr>
</th:block>
</table>
<br>
<a th:href="@{/discgolf/deleteRound/{id}(id=${round.roundId})}" title="Remove Course" data-target="#deleteRoundModal" class="table-link danger" id="deleteRoundButton">
<span id="deleteRound" class="fa-stack">
<i class="fa fa-square fa-stack-2x"></i>
<i class="fa fa-trash-o fa-stack-1x fa-inverse" title="Delete this round"></i>
</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
英文:
I have a list of discgolf rounds for a user, to display them I want an accordion for each course, then as you select the course all rounds for that course are displayed and can be collapsed. I can get the accordion working but the problem is each score is its own accordion. Question should I have a list of a list of rounds, or would just the shown list of rounds work?
Below is my data (getAllRoundsByUserId), my controller with rounds/{id} (id=userId) method and my html.
Data getAllRoundsByUserId (sorry if it looks complicated, a round has a date, total, score (List of Score) and a course(name, record, par, List of Hole)
[Round{roundId=19, course=Course{id=1, name='Legende', holes=[Hole{holeId=37, number=1, par=3}, Hole{holeId=38, number=2, par=3}, Hole{holeId=39, number=3, par=3}, Hole{holeId=40, number=4, par=3}, Hole{holeId=41, number=5, par=3}, Hole{holeId=42, number=6, par=3}, Hole{holeId=43, number=7, par=3}, Hole{holeId=44, number=8, par=3}, Hole{holeId=45, number=9, par=3}], par=27, record=-2}, scores=[Score{scoreId=181, score=2, holePar=3}, Score{scoreId=182, score=4, holePar=3}, Score{scoreId=183, score=4, holePar=3}, Score{scoreId=184, score=2, holePar=3}, Score{scoreId=185, score=3, holePar=3}, Score{scoreId=186, score=2, holePar=3}, Score{scoreId=187, score=3, holePar=3}, Score{scoreId=188, score=3, holePar=3}, Score{scoreId=189, score=3, holePar=3}], roundDate=2023-03-04 00:00:00.0, total=26}, Round{roundId=20, course=Course{id=1, name='Legende', holes=[Hole{holeId=37, number=1, par=3}, Hole{holeId=38, number=2, par=3}, Hole{holeId=39, number=3, par=3}, Hole{holeId=40, number=4, par=3}, Hole{holeId=41, number=5, par=3}, Hole{holeId=42, number=6, par=3}, Hole{holeId=43, number=7, par=3}, Hole{holeId=44, number=8, par=3}, Hole{holeId=45, number=9, par=3}], par=27, record=-2}, scores=[Score{scoreId=190, score=4, holePar=3}, Score{scoreId=191, score=4, holePar=3}, Score{scoreId=192, score=3, holePar=3}, Score{scoreId=193, score=3, holePar=3}, Score{scoreId=194, score=3, holePar=3}, Score{scoreId=195, score=3, holePar=3}, Score{scoreId=196, score=4, holePar=3}, Score{scoreId=197, score=3, holePar=3}, Score{scoreId=198, score=3, holePar=3}], roundDate=2023-03-04 00:00:00.0, total=30}, Round{roundId=21, course=Course{id=2, name='Ilsede', holes=[Hole{holeId=46, number=1, par=3}, Hole{holeId=47, number=2, par=3}, Hole{holeId=48, number=3, par=3}, Hole{holeId=49, number=4, par=3}, Hole{holeId=50, number=5, par=3}, Hole{holeId=51, number=6, par=3}, Hole{holeId=52, number=7, par=3}, Hole{holeId=53, number=8, par=3}, Hole{holeId=54, number=9, par=3}, Hole{holeId=55, number=10, par=3}, Hole{holeId=56, number=11, par=3}, Hole{holeId=57, number=12, par=3}, Hole{holeId=58, number=13, par=4}, Hole{holeId=59, number=14, par=3}, Hole{holeId=60, number=15, par=3}, Hole{holeId=61, number=16, par=3}, Hole{holeId=62, number=17, par=3}, Hole{holeId=63, number=18, par=3}], par=55, record=7}, scores=[Score{scoreId=199, score=3, holePar=3}, Score{scoreId=200, score=3, holePar=3}, Score{scoreId=201, score=3, holePar=3}, Score{scoreId=202, score=4, holePar=3}, Score{scoreId=203, score=3, holePar=3}, Score{scoreId=204, score=3, holePar=3}, Score{scoreId=205, score=2, holePar=3}, Score{scoreId=206, score=3, holePar=3}, Score{scoreId=207, score=3, holePar=3}, Score{scoreId=208, score=4, holePar=3}, Score{scoreId=209, score=3, holePar=3}, Score{scoreId=210, score=3, holePar=3}, Score{scoreId=211, score=2, holePar=3}, Score{scoreId=212, score=3, holePar=3}, Score{scoreId=213, score=3, holePar=3}, Score{scoreId=214, score=4, holePar=3}, Score{scoreId=215, score=3, holePar=3}, Score{scoreId=216, score=2, holePar=3}], roundDate=2023-03-01 00:00:00.0, total=54}]
Controller method
@GetMapping("/rounds/{id}")
public String roundsHome(@PathVariable(value = "id") Long id,
Model model) {
List<Course> courses = courseService.getAllCourses();
List<Round> rounds = userService.getUserById(id).getRounds();
model.addAttribute("courses", courses);
model.addAttribute("rounds", rounds);
return "/discgolf/round/rounds";
}
html
<div class="container">
<div>
<a>Rounds Played</a>
</div>
<div id="accordion">
<div th:each="round : ${rounds}" class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
<div>
<label>Course: </label>
<label th:text="${round.course.name}"></label>
</div>
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<div class="d-flex flex-row">
<div class="p-3">
<label>Date: </label>
<label th:text="${#dates.format(round.roundDate, 'dd-MMM-yyyy')}"></label>
</div>
<div class="p-3">
<label>Score: </label>
<label th:text="${round.total - round.course.par}"></label>
</div>
</div>
<br>
<div >
<table id="courseInfo" class="table table-bordered w-auto">
<th:block th:each="course : ${round.course}">
<tr>
<th th:text="${'Hole'}"></th>
<th th:each="hole : ${course.holes}" th:text="${hole.number}"></th>
<th th:text="${'Total'}"></th>
</tr>
<tr>
<td th:text="${'Par'}"></td>
<td th:each="par : ${course.holes}" th:text="${par.par}"></td>
<td th:text="${course.par}"></td>
</tr>
<tr>
<td th:text="${'Score'}"></td>
<th:block th:each="score : ${round.scores}">
<td th:style="${score.score > score.holePar}
? 'background-color: red'
: (${score.score < score.holePar } ? 'background-color: blue'
: 'background-color: #eee' ) " th:text="${score.score}"></td>
</th:block>
<td th:text="${round.total}"></td>
</tr>
</th:block>
</table>
<br>
<a th:href="@{/discgolf/deleteRound/{id}(id=${round.roundId})}" title="Remove Course"
data-target="#deleteRoundModal" class="table-link danger" id="deleteRoundButton" >
<span id="deleteRound" class="fa-stack">
<i class="fa fa-square fa-stack-2x"></i>
<i class="fa fa-trash-o fa-stack-1x fa-inverse" title="Delete this round"></i>
</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
答案1
得分: 1
So I figured it out with using a Map. For other beginners this is great to learn.
@GetMapping("/rounds/{id}")
public String roundsHome(@PathVariable(value = "id") Long id,
Model model) {
List<Course> courses = courseService.getAllCourses();
List<Round> rounds = userService.getUserById(id).getRounds();
Map<Course, List<Round>> mapRoundsByCourse = rounds.stream().collect(Collectors.groupingBy(Round::getCourse));
model.addAttribute("courses", courses);
model.addAttribute("rounds", mapRoundsByCourse);
return "/discgolf/round/rounds";
}
Then I used the bottom answer here to render in my accordion.
英文:
So I figured it out with using a Map. For other beginners this is great to learn.
@GetMapping("/rounds/{id}")
public String roundsHome(@PathVariable(value = "id") Long id,
Model model) {
List<Course> courses = courseService.getAllCourses();
List<Round> rounds = userService.getUserById(id).getRounds();
Map<Course, List<Round>> mapRoundsByCourse = rounds.stream().collect(Collectors.groupingBy(Round::getCourse));
model.addAttribute("courses", courses);
model.addAttribute("rounds", mapRoundsByCourse);
return "/discgolf/round/rounds";
}
Then I used the bottom answer here to render in my accordion.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论