validation - Setting a validator attribute using EL based on ui:repeat var -


i looking little bit of guidance today issue running into.

what trying accomplish build page on fly validation , all. end result allow user configure fields on page through administrative functions. below copy of code using test page loop through "configured" fields , write out fields using defined criteria.

<ui:repeat var="field" value="#{eventmgmt.eventfields}" varstatus="status">   <div class="formlabel">     <h:outputlabel value="#{field.customname}:"></h:outputlabel>   </div>   <div class="forminput">     <h:inputtext id="inputfield" style="width:# {field.fieldsize gt 0 ? field.fieldsize : 140}px;">       <f:validateregex  disabled="#{empty field.validationpattern}" pattern="#{field.validationpattern}"></f:validateregex>     </h:inputtext>     <h:message for="inputfield" showdetail="true" errorclass="errortext"></h:message>   </div> </ui:repeat> 

after page renders , attempt submit values field, following message "regex pattern must set non-empty value." means expression not populated. makes interesting me fields not have expression them disabled when el evaluated. can take same code #{field.validationpattern} , put in page , correct value written on page.

so, question(s) are: 1. possible? 2. @ point jsf container @ binding pattern validate regex? 3. doing wrong or right way ??

i running tomcat 7.0.22, mojarra 2.1.5, , eclipse ide.

this caused using <f:validateregex> properties depend on iterated item of <ui:repeat>.

the <f:xxx> tags tag handlers, not ui components. tag handlers parsed , evaluated when ui component tree built during view build time. el evaluated during view build time. <h:xxx> tags , <ui:xxx> tags <ui:repeat> ui components. el evaluated during view render time.

so in case, when <f:validateregex> parsed , executed, #{field} not available in current el scope , evaluates null.

there several ways work.

  • move validator class representing field , reference follows:

    <h:inputtext ... validator="#{field.validate}" /> 

    with in field class wherein manually instantiate it:

    public void validate(facescontext context, uicomponent component, object value) throws validatorexception {     if (pattern != null) {         regexvalidator regexvalidator = new regexvalidator();         regexvalidator.setpattern(pattern);         regexvalidator.validate(context, component, value);     } } 

  • or, wrap #{eventmgmt.eventfields} in listdatamodel<field> , bind validator #{eventmgmt} bean. way able set validator's properties based on row data:

    <h:inputtext ... validator="#{eventmgmt.validate}" /> 

    with in backing bean class behind #{eventmgmt}:

    private datamodel<field> model; private regexvalidator regexvalidator;  @postconstruct public void init() {     regexvalidator = new regexvalidator(); }  public void validate(facescontext context, uicomponent component, object value) throws validatorexception {     string pattern = model.getrowdata().getpattern();      if (pattern != null) {         regexvalidator.setpattern(pattern);         regexvalidator.validate(context, component, value);     } } 

  • or, create custom validator extends regexvalidator , set pattern custom attribute of component <f:attribute> , let validator intercept on that. <f:attribute> adds new attribute component unevaluated valueexpression, re-evaluated when call it. e.g.:

    <h:inputtext ...>     <f:validator validatorid="extendedregexvalidator" />     <f:attribute name="pattern" value="#{field.pattern}" /> </h:inputtext> 

    with

    @facesvalidator("extendedregexvalidator") public class extendedregexvalidator extends regexvalidator {      @override     public void validate(facescontext context, uicomponent component, object value) throws validatorexception {         string pattern = (string) component.getattributes().get("pattern");          if (pattern != null) {             setpattern(pattern);             super.validate(context, component, value);         }     }  } 

  • or, if happen use jsf utility library omnifaces, use <o:validator>. e.g.

    <h:inputtext ...>     <o:validator validatorid="javax.faces.regularexpression" pattern="#{field.pattern}" /> </h:inputtext> 

    yes, that's all. <o:validator> make sure attributes evaluated deferred expressions instead of immediate expressions.

see also:


Comments

Popular posts from this blog

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -