PrimeFaces 分页器 JumpToPageDropdown 错误
PrimeFaces Paginator JumpToPageDropdown Bug
我正在从 PrimeFaces 6.2 迁移到 8.0。在我的项目中,我使用了多个 Primeface DataTables with a Paginator.
MCVE:
创建一个包含 10 个以上元素的数据列表。然后单击不同的页码。当从 JumpToPageDropdown 中单击或选择任何大于 10 的页码时,控制台将记录以下错误:
Chrome 控制台出错:
jquery.js.xhtml?ln=primefaces&v=8.0:2 Uncaught Error: Syntax error, unrecognized expression: option[value= 0]
at Function.se.error (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at se.tokenize (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at se.compile (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at se.select (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at se (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at Function.se.matches (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at Function.k.filter (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at k.fn.init.k.fn.<computed> [as children] (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at c.updateUI (components.js.xhtml?ln=primefaces&v=8.0:58)
at c.updateTotalRecords (components.js.xhtml?ln=primefaces&v=8.0:58)
使用的组件:
<p:dataTable id="datatable"value="#{backendController.dataList}"
var="data" paginator="true" rows="1" paginatorPosition="top"
pageLinks="20"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {JumpToPageDropdown} {NextPageLink} {LastPageLink}">
-> Add a few <p:column> tags.
</p:dataTable>
临时修复:
我能够确定 JumpToPageDropdown 是导致错误的原因。当它从 paginatorTemplate 中删除时,单击大于 10 的页面时将不再显示错误。不幸的是我想使用这个下拉列表。
进一步研究:
PrimeFaces 将这些 JS 文件用于其组件,因此也用于 JumpToPageDropdown:
- PrimeFaces 6.2: components.js.xhtml?ln=primefaces&v=6.2 PrimeFaces
- PrimeFaces 8.0: components.js.xhtml?ln=primefaces&v=8.0
这是更新
的相应调用
Both versions:
this.jtpSelect = this.jq.children(".ui-paginator-jtp-select");
PrimeFaces 8.0:
this.jtpSelect.children("option[value=" + $.escapeSelector(this.cfg.page) + "]").prop("selected", "selected")
PrimeFaces 6.2:
this.jtpSelect.children("option[value=" + (this.cfg.page) + "]").prop("selected", "selected")
不同的是在8.0版本中this.cfg.page
的值被传递给函数$.escapeSelector()
.
this.cfg.page
使用从零开始的编号。第 1 页为 0,第 10 页为 9,依此类推。在版本 6.2 中,当所选页面为 11 时,this.jtpSelect.children()
将使用选项 [value=10] 调用。但在版本 8.0 中,$.escapeSelector()
会将相同的输入格式化为 0
并导致 option[value= 0]
.
这导致了上述错误。看到这一行:Uncaught Error: Syntax error, unrecognized expression: option[value= 0]
建议:
如果这是一个错误 $.escapeSelector()
应该从 PrimeFaces 8.0 中的这个函数中删除,显然不需要转义:数字不需要转义。
解决方法:
深入研究代码后,我发现了修复错误的技巧:
window.PrimeFaces.widget.Paginator.prototype.updateUI = function(){
if (this.cfg.page === 0) {
this.disableElement(this.firstLink);
this.disableElement(this.prevLink)
} else {
this.enableElement(this.firstLink);
this.enableElement(this.prevLink)
}
if (this.cfg.page === (this.cfg.pageCount - 1)) {
this.disableElement(this.nextLink);
this.disableElement(this.endLink)
} else {
this.enableElement(this.nextLink);
this.enableElement(this.endLink)
}
var a = (this.cfg.rowCount === 0) ? 0 : (this.cfg.page * this.cfg.rows) + 1
, c = (this.cfg.page * this.cfg.rows) + this.cfg.rows;
if (c > this.cfg.rowCount) {
c = this.cfg.rowCount
}
var e = this.cfg.currentPageTemplate.replace("{currentPage}", this.cfg.page + 1).replace("{totalPages}", this.cfg.pageCount).replace("{totalRecords}", this.cfg.rowCount).replace("{startRecord}", a).replace("{endRecord}", c);
this.currentReport.text(e);
if (this.cfg.prevRows !== this.cfg.rows) {
this.rppSelect.filter(":not(.ui-state-focus)").children("option").filter('option[value="' + $.escapeSelector(this.cfg.rows) + '"]').prop("selected", true);
this.cfg.prevRows = this.cfg.rows
}
if (this.jtpSelect.length > 0) {
if (this.jtpSelect[0].options.length != this.cfg.pageCount) {
var d = "";
for (var b = 0; b < this.cfg.pageCount; b++) {
d += '<option value="' + b + '">' + (b + 1) + "</option>"
}
this.jtpSelect.html(d)
}
this.jtpSelect.children("option[value=" + (this.cfg.page) + "]").prop("selected", "selected")
}
if (this.jtpInput.length > 0) {
this.jtpInput.val(this.cfg.page + 1)
}
this.updatePageLinks()
}
解释:
Paginator widget 的updateUI 函数导致错误。它可以通过 window.PrimeFaces.widget.Paginator.prototype.updateUI
访问,然后被更正后的版本覆盖。
hack 中更改的行:
this.jtpSelect.children("option[value=" + (this.cfg.page) + "]").prop("selected", "selected")
PrimeFaces 8.0 中的原始行:
this.jtpSelect.children("option[value=" + $.escapeSelector(this.cfg.page) + "]").prop("selected", "selected")
.
我正在从 PrimeFaces 6.2 迁移到 8.0。在我的项目中,我使用了多个 Primeface DataTables with a Paginator.
MCVE:
创建一个包含 10 个以上元素的数据列表。然后单击不同的页码。当从 JumpToPageDropdown 中单击或选择任何大于 10 的页码时,控制台将记录以下错误:
Chrome 控制台出错:
jquery.js.xhtml?ln=primefaces&v=8.0:2 Uncaught Error: Syntax error, unrecognized expression: option[value= 0]
at Function.se.error (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at se.tokenize (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at se.compile (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at se.select (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at se (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at Function.se.matches (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at Function.k.filter (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at k.fn.init.k.fn.<computed> [as children] (jquery.js.xhtml?ln=primefaces&v=8.0:2)
at c.updateUI (components.js.xhtml?ln=primefaces&v=8.0:58)
at c.updateTotalRecords (components.js.xhtml?ln=primefaces&v=8.0:58)
使用的组件:
<p:dataTable id="datatable"value="#{backendController.dataList}"
var="data" paginator="true" rows="1" paginatorPosition="top"
pageLinks="20"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {JumpToPageDropdown} {NextPageLink} {LastPageLink}">
-> Add a few <p:column> tags.
</p:dataTable>
临时修复:
我能够确定 JumpToPageDropdown 是导致错误的原因。当它从 paginatorTemplate 中删除时,单击大于 10 的页面时将不再显示错误。不幸的是我想使用这个下拉列表。
进一步研究:
PrimeFaces 将这些 JS 文件用于其组件,因此也用于 JumpToPageDropdown:
- PrimeFaces 6.2: components.js.xhtml?ln=primefaces&v=6.2 PrimeFaces
- PrimeFaces 8.0: components.js.xhtml?ln=primefaces&v=8.0
这是更新
的相应调用Both versions:
this.jtpSelect = this.jq.children(".ui-paginator-jtp-select");
PrimeFaces 8.0:
this.jtpSelect.children("option[value=" + $.escapeSelector(this.cfg.page) + "]").prop("selected", "selected")
PrimeFaces 6.2:
this.jtpSelect.children("option[value=" + (this.cfg.page) + "]").prop("selected", "selected")
不同的是在8.0版本中this.cfg.page
的值被传递给函数$.escapeSelector()
.
this.cfg.page
使用从零开始的编号。第 1 页为 0,第 10 页为 9,依此类推。在版本 6.2 中,当所选页面为 11 时,this.jtpSelect.children()
将使用选项 [value=10] 调用。但在版本 8.0 中,$.escapeSelector()
会将相同的输入格式化为 0
并导致 option[value= 0]
.
这导致了上述错误。看到这一行:Uncaught Error: Syntax error, unrecognized expression: option[value= 0]
建议:
如果这是一个错误 $.escapeSelector()
应该从 PrimeFaces 8.0 中的这个函数中删除,显然不需要转义:数字不需要转义。
解决方法:
深入研究代码后,我发现了修复错误的技巧:
window.PrimeFaces.widget.Paginator.prototype.updateUI = function(){
if (this.cfg.page === 0) {
this.disableElement(this.firstLink);
this.disableElement(this.prevLink)
} else {
this.enableElement(this.firstLink);
this.enableElement(this.prevLink)
}
if (this.cfg.page === (this.cfg.pageCount - 1)) {
this.disableElement(this.nextLink);
this.disableElement(this.endLink)
} else {
this.enableElement(this.nextLink);
this.enableElement(this.endLink)
}
var a = (this.cfg.rowCount === 0) ? 0 : (this.cfg.page * this.cfg.rows) + 1
, c = (this.cfg.page * this.cfg.rows) + this.cfg.rows;
if (c > this.cfg.rowCount) {
c = this.cfg.rowCount
}
var e = this.cfg.currentPageTemplate.replace("{currentPage}", this.cfg.page + 1).replace("{totalPages}", this.cfg.pageCount).replace("{totalRecords}", this.cfg.rowCount).replace("{startRecord}", a).replace("{endRecord}", c);
this.currentReport.text(e);
if (this.cfg.prevRows !== this.cfg.rows) {
this.rppSelect.filter(":not(.ui-state-focus)").children("option").filter('option[value="' + $.escapeSelector(this.cfg.rows) + '"]').prop("selected", true);
this.cfg.prevRows = this.cfg.rows
}
if (this.jtpSelect.length > 0) {
if (this.jtpSelect[0].options.length != this.cfg.pageCount) {
var d = "";
for (var b = 0; b < this.cfg.pageCount; b++) {
d += '<option value="' + b + '">' + (b + 1) + "</option>"
}
this.jtpSelect.html(d)
}
this.jtpSelect.children("option[value=" + (this.cfg.page) + "]").prop("selected", "selected")
}
if (this.jtpInput.length > 0) {
this.jtpInput.val(this.cfg.page + 1)
}
this.updatePageLinks()
}
解释:
Paginator widget 的updateUI 函数导致错误。它可以通过 window.PrimeFaces.widget.Paginator.prototype.updateUI
访问,然后被更正后的版本覆盖。
hack 中更改的行:
this.jtpSelect.children("option[value=" + (this.cfg.page) + "]").prop("selected", "selected")
PrimeFaces 8.0 中的原始行:
this.jtpSelect.children("option[value=" + $.escapeSelector(this.cfg.page) + "]").prop("selected", "selected")
.