該解決方案基於PF 6.0,我不請記住,如果BeanValidationMetadataExtractor
在以前的版本中可用。無論如何,創建DIY提取器是一項簡單的任務。
我有一個類似的問題。在我的具體情況:
- 用戶應告知某一領域(讀
UIInput
)需要
- 我不想在補償重複
required="true"
,因爲它已經綁定到@NotNull
/@NotBlank
財產/現場
- 對我來說,一個標籤組件可能不存在(我不喜歡帶星號的標籤)
所以,這裏是我做了什麼:
import java.util.Set;
import javax.el.ValueExpression;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PreRenderComponentEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
import javax.validation.constraints.NotNull;
import javax.validation.metadata.ConstraintDescriptor;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import org.omnifaces.util.Faces;
import org.primefaces.context.RequestContext;
import org.primefaces.metadata.BeanValidationMetadataExtractor;
public class InputValidatorConstraintListener implements SystemEventListener
{
@Override
public boolean isListenerForSource(Object source)
{
return source instanceof UIInput;
}
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException
{
if(event instanceof PreRenderComponentEvent)
{
UIInput component = (UIInput) event.getSource();
component.getPassThroughAttributes().computeIfAbsent("data-required", k ->
{
ValueExpression requiredExpression = component.getValueExpression("required");
if(requiredExpression != null || !component.isRequired())
{
FacesContext context = Faces.getContext();
ValueExpression valueExpression = component.getValueExpression("value");
RequestContext requestContext = RequestContext.getCurrentInstance();
try
{
Set<ConstraintDescriptor<?>> constraints = BeanValidationMetadataExtractor.extractAllConstraintDescriptors(context, requestContext, valueExpression);
if(constraints != null && !constraints.isEmpty())
{
return constraints.stream()
.map(ConstraintDescriptor::getAnnotation)
.anyMatch(x -> x instanceof NotNull || x instanceof NotBlank || x instanceof NotEmpty);
}
}
catch(Exception e)
{
return false;
}
}
return false;
});
}
}
}
並在faces-config中聲明它。XML:
<?xml version="1.0" encoding="utf-8"?>
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<application>
<system-event-listener>
<system-event-listener-class>it.shape.core.jsf.listener.InputValidatorConstraintListener</system-event-listener-class>
<system-event-class>javax.faces.event.PreRenderComponentEvent</system-event-class>
</system-event-listener>
</application>
</faces-config>
此偵聽UIInput
s的渲染與data-required
直通屬性:
<input
id="form:editPanelMain:j_idt253"
name="form:editPanelMain:j_idt253"
type="text"
value="Rack Assemply"
size="80"
data-required="true" <============================ NOTE THIS!!
data-widget="widget_form_editPanelMain_j_idt253"
class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all"
role="textbox"
aria-disabled="false"
aria-readonly="false">
現在,我使用的CSS規則來突出這些領域:
input[data-required='true'],
.ui-inputfield[data-required='true'],
*[data-required='true'] .ui-inputfield {
box-shadow: inset 0px 2px 2px #bf8f8f;
}
你可以讓聽衆根據需要設置組件或使用另一種適合您特定需求的方法。
另一種方法可以是:
- 聽
UILabel
!而非UIInput
小號
- 獲得與標籤的
for
/forValue
ValueExpression相關的UIInput
- 檢查
UIInput
爲驗證約束
- 最終調用
UIInput.setRequired(true)
性能影響可以忽略不計,因爲我測試了具有〜3000組件的複雜頁面。
@dforce:你使用哪個PF版本?由於PF 4.0有內置設施。然而,這個問題提到PF 3.3本身並不支持這一點。 – BalusC 2017-05-22 12:04:18
嗨,我們正在使用5.3.5。它如何被使用?謝謝 – dforce 2017-05-22 14:43:29
@dforce我不知道你是否收到新答案的通知,所以這是一個提醒:) – 2017-05-29 08:17:46