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中切换类有关.我想知道的是:
很抱歉,如果这是一个显而易见的问题,我对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选择器的选项很棒.但我不确定它是否能够真正清除这些价值观.
另外需要注意的是,我在表单对象的实例中引用了值.我不知道这是否有帮助,但我原来的帖子中没有.
需要仅在组件具有特定CSS类时提交值.
如果你碰巧使用PrimeFaces已经或正在打开即可使用它,因为最新的3.3版本,你可以使用新的@()选择,它接受基于jQuery的CSS选择器语法process和updatePrimeFaces AJAX组件的属性(这相当于execute和renderJSF标准的属性,<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字符串.因此,这充分考虑了客户端的变化.
| 归档时间: |
|
| 查看次数: |
773 次 |
| 最近记录: |