You can use a validator method on the component. Since the row index
will be set, your method will be called for each row. If you need the
row data in addition to the value you are validating, the bind the
datatable (UIData) to your bean and call getRowData in your validator
method. Either way, you don't need binding at the sub-table component
level to validate. To use a method instead of an f:validator tag, you
need to make sure you use the right signature. Google validator
method. There is a good article on IBM.com on it. I would find it
myself but the iPod touch doesn't have a clipboard.
On 6/7/08, Guy Bashan <[EMAIL PROTECTED]> wrote:
> Thanks Volker,
> And more thanks for the complements ... ("seems like you also don't know how
> UIData works ") ;-).
> You are right I am not very well familiar with UIData. In general, data
> binding and bean validations are giving most of what I need (most of the
> time). But there always comes the time... and then, well... you see the
> results...
> Anyway, from the changes you made in the code, I have come to the
> conclusion, JSF is actually using only a single component (or components,
> depending of how many components there are in each datatable row) to build
> the table and not a component for each row as I assumed (I hope I am not
> wrong here...).
> This also makes your assumption correct: "I can't believe you
> getComponents ever return more than one component in the list?"
>
> Regarding: "But i still dont understand why you need this having the values
> in the model".
> I do have the values in the model. But I need the component in order to add
> the validation error (maybe I have a better way of doing it?, If I
> understood correct the whole story, I can do it using a validation method
> and component binding and I will have the proper components on each
> iteration, but I have one more complex validation, in which daypats should
> be checked for overlapping times, so each set of dayparts will have to be
> compared with the others).
>
> One more thing: it seems that this code:
> htmlDataTableDayParts.getRowCount(); always returns zero.
> Is it a proper behavior?
>
> Thanks,
> Guy
>
>
> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> Behalf Of Volker Weber
> Sent: Saturday, June 07, 2008 11:08 PM
> To: MyFaces Discussion
> Subject: Re: Datatable binding problem
>
> Hi Guy,
>
> seems like you also don't know how UIData works. I can't believe you
> getComponents ever return more than one component in the list?
>
>
> guessing the htmlDataTableDayParts is the UIData, try this:
>
>
> private boolean validateDayParts()
> {
> boolean isOk = true;
> HtmlSelectOneMenu htmlSelectOneMenuFrom =
> htmlDataTableDayParts.findComponent(''hourFrom");
> HtmlSelectOneMenu htmlSelectOneMenuTo =
> htmlDataTableDayParts.findComponent(''hourTo");
>
> for (int i = 0; i < htmlDataTableDayParts.getRowCount(); i++) {
> htmlDataTableDayParts.setRowIndex(i);
> if (htmlSelectOneMenuFrom.getValue().equals(-1) ||
> htmlSelectOneMenuTo.getValue().equals(-1))
> {
> isOk = false;
> htmlSelectOneMenuFrom.setValid(false);
>
> FacesUtil.addErrorMessage(htmlSelectOneMenuFrom.getClientId(FacesUtil.getFacesContext()),
> "#{bundle['cmp_targeting.time.fromTo.required']}");
> }
>
> }
> htmlDataTableDayParts.setRowIndex(-1); // this is important
> return isOk;
> }
>
>
> But i still dont understand why you need this having the values in the
> model.
>
>
> Regards,
> Volker
>
>
>
> 2008/6/7 Guy Bashan <[EMAIL PROTECTED]>:
>> Hi Volker,
>>
>> Here are both methods I am using:
>> private List<UIComponent> getComponents(UIComponent rootComponent, String
>> id)
>> {
>> List<UIComponent> components = rootComponent.getChildren();
>> List<UIComponent> result = new ArrayList<UIComponent>();
>> for (UIComponent component : components)
>> {
>> if (component.getId().equals(id))
>> {
>> result.add(component);
>> }
>>
>> result.addAll(getComponents(component, id));
>> }
>>
>> return result;
>> }
>>
>> private boolean validateDayParts()
>> {
>> List<UIComponent> hoursFrom = getComponents(htmlDataTableDayParts,
>> "hourFrom");
>> List<UIComponent> hoursTo = getComponents(htmlDataTableDayParts,
>> "hourTo");
>>
>> boolean isOk = true;
>> for (int i = 0; i < hoursFrom.size(); i++)
>> {
>> HtmlSelectOneMenu htmlSelectOneMenuFrom =
>> (HtmlSelectOneMenu)hoursFrom.get(i);
>> HtmlSelectOneMenu htmlSelectOneMenuTo =
>> (HtmlSelectOneMenu)hoursTo.get(i);
>>
>> if (htmlSelectOneMenuFrom.getValue().equals(-1) ||
>> htmlSelectOneMenuTo.getValue().equals(-1))
>> {
>> isOk = false;
>> htmlSelectOneMenuFrom.setValid(false);
>>
>> FacesUtil.addErrorMessage(htmlSelectOneMenuFrom.getClientId(FacesUtil.getFacesContext()),
>> "#{bundle['cmp_targeting.time.fromTo.required']}");
>> }
>> }
>>
>> return isOk;
>> }
>>
>> I call the method "validateDayParts" from a saveAction method that is
>> activated when pressing a command link.
>>
>> Thanks,
>> Guy.
>>
>>
>> -----Original Message-----
>> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
>> Behalf Of Volker Weber
>> Sent: Saturday, June 07, 2008 9:41 PM
>> To: MyFaces Discussion
>> Subject: Re: Datatable binding problem
>>
>> Hi Guy,
>>
>> could you post your loop code?
>>
>>
>> Regards,
>> Volker
>>
>>
>>
>> 2008/6/7 Guy Bashan <[EMAIL PROTECTED]>:
>>> Hi again,
>>>
>>>
>>>
>>> In order to validate set of dropdowns in a datatable, I wrote a method to
>>> extract all components with a specific id (under that datatable), then
>>> scan
>>> the returned values in a loop an and make sure values are properly set.
>>>
>>> The method is activated in the save action.
>>>
>>> It seems like the drop down component properties: "value" and
>>> "submittedValue" are null.
>>>
>>> (The data is passed to the bean objects properly and saved to database,
>>> but
>>> when getting it directly from the component it returns a null value).
>>>
>>>
>>>
>>> Am I missing something?
>>>
>>>
>>>
>>> Thanks,
>>>
>>> Guy.
>>>
>>>
>>>
>>>
>>>
>>> From: Andrew Robinson [mailto:[EMAIL PROTECTED]
>>> Sent: Saturday, June 07, 2008 4:50 PM
>>> To: MyFaces Discussion
>>> Subject: Re: Datatable binding problem
>>>
>>>
>>>
>>> You are not understanding how JSF databinding works. I'll give you a
>>> brief
>>> overview, but I would strongly recommend that you stop development and
>>> read
>>> some articles on control binding before continuing.
>>>
>>>
>>>
>>> The binding happens at component construction time, not render time. If
>>> this
>>> does not click, then read my blog at http://andrewfacelets.blogspot.com.
>>>
>>>
>>>
>>> In your case, the binding happens when the component tree is built. Which
>>> means that the data table has no data, no var that is set, etc. A data
>>> table
>>> has only one set of components that are re-rendered for each value. There
>>> are not new components for each value. Think of it as a swing tree that
>>> has
>>> a node rendered that is called to render every node - there is only one.
>>>
>>> Sent from my iPod
>>>
>>> On Jun 7, 2008, at 2:53 AM, Guy Bashan <[EMAIL PROTECTED]> wrote:
>>>
>>> Hi All,
>>>
>>>
>>>
>>> I am having a little problem with datatable and binding.
>>>
>>>
>>>
>>> Here is the code:
>>>
>>> <t:dataTable id="dayParts"
>>> value="#{targetingParam.cmpTargetDayParts}"
>>>
>>> var="dayPart" cellpadding="0" cellspacing="0"
>>> rowIndexVar="rowIndex">
>>>
>>> <t:column style="height:30px" rendered="#{!dayPart.deleted}">
>>>
>>> <h:selectOneMenu value="#{dayPart.startHour}"
>>> onchange="updateTargetingActivity(#{rowIndexParam});"
>>>
>>> id="hourFrom" styleClass="mform"
>>> style="width:75px;" converter="ByteConverter">
>>>
>>> <f:selectItems value="#{cmp_targeting.dayPartHoursFrom}"/>
>>>
>>> </h:selectOneMenu>
>>>
>>> <div>
>>>
>>> <h:message for="dayParts" errorClass="error_message" />
>>>
>>> </div>
>>>
>>> </t:column>
>>>
>>> </t:dataTable>
>>>
>>>
>>>
>>> It works all fine, and I see a table with values on the screen. Now, when
>>> I
>>> add binding to the dropdown:
>>>
>>> binding="#{dayPart.htmlSelectOneMenuDaypartFrom}"
>>>
>>>
>>>
>>> I get the following exception:
>>>
>>> org.apache.jasper.el.JspPropertyNotFoundException:
>>> /cmp_targeting.jsp(593,12) '#{dayPart.htmlSelectOneMenuDaypartFrom}'
>>> Target
>>> Unreachable, identifier 'dayPart' resolved to null
>>>
>>> at
>>> org.apache.jasper.el.JspValueExpression.setValue(JspValueExpression.java:91)
>>>
>>> at
>>> org.apache.myfaces.application.ApplicationImpl.createComponent(ApplicationImpl.java:315)
>>>
>>> at
>>> javax.faces.webapp.UIComponentELTag.createComponent(UIComponentELTag.java:91)
>>>
>>> at
>>> javax.faces.webapp.UIComponentClassicTagBase.findComponent(UIComponentClassicTagBase.java:1101)
>>>
>>> at
>>> javax.faces.webapp.UIComponentClassicTagBase.doStartTag(UIComponentClassicTagBase.java:431)
>>>
>>> at
>>> org.apache.jsp.cmp_005ftargeting_jsp._jspx_meth_h_005fselectOneMenu_005f1(cmp_005ftargeting_jsp.java:5394)
>>>
>>> at
>>> org.apache.jsp.cmp_005ftargeting_jsp._jspx_meth_t_005fcolumn_005f4(cmp_005ftargeting_jsp.java:5343)
>>>
>>> at
>>> org.apache.jsp.cmp_005ftargeting_jsp._jspx_meth_t_005fdataTable_005f3(cmp_005ftargeting_jsp.java:5290)
>>>
>>> at
>>> org.apache.jsp.cmp_005ftargeting_jsp._jspService(cmp_005ftargeting_jsp.java:1042)
>>>
>>> at
>>> org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>>>
>>> at
>>> javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
>>>
>>> at
>>> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
>>>
>>> at
>>> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
>>>
>>> at
>>> org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
>>>
>>> at
>>> javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:654)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:445)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:292)
>>>
>>> at
>>> org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(ServletExternalContextImpl.java:338)
>>>
>>> at
>>> org.apache.myfaces.application.jsp.JspViewHandlerImpl.buildView(JspViewHandlerImpl.java:481)
>>>
>>> at
>>> org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:334)
>>>
>>> at
>>> org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
>>>
>>> at
>>> org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:140)
>>>
>>> at
>>> org.apache.myfaces.custom.ppr.PPRLifecycleWrapper.render(PPRLifecycleWrapper.java:84)
>>>
>>> at
>>> javax.faces.webapp.FacesServlet.service(FacesServlet.java:152)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>>>
>>> at
>>> com.todacell.ui.view.filter.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:149)
>>>
>>> at
>>> com.todacell.ui.view.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:61)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>>>
>>> at
>>> org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:147)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
>>>
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>>>
>>> at
>>> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
>>>
>>> at
>>> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
>>>
>>> at
>>> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
>>>
>>> at
>>> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
>>>
>>> at
>>> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
>>>
>>> at
>>> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
>>>
>>> at
>>> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
>>>
>>> at
>>> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
>>>
>>> at
>>> org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
>>>
>>> at java.lang.Thread.run(Thread.java:619)
>>>
>>>
>>>
>>> In the bean I have the following code:
>>>
>>> private transient HtmlSelectOneMenu htmlSelectOneMenuDaypartFrom;
>>>
>>>
>>>
>>> public HtmlSelectOneMenu getHtmlSelectOneMenuDaypartFrom()
>>>
>>> {
>>>
>>> return htmlSelectOneMenuDaypartFrom;
>>>
>>> }
>>>
>>>
>>>
>>> public void setHtmlSelectOneMenuDaypartFrom(HtmlSelectOneMenu
>>> htmlSelectOneMenuDaypartFrom)
>>>
>>> {
>>>
>>> this.htmlSelectOneMenuDaypartFrom = htmlSelectOneMenuDaypartFrom;
>>>
>>> }
>>>
>>>
>>>
>>> i:embed'> {
>>>
>>> this.htmlSelectOneMenuDaypartFrom = htmlSelectOneMenuDaypartFrom;
>>>
>>> }
>>>
>>>
>>
>>
>>
>> --
>> inexso - information exchange solutions GmbH
>> Bismarckstraße 13 | 26122 Oldenburg
>> Tel.: +49 441 4082 356 |
>> FAX: +49 441 4082 355 | www.inexso.de
>>
>>
>
>
>
> --
> inexso - information exchange solutions GmbH
> Bismarckstraße 13 | 26122 Oldenburg
> Tel.: +49 441 4082 356 |
> FAX: +49 441 4082 355 | www.inexso.de
>
>