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}
inlistdatamodel<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
extendsregexvalidator
, set pattern custom attribute of component<f:attribute>
, letvalidator
intercept on that.<f:attribute>
adds new attribute component unevaluatedvalueexpression
, 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.
Comments
Post a Comment