Я новичок в JSF и Primefaces, мне нужно открыть диалоговое окно, содержащее какую-то информацию о результатах поиска, когда была нажата кнопка поиска. Ранее открытый диалог всегда должен отображаться, если пользователь не закрыл его, поэтому я мог бы открыть несколько диалоговых окон.
Я использую приведенные ниже технологии, и моя проблема заключается в том, что я хочу использовать только один шаблон xhtml для диалогового окна, которое я вызываю, используя рамку диалога Primefaces. Любая идея, как достичь того, чего я хочу?
У меня есть пример кода, который я пытаюсь работать в качестве POC ниже. Он отлично работает, я могу отобразить первый диалог, но у меня больше нет идеи, как открыть другой диалог, когда кнопка поиска снова щелкнула.
home.xhtml
<div id="searchBtnDiv">
<p:commandButton id="queryNetworkElem" value="Search" ajax="true" actionListener="#{searchBean.querySubmit}" />
<p:commandButton id="advanceQuery" value="Advance Search" ajax="true" actionListener="#{searchBean.querySubmit}" />
</div>
SearchBean.java
@ManagedBean(name = "searchBean")
public class SearchBean{
...
public void generateSearchDialog(String searchParam) throws IOException{
System.out.println("opening dialog");
testMessage = "testing ";
RequestContext.getCurrentInstance().openDialog("test");
}
...
}
test.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<h:head>
</h:head>
<h:body>
<h1><p:outputLabel value="#{searchBean.testMessage}"/></h1>
<p:commandButton value="test" />
</h:body>
</html>
Ваш метод generateSearchDialog отображает только диалог p: с id = "test" на вашей странице. Что это будет сделано, так это то, что он откроет этот диалог и только тот (что означает, что, если вы закроете диалог и снова вызовите метод, он будет снова открыт).
Насколько я понимаю, вы хотите создать новые экземпляры Dialog при каждом вызове generateSearchDialog?
Если вы хотите это сделать, вам нужно создать новые диалоговые окна динамически. На своей веб-странице создайте контейнер для этих диалогов (т.е. PanelGroup), и каждый раз, когда вызывается метод, он создаст новый экземпляр Dialog. Имейте в виду, что создание диалоговых программ программно в бэк-компоненте не является хорошей практикой, но это поможет вам достичь этого. Теперь, чтобы это работало, заголовок диалога должен быть динамическим (возможно, добавить счетчик?). Ваш бэк-компонент выглядел бы примерно так:
UIComponent panelGroup = FacesContext.getCurrentInstance()
.getViewRoot().findComponent("dialogContainer");
Dialog dialog = new Dialog();
dialog.setId("newDialogInstance" + counter);
dialog.setVisible(true); //add whatever code you like
...
panelGroup.getChildren().add(dialog);
...
//update the WHOLE panel
RequestContext.getCurrentInstance().update("dialogContainer");
// OR openDialog your new Dialog.
RequestContext.getCurrentInstance().openDialog("newDialogInstance" + counter);
...
counter++;
У меня есть образец кода, который содержит список лиц. Каждый раз, когда пользователь нажимает на человека, открывается новое диалоговое окно
Код xhtml:
<h:form id="form">
<p:dataTable value="#{mbean.personList}" var="person">
<p:column headerText="Name">
<p:commandLink value="#{person.name}"
update=":form">
<f:setPropertyActionListener target="#{mbean.selectedPerson}"
value="#{person}" />
</p:commandLink>
</p:column>
<p:column headerText="Country">
#{person.country}
</p:column>
</p:dataTable>
<!-- <ui:include src="/WEB-INF/test.xhtml" /> -->
<ui:repeat var="d" value="#{mbean.personList}">
<p:dialog id="_#{d.getId()}" modal="false" width="500" height="500" widgetVar="Jag:#{d.getId()}">
<p:ajax event="close" listener="#{mbean.handleClose}" />
<h:outputLabel value="#{d.getName()}"></h:outputLabel>
</p:dialog>
</ui:repeat>
</h:form>
Код Java:
@ManagedBean(name = "mbean")
Открытый класс @ViewScoped TestBean реализует Serializable {
private List<Person> personList;
private Person selectedPerson;
private String dialogName;
private static int count=0;
private Map<Integer, String> dialogRemover = new HashMap<>();
public Map<Integer, String> getDialogRemover() {
return dialogRemover;
}
public void setDialogRemover(Map<Integer, String> dialogRemover) {
this.dialogRemover = dialogRemover;
}
public String getDialogName() {
return dialogName;
}
public void setDialogName(String dialogName) {
this.dialogName = "jag"+String.valueOf(count++);
}
public TestBean() {
personList = new ArrayList<Person>();
personList.add(new Person(6,"Aaa", "UK"));
personList.add(new Person(7,"Bbb", "Australia"));
personList.add(new Person(8,"Ccc", "Asia"));
}
public List<Person> getPersonList() {
return personList;
}
public void setPersonList(List<Person> personList) {
this.personList = personList;
}
public Person getSelectedPerson() {
return selectedPerson;
}
public void handleClose(CloseEvent event){
System.out.println("eventZ: "+event.getComponent().getId());
System.out.println("handle close event "+event.getComponent().getClientId());
String[] array = event.getComponent().getClientId().split(":");
dialogRemover.remove(Integer.parseInt(array[2]));
System.out.println("list elements are "+dialogRemover.size());
}
public void setSelectedPerson(Person selectedPerson) {
this.selectedPerson = selectedPerson;
String test = this.selectedPerson.getName();
if(!dialogRemover.containsValue("Jag:"+String.valueOf(this.selectedPerson.getId())) ){
dialogRemover.put(personList.indexOf(this.getSelectedPerson()),"Jag:"+String.valueOf(this.selectedPerson.getId()));
}
RequestContext context1 = RequestContext.getCurrentInstance();
for (Map.Entry<Integer, String> entry : dialogRemover.entrySet()) {
context1.execute("PF('"+entry.getValue()+"').show();");
}
}
}