如何重置 p:dialog 以及所包含组件的禁用状态?
How to reset p:dialog together with the disable-state of the contained components?
Primefaces 4.0
我需要重置 p:dialog
中包含的组件的初始禁用状态。
以下简化示例显示了问题:
XML:
<p:dialog header="header" widgetVar="dialog" appendTo="@(body)"
modal="true" resizable="false">
<h:form id="form">
<p:inputText value="#{bean.text}" id="text" />
<p:commandButton value="Disable InputText"
action="#{bean.disableInputText}" />
<p:commandButton value="Cancel"
action="#{bean.cancelDialog}"
process="@this"
update="@form" immediate="true">
<p:resetInput target="@form"/>
</p:commandButton>
</h:form>
</p:dialog>
ManagedBean:
@ViewScoped
public class Bean {
public void disableText() {
final FacesContext context = FacesContext.getCurrentInstance();
final UIViewRoot root = context.getViewRoot();
final UIComponent component = root.findComponent(":text");
if (uiComponent instanceof InputText) {
((InputText) uiComponent).setDisabled(true);
}
}
public void cancel() {
// reset disable-state of the disable-state of all components in a generic way.
}
}
使用对话框时,可以禁用 p:inputText
元素。如果对话框被取消并再次打开,则不应禁用 inputText。应该已经恢复到初始状态了。请注意,这个例子是简化的,我正在寻找一个通用的解决方案,它也适用于具有 10 个以上输入元素的公式。
通用(也是最广泛的)解决方案
对于通用解决方案,您可以使用 Java Server Faces 中提供的状态保存功能。使用您的代码示例作为基础(进行一些小的更改以清理内容),这是一个使用状态保存并恢复组件先前状态的示例;
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Disable Test</title>
</h:head>
<h:body>
<p:dialog header="header" widgetVar="dialog" appendTo="@(body)" modal="true" resizable="false">
<h:form id="form">
<p:inputText value="#{disableTestBean.text}" id="text"/>
<p:commandButton value="Disable InputText" action="#{disableTestBean.onDisable}" update="@form" />
<p:commandButton value="Cancel" action="#{disableTestBean.onCancel}" update="@form" onsuccess="PF('dialog').hide()" />
</h:form>
</p:dialog>
<button onclick="PF('dialog').show()">Open</button>
</h:body>
</html>
要真正看到重置发生,从第二个 commandButton
中删除 onsuccess
属性 - 因为它当前关闭对话框。
@Data
@Named
@ViewScoped
public class DisableTestBean implements Serializable {
private String text;
private Object prevState;
private UIComponent findComponent(String where) {
final FacesContext context = FacesContext.getCurrentInstance();
final UIViewRoot root = context.getViewRoot();
return (UIComponent) root.findComponent(where);
}
public void onDisable() {
final InputText component = (InputText) findComponent(":form:text");
component.setDisabled(false);
component.setValue("");
prevState = component.saveState(FacesContext.getCurrentInstance());
component.setValue("meh");
component.setDisabled(true);
}
public void onCancel() throws IOException {
final InputText component = (InputText) findComponent(":form:text");
component.restoreState(FacesContext.getCurrentInstance(), prevState);
}
}
该示例针对一个特定的输入组件。但是,如果你需要处理多个组件,你可以很容易地使用一个循环来以通用的方式完成你想要的。
作为演示,我不仅重置了上面支持 bean 中的禁用状态,还重置了输入组件的值(内容)。这向您展示了如何实际重置组件的完整状态(不仅是单个属性或值)。所以解决方案很广泛,也很通用。
第二种更直接的方法
第二种方法是做 @Kukeltje 在他上面的评论中暗示的事情。在输入组件上使用 disabled=
属性,并有一个支持 bean 值,当您按 Cancel
时,该值只会将值更改为 false
。这不是一般的,不会适用于其他一切,但它会在您的特定用例中完成工作。如果您只对禁用状态感兴趣,它甚至可能是首选的方式。如果你也想要一个例子,我可以扩展这个答案 - 告诉我。
Primefaces 4.0
我需要重置 p:dialog
中包含的组件的初始禁用状态。
以下简化示例显示了问题:
XML:
<p:dialog header="header" widgetVar="dialog" appendTo="@(body)"
modal="true" resizable="false">
<h:form id="form">
<p:inputText value="#{bean.text}" id="text" />
<p:commandButton value="Disable InputText"
action="#{bean.disableInputText}" />
<p:commandButton value="Cancel"
action="#{bean.cancelDialog}"
process="@this"
update="@form" immediate="true">
<p:resetInput target="@form"/>
</p:commandButton>
</h:form>
</p:dialog>
ManagedBean:
@ViewScoped
public class Bean {
public void disableText() {
final FacesContext context = FacesContext.getCurrentInstance();
final UIViewRoot root = context.getViewRoot();
final UIComponent component = root.findComponent(":text");
if (uiComponent instanceof InputText) {
((InputText) uiComponent).setDisabled(true);
}
}
public void cancel() {
// reset disable-state of the disable-state of all components in a generic way.
}
}
使用对话框时,可以禁用 p:inputText
元素。如果对话框被取消并再次打开,则不应禁用 inputText。应该已经恢复到初始状态了。请注意,这个例子是简化的,我正在寻找一个通用的解决方案,它也适用于具有 10 个以上输入元素的公式。
通用(也是最广泛的)解决方案
对于通用解决方案,您可以使用 Java Server Faces 中提供的状态保存功能。使用您的代码示例作为基础(进行一些小的更改以清理内容),这是一个使用状态保存并恢复组件先前状态的示例;
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Disable Test</title>
</h:head>
<h:body>
<p:dialog header="header" widgetVar="dialog" appendTo="@(body)" modal="true" resizable="false">
<h:form id="form">
<p:inputText value="#{disableTestBean.text}" id="text"/>
<p:commandButton value="Disable InputText" action="#{disableTestBean.onDisable}" update="@form" />
<p:commandButton value="Cancel" action="#{disableTestBean.onCancel}" update="@form" onsuccess="PF('dialog').hide()" />
</h:form>
</p:dialog>
<button onclick="PF('dialog').show()">Open</button>
</h:body>
</html>
要真正看到重置发生,从第二个 commandButton
中删除 onsuccess
属性 - 因为它当前关闭对话框。
@Data
@Named
@ViewScoped
public class DisableTestBean implements Serializable {
private String text;
private Object prevState;
private UIComponent findComponent(String where) {
final FacesContext context = FacesContext.getCurrentInstance();
final UIViewRoot root = context.getViewRoot();
return (UIComponent) root.findComponent(where);
}
public void onDisable() {
final InputText component = (InputText) findComponent(":form:text");
component.setDisabled(false);
component.setValue("");
prevState = component.saveState(FacesContext.getCurrentInstance());
component.setValue("meh");
component.setDisabled(true);
}
public void onCancel() throws IOException {
final InputText component = (InputText) findComponent(":form:text");
component.restoreState(FacesContext.getCurrentInstance(), prevState);
}
}
该示例针对一个特定的输入组件。但是,如果你需要处理多个组件,你可以很容易地使用一个循环来以通用的方式完成你想要的。
作为演示,我不仅重置了上面支持 bean 中的禁用状态,还重置了输入组件的值(内容)。这向您展示了如何实际重置组件的完整状态(不仅是单个属性或值)。所以解决方案很广泛,也很通用。
第二种更直接的方法
第二种方法是做 @Kukeltje 在他上面的评论中暗示的事情。在输入组件上使用 disabled=
属性,并有一个支持 bean 值,当您按 Cancel
时,该值只会将值更改为 false
。这不是一般的,不会适用于其他一切,但它会在您的特定用例中完成工作。如果您只对禁用状态感兴趣,它甚至可能是首选的方式。如果你也想要一个例子,我可以扩展这个答案 - 告诉我。