jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [jsr372-experts mirror] Re: StateHelper inside Repeat

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Thu, 26 Feb 2015 10:53:08 -0500

Hi

If h:dataTable has a property called rowStatePreserved to deal with the state,
why ui:repeat doesn't have it?

<ui:repeat ... rowStatePreserved="true">
   <my:comp />
</ui:repeat>

The only change we need into the spec is add one property to the component
and that's it. It will work just like UIData does.

This is old history. See this blog entry.

http://lu4242.blogspot.com/2011/06/jsf-component-state-per-row-for.html

In tomahawk t:dataList this problem was solved using rowStatePreserved
property.

The issue is already in the spec issue tracker:

https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1263
https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1230

I think this is one known problem that refuses to get fixed, and it is pointed
out over and over.

regards,

Leonardo Uribe

2015-02-25 17:54 GMT-05:00 Edward Burns <edward.burns_at_oracle.com>:
>>>>>> On Tue, 24 Feb 2015 16:05:50 +0200, Cagatay Civici <cagatay.civici_at_gmail.com> said:
>
> CC> When a component uses state map via stateHelper a problem occurs in
> CC> case the component is inside Data iteration.
>
> CC> For example there is a data iteration with ui:repeat from 0 to 9,
> CC> comp keeps mystate in state helper in first index which is 0, for
> CC> all other iterations from 1 to 9 mystate will be same.
>
> CC> getStateHelper().put(mystate, somevalue);
>
> CC> <ui:repeat>
> CC> <my:comp />
> CC> </ui:repeat>
>
> CC> Cant the JSF runtime create a unique state map using client id of
> CC> the my:comp? So that the component can have a separate state map
> CC> when we try to put and get from the map.
>
> CC> Or would you suggest setting the state value using client id like;
>
> CC> getStateHelper().put(this.clientId + mystate, somevalue);
>
> On Wednesday, February 25, 2015, Hanspeter <hampidu_at_gmail.com> wrote:
>
>>>>>> On Wed, 25 Feb 2015 10:41:52 +0100, arjan tijms <arjan.tijms_at_gmail.com> said:
>
> HP> So there might be iteraring components that do no proper children state
> HP> handling per iterarion - these need to be fixed.
>
> As Hanspeter points out, StateHolder.saveState() for an instance of a
> component gets called once, even when the component is placed inside of
> an iterating component. This is correct and certainly will not be
> changing. I've coded up a sample app and uploaded it to
> <https://java.net/projects/javaserverfaces-spec-public/downloads/download/JSF_2_3/Early%20Draft%20Review/repeatStateMap.zip>.
>
> Here's index.xhtml
>
> <html xmlns="http://www.w3.org/1999/xhtml"
> xmlns:h="http://java.sun.com/jsf/html"
> xmlns:my="http://xmlns.jcp.org/jsf/component"
> xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
> <head>
> <title></title>
> </head>
> <body>
> <h:form prependId="false">
> <ui:repeat value="#{userBean.fruit}" var="cur">
> <p>#{cur} <my:myInputText value="#{userBean.fruitValues[cur]}" /> </p>
> </ui:repeat>
>
> <h:commandButton value="submit" />
> </h:form>
> </body>
> </html>
>
> Here's the component
>
> @FacesComponent(createTag = true)
> public class MyInputText extends HtmlInputText {
>
> @Override
> public Object saveState(FacesContext context) {
> StateHelper stateHelper = this.getStateHelper(true);
> stateHelper.put("foo", "" + System.currentTimeMillis());
>
> Object result = super.saveState(context);
> return result;
> }
>
> @Override
> public void encodeAll(FacesContext context) throws IOException {
> super.encodeAll(context);
> String stateHelperValue = "" + this.getStateHelper(true).get("foo");
> ResponseWriter writer = context.getResponseWriter();
> writer.startElement("p", this);
> writer.writeText(stateHelperValue, "stateHelperValue");
> writer.endElement("p");
> }
> }
>
> Here's the managed bean
>
> @Named
> @RequestScoped
> public class UserBean implements Serializable {
> private static final long serialVersionUID = -6249152971686287687L;
>
> private List<String> fruit;
> private Map<String, String> fruitValues;
>
> @PostConstruct
> private void init() {
> fruit = new ArrayList<>();
> fruit.add("apple");
> fruit.add("orange");
> fruit.add("pear");
> fruit.add("banana");
>
> fruitValues = new HashMap<>();
> }
>
> public List<String> getFruit() {
> return fruit;
> }
>
> public Map<String, String> getFruitValues() {
> return fruitValues;
> }
>
> }
>
> My question: what's the problem? If you need to save state in the
> component that is relative to a particular run through the items of the
> enclosing collection, then it's your responsibility to make that happen
> somehow within the existing design. I'm open to adding something here,
> but I don't understand what. Please someone elaborate.
>
> AT> I don't have a direct answer to Cagatay's question, but I do like to remark
> AT> it would be beneficial if we'd had a proper base class for iterating
> AT> components. Currently UIRepeat, UIData and what else is out there have to
> AT> implement the same features and get the same fixes all the time.
>
> I recall our old colleague Matthias Wessendorf filed
> JAVASERVERFACES_SPEC_PUBLIC-935 about this. Arjan, can you please take
> a look at that one and see if it fits? If so, and you care about it,
> please open a new thread with Subject: [935-StampingComponent]. Please
> don't discuss this further on this thread.
>
> Thanks,
>
> Ed
>
> --
> | edward.burns_at_oracle.com | office: +1 407 458 0017
> | 8 days til DevNexus 2015
> | 18 days til JavaLand 2015
> | 28 days til CONFESS 2015