我有一个<h:selectOneMenu>
。根据所选内容,将显示与所选内容相关的众多<div>
中的一个,而其他隐藏。
每个<div>
都有一些<h:inputText>
,它们分别写入不同的@ViewScoped
bean。其中一些<div>
甚至会写入Bean中的相同属性。
例如。
<div>
<h:outputLabel for="list" value="Items"/>
<div>
<h:message for="list"/>
<h:selectOneMenu id="list" value="#{bean.selectedItem}" >
<f:selectItem itemLabel="Select one"></f:selectItem>
<f:selectItems value="bean.someItemsList" />
</h:selectOneMenu>
</div>
</div>
<div id="item1">
<!-- some other input fields -->
<div>
<h:message for="item1input1"/>
<h:inputText id="item3input1" value="bean.thisIsTheSameProperty" />
</div>
</div>
<div id="item2">
<!-- some other input fields -->
</div>
<div id="item3">
<!-- some other input fields -->
<div>
<h:message for="item3input1"/>
<h:inputText id="item3input1" value="bean.thisIsTheSameProperty" />
</div>
</div>
问题:当我选择一个显示<div>
(例如<div id="item1">
)的项目时,还有另一个隐藏的<div>
(例如<div id="item3">
)写入相同的bean属性(例如value="bean.thisIsTheSameProperty"
),并且用javax.validation.constraints.@NotNull
注释该属性,即使我给此输入字段赋值,当我提交表单时,我认为JSF也会运行隐藏的<div>
(通常没有输入集)。
我在调试过程中看到的内容:提交表单时,我看到Bean的setter将被调用两次。第一次使用我输入的正确valeus设置bean属性,但是第二次将使用空值调用setter。因此,由于@NotNull,验证将失败。
我的假设是JSF尝试两次设置Bean值,一次用于显示的<div>
上的输入字段,第二次设置隐藏的<div>
(因为它们指向相同的Bean属性) ),但对于隐藏的bean,则没有设置输入字段(它们为null)。
我根据从<div>
中选择的项目,使用jQuery显示/隐藏<h:selectOneMenu>
。
例如。
$('#item1').show();
$('#item1').hide();
$('#item2').show();
$('#item2').hide();
$('#item3').show();
$('#item3').hide();
有没有办法说JSF根本不考虑隐藏的<div>
?
答案 0 :(得分:3)
您似乎假设隐藏的输入(通过CSS隐藏)未提交到服务器。这种假设是错误的,顺便说一句是html内容,与JSF无关。
例如参见Stop an input field in a form from being submitted
但是,它仍然允许通过浏览器开发人员工具的客户端操作来“攻击”您的应用程序。与所有炒作式javascript UI框架相反,JSF是一个成熟的'MVC framework',它内置了针对client-side manipulation/tampering and CSRF, XSS的保护,为此您需要其他框架中的OWASP相关功能。 (这一切使JSF(带有PrimeFaces,OmniFaces和DeltaSpike)对我来说仍然是一个快速开发面向业务的应用程序的好框架。)
最好使用ajax
到conditionally render one div or the other,但是如果定义'update' the divs就像拥有它们,则不能使用Ajax update/render does not work on a component which has rendered attribute。
另请参见:
答案 1 :(得分:0)
@Kukeltje的回答和@drkunibar的评论对我有用。 我做了一点修改。
实际解决方案:
$('#myForm').submit(function() {
if($('#list').find(':selected').val() === 'itemOption1') {
$('item3').remove();
} else if($('#list').find(':selected').val() === 'itemOption3') {
$('item1').remove();
}
});
我检查以查看选择了哪个选项。如果选择了option1,则从DOM中删除ID为div
的{{1}},否则,如果我选择了ID3,则从DOM中删除ID为item3
的{{1}} 。
这样,绑定div
仅发送一次,并且不会覆盖这些值。
谢谢。