3

DataTableでのInCell編集と検証の両方を使用したいと思います。慣用名はf:validatorで解決できることは知っていますが、慣用名ではどうでしょうか。

たとえば、「name」プロパティがテーブル内で一意であることを確認する必要があります。したがって、編集を受け入れる前に、名前が変更されているかどうか、および別の要素によって使用されているかどうかを確認する必要があります。その場合、編集を拒否する必要があります。

それを達成する方法は?私が理解しているように、eventListenerは編集が受け入れられたことのみを通知されるので、理論的にはそれに反応して元に戻すことができますが、ユーザーが「受け入れる」アイコンをクリックしたときに編集を拒否したいと思います。

4

1 に答える 1

6

ダニエルが言ったように、これには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 Validation(JSR-303)を使用して、ドメインレベルで検証を構成できます。JSFに依存せず、JPAと統合されるため、強くお勧めします。


Bean Validationを使用して、約束どおりに更新します。

まず、バリデーター:

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.

人のクラス:

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}" />

簡単ですよね?;-)

于 2013-01-08T23:06:28.087 に答える