我有这个表单,其中包含约 170 个单独的文本框,其中包含会话范围 bean 中的值。要求仅在组件具有特定 CSS 类时才提交值。
我最初的方法是在 UPDATE_MODEL_VALUES 创建一个 PhaseListener 并在那里测试 CSS 类。如果该类是受影响的类,我将组件的值设置为 null。然后在前端,我使用通用 JavaScript 方法将类切换为焦点。这意味着我只需要添加对每个组件的更改:
... styleClass="examfieldgrey" onfocus="whiteField(this);"
考虑到我需要更改多少组件,这很好。
在我重构我的 e 表单以使用多个 h 表单标签之前,这一切正常。现在 CSSclass 正在前端切换,但没有保存此更改。相位侦听器正在获取旧类。
我认为这显然与我在 jQuery/javascript 中切换类有关。我想知道的是:
- 有没有更好的方法来做到这一点?一个最好意味着我不必修改 170 多个组件?
- 如果我必须继续使用 Javascript 来切换课程,有没有办法可以将更改从 javascript 发布回来?
抱歉,如果这是一个明显的问题,我对 JSF 生命周期还是有点陌生。
我正在使用 JSF 2.0 MyFaces
作为参考,这里是我的表单上需要过滤的组件的示例:
<h:inputTextarea
id="inputVal"
styleClass="midTextArea examfieldgrey"
onfocus="whiteField(this);"
value="#{bean.form.val}"/>
其中“examfieldgrey”是我在确定是否要阻止组件时测试的类。
和 whiteField 方法:
function whiteField(field){
if(! jQuery(field).hasClass("examfieldgrey")){
return;
}
jQuery(field).removeClass("examfieldgrey");
jQuery(field).addClass("examfieldwhite");
}
以及我过滤的阶段方法之前的阶段侦听器:
// TODO: make whatever mode allows ghosting to be configurable outside of
// the system (perhaps in the config file)
/**
* Before the model is updated, test each component's CSS on the form. If the
* CSS style is 'examfieldgrey' set the value to null so it doesn't get submitted
*/
@Override
public void beforePhase(PhaseEvent arg0) {
//We need the session to get the backing bean
if (arg0.getFacesContext().getExternalContext().getSessionMap() == null) {
return;
}
//get the measurements bean so we can determine the form mode
if (arg0.getFacesContext().getExternalContext().getSessionMap()
.get("measurements") == null) {
return;
}
//ensure the bean is the expected data type, it should always be this type. I'm just paranoid ;)
if (!(arg0.getFacesContext().getExternalContext().getSessionMap()
.get("measurements") instanceof MeasurementsController)) {
return;
}
//get, convert and check the backing bean's mode. We only filter if the mode is COPY
if (((MeasurementsController) arg0.getFacesContext()
.getExternalContext().getSessionMap().get("measurements"))
.getMode() != FormMode.COPY) {
return;
}
//recursivly traverse the componenets and filter the ones who have the CSS class
traverseChildren(arg0.getFacesContext().getViewRoot().getChildren());
}
/**
* Traverse a List of UIComponenets and check the CSS. If it's the 'examfieldgrey' class
* and the component is a UIInput component, set the value to null.
* @param children a List of the componenets to filter on the form.
*/
private void traverseChildren(List<UIComponent> children) {
debugLevelCount++;
if (children == null || children.size() == 0) {
debugLevelCount--;
return;
}
for (UIComponent component : children) {
if (component instanceof UIInput) {
if (component.getAttributes() != null
&& component.getAttributes().get("styleClass") != null
&& component.getAttributes().get("styleClass")
.toString().contains("examfieldgrey")) {
((UIInput) component).setValue(null);
} else {
debugPrintAllow(component);
}
continue;
}
traverseChildren(component.getChildren());
}
debugLevelCount--;
}
忽略打印功能,它们什么都不做;)
多谢你们!
编辑
这是一个复制操作,因此支持 bean 在构建 bean 之后在其中具有值。如果我点击提交并且支持 bean 尚未填充,则使用 primefaces 选择器的选项非常好。但我不确定它是否能够真正清除这些值。
需要注意的另一件事是,我在表单对象的实例中引用了值。我不知道这是否有帮助,但它没有出现在我的原始帖子中。