带有搜索参数的 Freemarker 分页
Freemarker pagination with Search parameter
我正在使用 Fremarker 进行分页。这是寻呼机宏:
<#macro pager url page>
<#if page.getTotalPages() gt 7>
<#assign
totalPages = page.getTotalPages()
pageNumber = page.getNumber() + 1
head = (pageNumber > 4)?then([1, -1], [1, 2, 3])
tail = (pageNumber < totalPages - 3)?then([-1, totalPages], [totalPages - 2, totalPages - 1, totalPages])
bodyBefore = (pageNumber > 4 && pageNumber < totalPages - 1)?then([pageNumber - 2, pageNumber - 1], [])
bodyAfter = (pageNumber > 2 && pageNumber < totalPages - 3)?then([pageNumber + 1, pageNumber + 2], [])
body = head + bodyBefore + (pageNumber > 3 && pageNumber < totalPages - 2)?then([pageNumber], []) + bodyAfter + tail
>
<#else>
<#assign body = 1..page.getTotalPages()>
</#if>
<div class="container-fluid mt-3">
<div class="row">
<ul class="pagination col">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Pages</a>
</li>
<#list body as p>
<#if (p - 1) == page.getNumber()>
<li class="page-item active">
<a class="page-link" href="#" tabindex="-1">${p}</a>
</li>
<#elseif p == -1>
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">...</a>
</li>
<#else>
<li class="page-item">
<a class="page-link" href="${url}?page=${p - 1}&size=${page.getSize()}" tabindex="-1">${p}</a>
</li>
</#if>
</#list>
</ul>
<ul class="pagination col justify-content-end">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Elements per page</a>
</li>
<#list [20, 40, 80, 120] as c>
<#if c == page.getSize()>
<li class="page-item active">
<a class="page-link" href="#" tabindex="-1">${c}</a>
</li>
<#else>
<li class="page-item">
<a class="page-link" href="${url}?page=${page.getNumber()}&size=${c}" tabindex="-1">${c}</a>
</li>
</#if>
</#list>
</ul>
</div>
</div>
</#macro>
分页 URL 看起来像:
http://localhost:8080/main?page=1&size=10
主页有搜索功能:
<@c.page>
<div class="form-row">
<div class="form-group col-md-6">
<form method="get" action="/main" class="form-inline">
<input type="text" name="filter" class="form-control" value="${filter?ifExists}"
placeholder="Search by tag"/>
<button type="submit" class="btn btn-primary ml-2">Search</button>
</form>
</div>
</div>
</@c.page>
如果输入搜索,URL 将如下所示:
http://localhost:8080/main?filter=search-param
但是,分页不适用于输入搜索参数(实际上称为过滤器)的 URL。
尝试向 pager.ftl
添加如下内容:
<#if '${url}'?contains("filter")>
<a class="page-link" href="${url}&page=${p - 1}&size=${page.getSize()}" tabindex="-1">${p}</a>
<#else>
<a class="page-link" href="${url}?page=${p - 1}&size=${page.getSize()}" tabindex="-1">${p}</a>
</#if>
想法是检查 URL 是否设置了过滤器参数 -> 向其添加分页:
http://localhost:8080/main?filter=search-param&page=1&size=10
如果没有搜索参数,使用默认参数。
它没有用。
此处已满Project Sources at GitHub。
具有 Spring 引导和 Spring 数据的后端逻辑工作得很好。
尝试了@ddekany 的解决方案。这是结果:
<#else>
<li class="page-item">
<a class="page-link"
href="${url}${url?contains('?')?then('&', '?')}page=${p - 1}&size=${page.getSize()}"
tabindex="-1">
${p}
</a>
</li>
</#if>
和第二部分:
<#else>
<li class="page-item">
<a class="page-link"
href="${url}${url?contains('?')?then('&', '?')}page=${page.getNumber()}&size=${c}"
tabindex="-1">
${c}
</a>
</li>
</#if>
这里是你输入搜索的时候:
但是,当您按 2
搜索页面时,您将被重定向到主页(搜索为空,而不是转到搜索结果的第 2 页):
解决方案:
在控制器上正确设置 URL:
Page<MessageDto> page = messageService.messageList(pageable, filter, user);
if (StringUtils.isNotBlank(filter)) {
model.addAttribute("url", String.format("/main?filter=%s", filter));
} else {
model.addAttribute("url", "/main");
}
model.addAttribute("page", page);
model.addAttribute("filter", filter);
return "main";
并在寻呼机上更改设置 URL:
<li class="page-item">
<#--<a class="page-link" href="${url}?page=${p - 1}&size=${page.getSize()}" tabindex="-1">${p}</a>-->
<a class="page-link" href="${url}${url?contains('?')?then('&', '?')}page=${p - 1}&size=${page.getSize()}" tabindex="-1">
${p}
</a>
</li>
和
<li class="page-item">
<#--<a class="page-link" href="${url}?page=${page.getNumber()}&size=${c}" tabindex="-1">${c}</a>-->
<a class="page-link" href="${url}${url?contains('?')?then('&', '?')}page=${page.getNumber()}&size=${c}" tabindex="-1">
${c}
</a>
</li>
注释行是旧代码。未注释的确实有效。
问题是如何为此类功能配置 Fremarker?
再次检查,因为 #if
应该有效。
但是,我会寻找 ?
,因为它比寻找 filter
更可靠,因为即使稍后重命名参数,它也能正常工作。
另外,<#if '${url}'?contains('...')>
也可以写成<#if url?contains('...')>
。
实际上,您可能不想重复整行,只是为了替换单个字符,所以只写
href="${url}${url?contains('?')?then('&', '?')}page=...
.
(你可以在 Freemarker demo 上快速测试这些东西)
我正在使用 Fremarker 进行分页。这是寻呼机宏:
<#macro pager url page>
<#if page.getTotalPages() gt 7>
<#assign
totalPages = page.getTotalPages()
pageNumber = page.getNumber() + 1
head = (pageNumber > 4)?then([1, -1], [1, 2, 3])
tail = (pageNumber < totalPages - 3)?then([-1, totalPages], [totalPages - 2, totalPages - 1, totalPages])
bodyBefore = (pageNumber > 4 && pageNumber < totalPages - 1)?then([pageNumber - 2, pageNumber - 1], [])
bodyAfter = (pageNumber > 2 && pageNumber < totalPages - 3)?then([pageNumber + 1, pageNumber + 2], [])
body = head + bodyBefore + (pageNumber > 3 && pageNumber < totalPages - 2)?then([pageNumber], []) + bodyAfter + tail
>
<#else>
<#assign body = 1..page.getTotalPages()>
</#if>
<div class="container-fluid mt-3">
<div class="row">
<ul class="pagination col">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Pages</a>
</li>
<#list body as p>
<#if (p - 1) == page.getNumber()>
<li class="page-item active">
<a class="page-link" href="#" tabindex="-1">${p}</a>
</li>
<#elseif p == -1>
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">...</a>
</li>
<#else>
<li class="page-item">
<a class="page-link" href="${url}?page=${p - 1}&size=${page.getSize()}" tabindex="-1">${p}</a>
</li>
</#if>
</#list>
</ul>
<ul class="pagination col justify-content-end">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Elements per page</a>
</li>
<#list [20, 40, 80, 120] as c>
<#if c == page.getSize()>
<li class="page-item active">
<a class="page-link" href="#" tabindex="-1">${c}</a>
</li>
<#else>
<li class="page-item">
<a class="page-link" href="${url}?page=${page.getNumber()}&size=${c}" tabindex="-1">${c}</a>
</li>
</#if>
</#list>
</ul>
</div>
</div>
</#macro>
分页 URL 看起来像:
http://localhost:8080/main?page=1&size=10
主页有搜索功能:
<@c.page>
<div class="form-row">
<div class="form-group col-md-6">
<form method="get" action="/main" class="form-inline">
<input type="text" name="filter" class="form-control" value="${filter?ifExists}"
placeholder="Search by tag"/>
<button type="submit" class="btn btn-primary ml-2">Search</button>
</form>
</div>
</div>
</@c.page>
如果输入搜索,URL 将如下所示:
http://localhost:8080/main?filter=search-param
但是,分页不适用于输入搜索参数(实际上称为过滤器)的 URL。
尝试向 pager.ftl
添加如下内容:
<#if '${url}'?contains("filter")>
<a class="page-link" href="${url}&page=${p - 1}&size=${page.getSize()}" tabindex="-1">${p}</a>
<#else>
<a class="page-link" href="${url}?page=${p - 1}&size=${page.getSize()}" tabindex="-1">${p}</a>
</#if>
想法是检查 URL 是否设置了过滤器参数 -> 向其添加分页:
http://localhost:8080/main?filter=search-param&page=1&size=10
如果没有搜索参数,使用默认参数。
它没有用。
此处已满Project Sources at GitHub。
具有 Spring 引导和 Spring 数据的后端逻辑工作得很好。
尝试了@ddekany 的解决方案。这是结果:
<#else>
<li class="page-item">
<a class="page-link"
href="${url}${url?contains('?')?then('&', '?')}page=${p - 1}&size=${page.getSize()}"
tabindex="-1">
${p}
</a>
</li>
</#if>
和第二部分:
<#else>
<li class="page-item">
<a class="page-link"
href="${url}${url?contains('?')?then('&', '?')}page=${page.getNumber()}&size=${c}"
tabindex="-1">
${c}
</a>
</li>
</#if>
这里是你输入搜索的时候:
但是,当您按 2
搜索页面时,您将被重定向到主页(搜索为空,而不是转到搜索结果的第 2 页):
解决方案:
在控制器上正确设置 URL:
Page<MessageDto> page = messageService.messageList(pageable, filter, user);
if (StringUtils.isNotBlank(filter)) {
model.addAttribute("url", String.format("/main?filter=%s", filter));
} else {
model.addAttribute("url", "/main");
}
model.addAttribute("page", page);
model.addAttribute("filter", filter);
return "main";
并在寻呼机上更改设置 URL:
<li class="page-item">
<#--<a class="page-link" href="${url}?page=${p - 1}&size=${page.getSize()}" tabindex="-1">${p}</a>-->
<a class="page-link" href="${url}${url?contains('?')?then('&', '?')}page=${p - 1}&size=${page.getSize()}" tabindex="-1">
${p}
</a>
</li>
和
<li class="page-item">
<#--<a class="page-link" href="${url}?page=${page.getNumber()}&size=${c}" tabindex="-1">${c}</a>-->
<a class="page-link" href="${url}${url?contains('?')?then('&', '?')}page=${page.getNumber()}&size=${c}" tabindex="-1">
${c}
</a>
</li>
注释行是旧代码。未注释的确实有效。
问题是如何为此类功能配置 Fremarker?
再次检查,因为 #if
应该有效。
但是,我会寻找 ?
,因为它比寻找 filter
更可靠,因为即使稍后重命名参数,它也能正常工作。
另外,<#if '${url}'?contains('...')>
也可以写成<#if url?contains('...')>
。
实际上,您可能不想重复整行,只是为了替换单个字符,所以只写
href="${url}${url?contains('?')?then('&', '?')}page=...
.
(你可以在 Freemarker demo 上快速测试这些东西)