如何以编程方式禁用JSF组件

时间:2015-05-18 11:42:22

标签: jsf-2 richfaces

我们有一个带有<rich:tab>的JSF应用程序,它根据存储在数据库中的某些配置显示字段,因此组件未在.xhtml页面中定义,但必须以编程方式生成,如下例所示:

Example of dinamically generated fields

组件在面板中生成:

<rich:tab id="someTab" header="#{msg['someHeader']}" immediate="true">
    <rich:messages/>
    <h:panelGrid id="generatedComponentsContainer"/>
</rich:tab>

组件生成示例(为简单起见而简化):

FacesContext ctx = FacesContext.getCurrentInstance();
UIPanel panel = (UIPanel) ctx.getViewRoot().findComponent("someForm:generatedComponentsContainer");

text = (UIInput) ctx.getApplication().createComponent(ctx, "javax.faces.Input", "javax.faces.component.UIInput");
text.getAttributes().put("label", someLabel);
panel.getChildren().add(text);

这些组件必须根据某些条件显示为禁用,因此我使用以下代码在需要时禁用它们:

if (!showEnabled) { text.getAttributes().put("disabled", "true"); }

此方法适用于UIInputHtmlInputTextarea,但它不适用于UICalendar,只会投放IllegalArgumentException (argument type mismatch)

如何禁用日历?

我一直想知道这段代码是否只是禁用客户端的组件,而是在服务器上启用它。这可能是一个安全威胁,因为有人可以通过Javascript启用组件并将表单提交给服务器。我不确定这是否可能,请告知我是否错了。

1 个答案:

答案 0 :(得分:0)

经过进一步研究后,我注意到有一些类扩展了我们在项目中使用的类。这些类具有禁用属性的getter / setter,它还会禁用服务器端的组件。我测试了这个以编程方式禁用组件并在浏览页面时删除了disabled属性以允许编辑和提交。提交表单时,值在请求中设置,但在服务器端被忽略。 Bean值保持不变。

我们使用的课程:

HtmlInputTextarea代替UIInput

HtmlInputText代替UIInput

我们已经在使用符合目的的UICalendar

代码示例:

HtmlInputText text = (HtmlInputText) ctx.getApplication().createComponent(
ctx, HtmlInputText.COMPONENT_TYPE, "javax.faces.component.html.HtmlInputText");

if (!showEnabled) { text.setDisabled(true); }

调试HtmlInputText的内容时,您可以看到一个ComponentStateHelper对象(名为stateHelper),它存储组件的禁用状态(以及其他数据)。它的超接口是StateHolder

public interface StateHolder
     

此接口由需要保存其状态的类实现   请求之间。

我知道组件的服务器端状态存储在此对象中,但我不确定它是仅存储在此处还是存储在更多点中,或者即使我对其目的的解释是正确的。专家的反馈非常有用。