所以我能够在视图中列出数据库中的所有用户,但我想按字母顺序和选项卡列出它们。例如,我将为" All"," A"," B"," C"等提供标签。我想要发生的是当用户点击" A"选项卡,它仅显示姓氏以" A"开头的用户。
我这样做的想法是这样的:
<ul class="tabs">
<li><a href="#A">A</a></li>
<li><a href="#B">B</a></li>
<li><a href="#C">C</a></li>
...
</ul>
<div class="tabcontents">
<div id="All">
<nav>
<ul>
<g:each var="user" in="${users}" ID="">
<li><g:link controller="user" action="profile" id="${user.employeeNumber}">${user.lastName}, ${user.firstName}</g:link></li>
</g:each>
</ul>
</nav>
</div>
<div id="A">
<nav>
<ul>
<g:each var="user" in="${users}" ID="A">
<li><g:link controller="user" action="profile" id="${user.employeeNumber}">${user.lastName}, ${user.firstName}</g:link></li>
</g:each>
</ul>
</nav>
</div>
...
</div>
后端UserController包含类似
的内容class UserController {
def index() {
def users = UserFeed.createCriteria().list {
eq('lastName[0]', '${ID}')
}
render(view: 'index', model: [users: users])
}
def search() {
}
def results(String lastName) {
def users = UserFeed.where {
lastName =~ "%${lastName}%"
}.list()
return [ users: users,
term: params.lastName,
totalUsers: UserFeed.count() ]
}
def profile(String id) {
def user = UserFeed.findByEmployeeNumber(id)
render(view: 'profile', model: [user: user])
}
}
因此,当用户单击选项卡时,选项卡的字母将被发送到控制器,其中比较数据库中姓氏的第一个字母,如果匹配则将其添加到列表中。这可能吗?有没有一个光滑的方法来做到这一点?
提前致谢!
编辑:我可以蛮力这个,我只想避免为每个字母表中的26个用户组。
编辑2:我尝试过这样的事情,但无济于事
<div id="A">
<nav>
<ul>
<g:each var="user" in="${users}">
<g:if test="${user.lastName.charAt(0)} == 'A'">
<li style="padding-left:5px;"><g:link controller="user" action="profile" id="${user.employeeNumber}">${user.lastName}, ${user.firstName}</g:link></li>
</g:if>
</g:each>
</ul>
</nav>
</div>
我已经验证user.lastName.charAt(0)打印出正确的字母,但无论出于何种原因,g:if
语句都不会将列表限制为只有A&#39;秒。有什么想法吗?
答案 0 :(得分:1)
我认为一个好的起点是一个易于渲染到标签的模型。例如,控制器方法可以返回一个模型,该模型包含一个包含键的字母的Map和每个字母下面的用户的值。
从用户列表和所选字母开始,以下是如何在Groovy中创建此类Map的示例:
def selectedLetter = 'A'
def tabs = users
.groupBy { it.lastName[0].toUpperCase() }
.collectEntries { k, v -> [k, v.sort() {a, b -> a.lastName <=> b.lastName}] }
.collectEntries { k, v -> k == selectedLetter ? [k, v] : [k, null] }
这会返回一个稀疏映射;通过将所有其他用户设置为null,仅包括所选字母的用户。接下来,返回包含选项卡的模型:
render(view: 'index', model: [tabs: tabs])
使用这样的模型,可以按如下方式动态呈现选项卡:
<ul class="tabs">
<g:each var="letter" in="${tabs.keySet().sort()}">
<li class="${tabs.letter != null ? 'active' : ''">
<a href="#${letter}">${letter}</a>
</li>
</g:each>
</ul>
标签内容可以这样呈现:
<div class="tabcontents">
<g:each var="letter" in="${tabs.keySet().sort()}">
<div id="${letter}">
<nav>
<ul>
<g:each var="user" in="${tabs.letter}">
<li><g:link controller="user" action="profile" id="${user.employeeNumber}">${user.lastName}, ${user.firstName}</g:link></li>
</g:each>
</ul>
</nav>
</div>
</g:each>
</div>