我想同時使用InCell編輯數據表和驗證。我知道瑣碎的驗證可以用f:validator來解決,但是用非平凡的名字是什麼?PrimeFaces DataTable InCell編輯 - 非平凡驗證
我必須說,確保'name'屬性在表中是唯一的。因此,在接受編輯之前,我應該檢查名稱是否已更改以及是否被其他元素使用。如果是這樣,編輯必須是拒絕。
如何實現它?據我所知,eventListener只會被通知編輯被接受,所以理論上我可以做出反應並將其恢復,但當用戶單擊「接受」圖標時,我寧願拒絕編輯。
我想同時使用InCell編輯數據表和驗證。我知道瑣碎的驗證可以用f:validator來解決,但是用非平凡的名字是什麼?PrimeFaces DataTable InCell編輯 - 非平凡驗證
我必須說,確保'name'屬性在表中是唯一的。因此,在接受編輯之前,我應該檢查名稱是否已更改以及是否被其他元素使用。如果是這樣,編輯必須是拒絕。
如何實現它?據我所知,eventListener只會被通知編輯被接受,所以理論上我可以做出反應並將其恢復,但當用戶單擊「接受」圖標時,我寧願拒絕編輯。
像丹尼爾說的那樣,你可以使用JSF驗證器。一個簡單的例子:
假設我們有一個人:
public class Person
{
// Just imagine getters and setters ;-)
private String firstName, lastName;
}
和一個非常簡單的後臺bean:
@ManagedBean
@ViewScoped
public class PersonBean
{
private List<Person> persons = new ArrayList<Person>();
@PostConstruct
private void init()
{
persons.add(new Person("John", "Doe"));
}
}
例如我們要確保頭名開頭大寫字母。我們不在乎姓氏是否以大寫字母開頭(因爲與IE或舊數據庫的兼容性,你知道,通常是怪異的)。
@FacesValidator("firstNameValidator")
public class FirstNameValidator implements javax.faces.validator.Validator
{
@Override
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException
{
if (!Character.isUpperCase(String.valueOf(value).charAt(0)))
{
FacesMessage msg = new FacesMessage("First name should start with a capital.");
throw new ValidatorException(msg);
}
}
}
現在顯示一切很好:
<p:growl id="growl" />
<h:form>
<p:dataTable value="#{bean.persons}" var="person" editable="true">
<p:ajax event="rowEdit" update=":growl"/>
<p:column headerText="first name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{person.firstName}" />
</f:facet>
<f:facet name="input">
<p:inputText validator="firstNameValidator"
value="#{person.firstName}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="last name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{person.lastName}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{person.lastName}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column>
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
如果你有興趣,驗證可以在域級別配置使用Bean驗證(JSR-303)。我強烈推薦它,因爲它不依賴於JSF並且它與JPA集成。
更新爲使用Bean驗證承諾:
首先,驗證:
public class FirstNameValidator implements ConstraintValidator<FirstUpper, String>
{
@Override
public void initialize(FirstUpper constraintAnnotation) { }
@Override
public boolean isValid(String value, ConstraintValidatorContext context)
{
return Character.isUpperCase(value.charAt(0));
}
}
註解我們將使用:
@Constraint(validatedBy = FirstNameValidator.class)
@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface FirstUpper
{
String message() default "{FirstUpper.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
注意消息我們宣稱"{FirstUpper.message}"
將解析爲資源包。該包必須位於您的類路徑的根目錄中,名稱爲ValidationMessages.properties
。要本地化,您可以添加一個區域代碼:ValidationMessages_en.properties
。
在該文件中聲明的消息:
FirstUpper.message=First name should start with a capital.
Person類:
public class Person
{
@FirstUpper
private String firstName;
private String lastName;
// Imagine the getters/setters again ;-)
}
而現在,在你的UI,你不必是指驗證,JSF是足夠聰明使用JSR-303進行驗證。因此,而不是這樣的:
<p:inputText validator="firstNameValidator" value="#{person.firstName}" />
只要使用此:
<p:inputText value="#{person.firstName}" />
容易吧? ;-)
但是,這仍然是實體級驗證程序,而不是實體級驗證程序,所以最微不足道的情況 –
Hibernate Validator的問題(我認爲你是指他)是有依賴擁有JBoss許可證,它不能在沒有費用的商業程序中簡單使用(至少合法部門已經找到它了) –
Hibernate驗證器是JSR-303的一個實現。像Apache公共許可證驗證(可能是Apache許可證)和Slring框架有多個。您也可以使用vanilla JavaEE bean驗證。在包javax.validation中已經有一些了。 – siebz0r
爲什麼你不能在'f:validator validatorId =「myNonTrivialValidator」'中做到這一點? ,只需用你的邏輯編寫自己的定製驗證器... – Daniel
這樣的驗證器是否可以訪問給定的數據bean或表格內容?我認爲驗證者只能訪問他們放置在 –
的字段,另外,我們不使用jsf驗證器,因爲它們在表單級別上激活,在每次提交時都比自定義代碼更難控制。但無論如何,jsf驗證程序只驗證單個字段,並且驗證可以依賴於多個字段 –