2013-02-08 15 views
8

JSF 2.0アプリケーションPrimefaces 3.3を使用しています。現在のところ、関連する<p:inputText>required="true"属性を使用している場合、ラベルにアスタリスクが付いた素敵な機能があります。JSF 2.0必須フィールドのデコレータ@NotNullを持つプロパティの場合

このフィールドは、@NotNull検証制約付きのBeanプロパティにバインドされています。冗長でエラーが発生しやすいように見えますが、Beanプロパティに@NotNullが既に注釈されている場合は、XHTMLにrequired="true"を追加する必要があります。

@NotNullでプロパティにバインドされたコンポーネントのラベルを自動的に装飾するためのフックや方法がありますか?

ご意見やご提案をいただければ幸いです。

+1

@dforce:どのPFバージョンを使用していますか? PF 4.0以降には設備が整っています。しかし、この問題は、これをネイティブにサポートしていないPF 3.3について言及しています。 – BalusC

+0

こんにちは、5.3.5を使用しています。どのように使用できますか?ありがとう – dforce

+0

@dforce新しい回答を通知されたかどうかわからないので、これは思い出させます:) –

答えて

3

注:これはハックです。それは内省

  1. の使用は基本的なレベルではありますが原因でそれはフィールドが@NotNullで注釈されている場合、あなたが知っておくべきこと、パフォーマンスへの影響を有することができます。ビュースコープBeanの場合は@PostConstructのような適切な場所でこのチェックを実行します。バッキングBean

    <p:inputText id="inputit" required="#{myBean.requiredAttribute}"/> 
    
3

内の変数にrequired属性は、このソリューションは、PF 6.0に基づいており、私はしません必要な属性

boolean requiredAttribute;   

@PostConstruct 
public void init{ 
Field theField = this.getClass().getField("theField"); 
NotNull theAnnotation = theField.getAnnotation(NotNull.class); 
if(theAnnotation != null){ 
    requiredAttribute = true; 
    } 
} 
  • バインドを決定するためにグローバル変数を宣言します以前のバージョンでBeanValidationMetadataExtractorが利用可能かどうかを覚えておいてください。とにかく、DIY抽出プログラムを作成するのは簡単な作業です。

    私にも同様の問題がありました。私の特定のケースで:

    • ユーザーは、特定のフィールドは(UIInputを読む)/
    • が、私はそれがすでに@NotNull/@NotBlankプロパティにバインドされていますので、試しにrequired="true"を繰り返したくはありません必要であることを知らされるべきですフィールド私の場合は
    • 、ラベル・コンポーネントが存在しないかもしれない(と私はアスタリスクを付し-ラベルを好きではありません)

    だから、ここで私がやっていることです:

    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:UIInput sがdata-requiredパススルー属性でレンダリングされているリスナーに

    <?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> 
    

    input[data-required='true'], 
    .ui-inputfield[data-required='true'], 
    *[data-required='true'] .ui-inputfield { 
        box-shadow: inset 0px 2px 2px #bf8f8f; 
    } 
    

    次のことができます。今すぐ

    <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ルールを使用しますこのリスナーを調整して、必要に応じてコンポーネントを設定するか、特定のニーズに適した別のアプローチを使用します。

    別のアプローチは次のようになります。

    • UILabelの代わりにUIInput
    • 取得ラベルのfor/forValueのValueExpressionに関連付けられているUIInputをリッスン
    • チェック検証制約
    • ため UIInput
    • が最終的に呼び出されますUIInput.setRequired(true)

    〜3000個のコンポーネントで複雑なページをテストしたため、パフォーマンスへの影響はごくわずかです。

  • 関連する問題