JSF 2.0动态控制哪些值基于CSS返回

Dav*_*ave 2 css myfaces filter jsf-2 phaselistener

我有这个表单,有170个单独的文本框,在会话范围的bean中有值.需要仅在组件具有特定CSS类时提交值.

我最初接近这个的方法是在UPDATE_MODEL_VALUES创建一个PhaseListener并在那里测试CSS类.如果该类是受影响的类,我将组件的值设置为null.然后在前端,我使用通用JavaScript方法切换焦点类.这意味着每个组件的更改我只需要添加:

... styleClass="examfieldgrey" onfocus="whiteField(this);"
Run Code Online (Sandbox Code Playgroud)

鉴于我需要改变多少组件,这是一种很好的方式.

这工作正常,直到我重新考虑我的电子表格以使用多个h表格标签.现在CSSclass正在切换前端,但是没有保存此更改.阶段监听器正在获得旧班级.

我认为这显然与我在jQuery/javascript中切换类有关.我想知道的是:

  1. 有没有更好的方式来做到这一点?一个最好意味着我不必修改170多个组件?
  2. 如果我必须继续使用Javascript切换类,有没有办法可以从javascript发回更改?

很抱歉,如果这是一个显而易见的问题,我对JSF生命周期仍然有点青睐.

我正在使用JSF 2.0 MyFaces

这里的参考是我的表单上需要过滤的组件的示例:

<h:inputTextarea 
  id="inputVal" 
  styleClass="midTextArea examfieldgrey"
  onfocus="whiteField(this);"
  value="#{bean.form.val}"/>
Run Code Online (Sandbox Code Playgroud)

其中"examfieldgrey"是我在确定是否要阻止组件时测试的类.

和whiteField方法:

function whiteField(field){
    if(! jQuery(field).hasClass("examfieldgrey")){
        return;
    }
    jQuery(field).removeClass("examfieldgrey");
    jQuery(field).addClass("examfieldwhite");
}
Run Code Online (Sandbox Code Playgroud)

我的阶段监听器在阶段方法之前我过滤:

// 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--;
}
Run Code Online (Sandbox Code Playgroud)

忽略打印​​功能,他们什么都不做;)

多谢你们!

编辑

这是一个复制操作,因此在构造bean之后,backing bean在其中具有值.如果我点击提交并且尚未填充支持bean,则使用primefaces选择器的选项很棒.但我不确定它是否能够真正清除这些价值观.

另外需要注意的是,我在表单对象的实例中引用了值.我不知道这是否有帮助,但我原来的帖子中没有.

Bal*_*usC 5

需要仅在组件具有特定CSS类时提交值.

如果你碰巧使用PrimeFaces已经或正在打开即可使用它,因为最新的3.3版本,你可以使用新的@()选择,它接受基于jQuery的CSS选择器语法processupdatePrimeFaces AJAX组件的属性(这相当于executerenderJSF标准的属性,<f:ajax>成分).

例如

<p:commandButton ... process="@(.foo)" />
Run Code Online (Sandbox Code Playgroud)

要么

<p:ajax ... process="@(.foo)" />
Run Code Online (Sandbox Code Playgroud)

将指示JSF 处理classname为的HTML输入元素foo.


现在CSSclass正在切换前端,但是没有保存此更改.阶段监听器正在获得旧班级.

那是因为你没有让服务器端的JSF组件树与客户端的HTML DOM树保持同步.您只是在客户端进行更改而不通知JSF.CSS类没有作为请求参数发送到服务器端,只有HTML表单输入值.您基本上需要通过JSF而不是JS/jQuery来更改CSS类,以便更改也反映在JSF组件树中.

然而,实现这一点并非完全无足轻重且可能浪费.因此,最简单的方法是使用PrimeFaces及其@()选择器支持.此选择器在客户端评估,并转换为与选择器匹配的JSF可理解组件客户端ID字符串.因此,这充分考虑了客户端的变化.