在 dataTable rowSelect 上调用 history.pushState
Calling history.pushState on dataTable rowSelect
我正在使用 PrimeFaces 5.1,当用户使用以下代码单击 p:dataTable
行时,我会调用 history.pushState
:
<p:dataTable value="#{associateBean.scenarios}"
selectionMode="single"
selection="#{associateBean.selectedScenarioViewBean}"
var="scenarioViewBean" rowKey="#{scenarioViewBean.id}">
<p:ajax event="rowSelect"
listener="#{associateBean.onScenarioRowSelect}"
oncomplete="history.pushState('','','test#{scenarioViewBean.id}')"
update="@form"/>
<p:column>
<h:outputText value="#{scenarioViewBean.name}"/>
</p:column>
</p:dataTable>
如您所见,我正在尝试将 scenarioViewBean.id
值传递给我的 pushState
调用。
问题是 #{scenarioViewBean.id}
没有 return 任何东西,所以 JavaScript 推 "test" 而不是 "test123" 在 URL.
我该如何解决这个问题?
好的,现在可以了,但我必须调整 DataTable 组件:
<script type="text/javascript">
jQuery(document).ready(function(jQuery) {
function updateHistory(selectedRowKey) {
history.pushState({
selectedRowKey: selectedRowKey
},
document.title,
selectedRowKey);
}
if (PF('widgetScenariosDataTable')) {
// initial callback
var f = PF('widgetScenariosDataTable').onRowClick;
PF('widgetScenariosDataTable').onRowClick = function(event, rowElement) {
// Call initial callback (we have to use apply because
// the method is using 'this')
f.apply(PF('widgetScenariosDataTable'), [event, rowElement]);
// selected row key
var selectedRowKey = PF('widgetScenariosDataTable').selection;
// Your callback
updateHistory(selectedRowKey);
};
jQuery(window).bind('popstate', function(event) {
// First we have to unselect all rows
PF('widgetScenariosDataTable').unselectAllRows();
if (event.originalEvent.state!=null) {
// We select the row by passing the tr object that
// has the correct rowKey value (this is safer than
// using the rowIndex if the user adds/deletes the
// datatable rows and then uses the browser's history)
PF('widgetScenariosDataTable').selectRow(
jQuery("tr[data-rk="+event.originalEvent.state.selectedScenarioId+"]"),
false
);
}
else {
// We use location.href if there is no state stored
var href = window.location.href;
PF('widgetScenariosDataTable').selectRow(
jQuery("tr[data-rk="+href.substr(href.lastIndexOf('/') + 1)+"]"),
false
);
}
});
}
});
</script>
此代码改编自http://www.takohi.com/javascript-callback-on-row-click-event-with-primefaces-datatable/
如果有人知道更简单的方法,请post它,然后我会将您的答案添加为最佳答案。
无需复杂化,保留您的 rowSelect ajax 事件并按以下方式传递 ID:
PF('dataTableWV').selection[0]
根据你的问题,最终结果应该是这样的:
<p:ajax event="rowSelect"
listener="#{associateBean.onScenarioRowSelect}"
oncomplete="history.pushState('','','test'+PF('dataTableWV').selection[0]"
update="@form"/>
注:dataTableWV
是dataTable widgetVar
我不使用 onRowClick 事件的解决方案:
<h:outputScript library="js" target="head" name="pop.js"/>
<p:dataTable id="table" widgetVar="tableWdg" var="vv"
value="#{bean.list}"
rowKey="#{vv.id}" rowIndexVar="rowIndex"
selectionMode="single"
selection="#{bean.selected}">
<p:ajax event="rowSelect" process="@this" listener="#{bean.actionRowSelect}"/>
<p:column headerText="ID">
<h:outputText value="#{vv.id}" />
</p:column>
</p:dataTable>
'bean' 中的侦听器:
public void actionRowSelect(SelectEvent event) {
SelectedElement element = (SelectedElement) event.getObject();
HashMap<String, Object> jsonParams = new HashMap<String, Object>();
jsonParams.put("selectedRow", element.getId());
jsonParams.put("tableWdgName", table.getWidgetVar());
JSONObject json = new JSONObject(jsonParams);
String jsonString = json.toString();
String title = "generate yourself";
HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
String url = req.getRequestURL().toString();
if(req.getQueryString().length() > 0) {
url += "?" + req.getQueryString();
}
String jscriptString = "if (popstated != true) { window.history.pushState(" + jsonString + ", '" + title + "', '" + url + "'); popstated = false; } " ;
RequestContext.getCurrentInstance().execute(jscriptString);
}
和JS脚本'pop.js':
var popstated = false;
window.addEventListener('popstate', function(event) {
console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
console.log("event state.selectedRow=" + event.state.selectedRow);
PF(tableWdgName).unselectAllRows();
if(event.state.selectedRow != null) {
popstated = true;
PF(tableWdgName).selectRow(
jQuery( "tr[data-rk=" + event.state.selectedRow + "]" ),
false
);
}
});
诀窍是简单的布尔全局 JS 变量 'popstated' 并在服务器端生成 JS。
我正在使用 PrimeFaces 5.1,当用户使用以下代码单击 p:dataTable
行时,我会调用 history.pushState
:
<p:dataTable value="#{associateBean.scenarios}"
selectionMode="single"
selection="#{associateBean.selectedScenarioViewBean}"
var="scenarioViewBean" rowKey="#{scenarioViewBean.id}">
<p:ajax event="rowSelect"
listener="#{associateBean.onScenarioRowSelect}"
oncomplete="history.pushState('','','test#{scenarioViewBean.id}')"
update="@form"/>
<p:column>
<h:outputText value="#{scenarioViewBean.name}"/>
</p:column>
</p:dataTable>
如您所见,我正在尝试将 scenarioViewBean.id
值传递给我的 pushState
调用。
问题是 #{scenarioViewBean.id}
没有 return 任何东西,所以 JavaScript 推 "test" 而不是 "test123" 在 URL.
我该如何解决这个问题?
好的,现在可以了,但我必须调整 DataTable 组件:
<script type="text/javascript">
jQuery(document).ready(function(jQuery) {
function updateHistory(selectedRowKey) {
history.pushState({
selectedRowKey: selectedRowKey
},
document.title,
selectedRowKey);
}
if (PF('widgetScenariosDataTable')) {
// initial callback
var f = PF('widgetScenariosDataTable').onRowClick;
PF('widgetScenariosDataTable').onRowClick = function(event, rowElement) {
// Call initial callback (we have to use apply because
// the method is using 'this')
f.apply(PF('widgetScenariosDataTable'), [event, rowElement]);
// selected row key
var selectedRowKey = PF('widgetScenariosDataTable').selection;
// Your callback
updateHistory(selectedRowKey);
};
jQuery(window).bind('popstate', function(event) {
// First we have to unselect all rows
PF('widgetScenariosDataTable').unselectAllRows();
if (event.originalEvent.state!=null) {
// We select the row by passing the tr object that
// has the correct rowKey value (this is safer than
// using the rowIndex if the user adds/deletes the
// datatable rows and then uses the browser's history)
PF('widgetScenariosDataTable').selectRow(
jQuery("tr[data-rk="+event.originalEvent.state.selectedScenarioId+"]"),
false
);
}
else {
// We use location.href if there is no state stored
var href = window.location.href;
PF('widgetScenariosDataTable').selectRow(
jQuery("tr[data-rk="+href.substr(href.lastIndexOf('/') + 1)+"]"),
false
);
}
});
}
});
</script>
此代码改编自http://www.takohi.com/javascript-callback-on-row-click-event-with-primefaces-datatable/
如果有人知道更简单的方法,请post它,然后我会将您的答案添加为最佳答案。
无需复杂化,保留您的 rowSelect ajax 事件并按以下方式传递 ID:
PF('dataTableWV').selection[0]
根据你的问题,最终结果应该是这样的:
<p:ajax event="rowSelect"
listener="#{associateBean.onScenarioRowSelect}"
oncomplete="history.pushState('','','test'+PF('dataTableWV').selection[0]"
update="@form"/>
注:dataTableWV
是dataTable widgetVar
我不使用 onRowClick 事件的解决方案:
<h:outputScript library="js" target="head" name="pop.js"/>
<p:dataTable id="table" widgetVar="tableWdg" var="vv"
value="#{bean.list}"
rowKey="#{vv.id}" rowIndexVar="rowIndex"
selectionMode="single"
selection="#{bean.selected}">
<p:ajax event="rowSelect" process="@this" listener="#{bean.actionRowSelect}"/>
<p:column headerText="ID">
<h:outputText value="#{vv.id}" />
</p:column>
</p:dataTable>
'bean' 中的侦听器:
public void actionRowSelect(SelectEvent event) {
SelectedElement element = (SelectedElement) event.getObject();
HashMap<String, Object> jsonParams = new HashMap<String, Object>();
jsonParams.put("selectedRow", element.getId());
jsonParams.put("tableWdgName", table.getWidgetVar());
JSONObject json = new JSONObject(jsonParams);
String jsonString = json.toString();
String title = "generate yourself";
HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
String url = req.getRequestURL().toString();
if(req.getQueryString().length() > 0) {
url += "?" + req.getQueryString();
}
String jscriptString = "if (popstated != true) { window.history.pushState(" + jsonString + ", '" + title + "', '" + url + "'); popstated = false; } " ;
RequestContext.getCurrentInstance().execute(jscriptString);
}
和JS脚本'pop.js':
var popstated = false;
window.addEventListener('popstate', function(event) {
console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
console.log("event state.selectedRow=" + event.state.selectedRow);
PF(tableWdgName).unselectAllRows();
if(event.state.selectedRow != null) {
popstated = true;
PF(tableWdgName).selectRow(
jQuery( "tr[data-rk=" + event.state.selectedRow + "]" ),
false
);
}
});
诀窍是简单的布尔全局 JS 变量 'popstated' 并在服务器端生成 JS。