2

I would like to know if it possible to push a value from inside a <ui:repeat> to a map, a set or a list?

I would like to pass the value of the <h:inputtext> to a set.

Code:

<ui:repeat var="_par" value="#{cmsFilterParameterHandler.normaleSuchParameter()}">

      <p:outputLabel value="#{_par.bezeichnung}" />
      <p:spacer width="5px" />
      <p:inputText id="me" value="#{??? push me to a set ???}"/>
      <br /><br />

</ui:repeat>
Kukeltje
  • 12,223
  • 4
  • 24
  • 47
LStrike
  • 1,598
  • 4
  • 26
  • 58

3 Answers3

3

With a Set, it is not possible as it doesn't allow referencing items by index or key. It's however possible with a List and a Map by just specifying the list index and map key in the input value.


With a List:

private List<String> list; // +getter (no setter necessary)

@PostConstruct
public void init() { 
    list = createAndFillItSomehow();
}
<ui:repeat value="#{bean.list}" varStatus="loop">
    <h:inputText value="#{bean.list[loop.index]}" />
</ui:repeat>

With a Map (only if your environment supports EL 2.2 or JBoss EL):

private Map<String, String> map; // +getter (no setter necessary)

@PostConstruct
public void init() { 
    map = createAndFillItSomehow();
}
<ui:repeat value="#{bean.map.entrySet().toArray()}" var="entry">
    <h:inputText value="#{bean.map[entry.key]}" />
</ui:repeat>

Noted should be that the canonical approach is to use a List of fullworthy javabeans. Let's assume a Javabean class named Par with properties id and value which maps exactly to a par table in DB with columns id and value:

private List<Par> pars; // +getter (no setter necessary)

@PostConstruct
public void init() { 
    pars = createAndFillItSomehow();
}
<ui:repeat value="#{bean.pars}" var="par">
    <h:inputText value="#{par.value}" />
</ui:repeat>

Either way, it works as good when using <p:inputText>, it's in no way related to PrimeFaces, it's in the context of this question merely a jQuery based JSF UI component library. Just replace h: by p: to turn it on.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Is it possible to write a value into the `inputText` and how will this value be written into the backed `List` (in the first case)? I think without explicit "clean" getter and setter (clean = without additional arguments) this does not work, does it? – MrD Aug 13 '13 at 14:32
  • I have no utter idea what you meant with "write a value into the `inputText`". Do you mean, you want to preserve/prefill some default values? Just do the job in `createAndFillItSomehow()` accordingly. Create `new ArrayList<>()`. Set the desired items in it, which can be `null` for an empty input, or `"foo"` for an input with "foo" prefilled. – BalusC Aug 13 '13 at 14:34
  • Or, do you mean updating the model values? JSF as being a MVC framrework already does that automatically. In the command link/button's action method, just access `list` or `map` the usual way. The submitted values are already updated in there. Think logically, this answer would otherwise have no point at all. – BalusC Aug 13 '13 at 14:37
  • Yes, I ment updating the model values - sorry for being inaccurate. So I tried your solution (which looks much better than mine below - which is a workaround since I wasn't able to do it your way) with a list and got an IllegalArgumentException during rendering the input-field. So i guess I'm missing another point... – MrD Aug 13 '13 at 15:07
  • 1
    Why don't you tell more about the exception and the stack trace? They are the whole answer at its own. If you're unable to interpret exceptions, you should not ignore them as if they are decoration, but you should share them with us. We can translate them for you in layman's terms. You know, once a problem is *understood*, the solution becomes completely obvious. – BalusC Aug 13 '13 at 15:09
  • Hmm - I would like to do so. But how can I? The comment-size is limited here and the stack-trace would be too long (and unreadable in the comment). Can you give me a hint? What I can do now is posting only an excerpt `java.lang.IllegalArgumentException: null at javax.el.ListELResolver.coerce(ListELResolver.java:168) at javax.el.ListELResolver.getValue(ListELResolver.java:51) at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54) at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72) [...]` – MrD Aug 14 '13 at 06:52
  • You're using JSF 1.x not JSF 2.x. `` is not supported in Facelets 1.x. – BalusC Aug 14 '13 at 10:23
1

I'm not sure, if I understood your requirements correctly. I suppose the following: You need a List of Strings in some backend and an ui:repeat tag to iterate over those strings with input-fields to edit them. Maybe there are some syntax-issues, but my idea should be clear:

public class Backend {
    private List<String> myStrings;

    public MyStringWrapper getMyStringWrapper(int index) {
        return new MyStringWrapper(index);
    }

    public class MyStringWrapper {
        private final int index;
        public MyStringWrapper(int index) { this.index = index; }
        public String getContent() { return myStrings.get(index); }
        public void setContent(String newContent) { myStrings.add(index, newContent); }
    }
}

In the frontend you use as follows:

<ui:repeat var="_index" value="#{backend.getIndexSequence()}">
  <p:inputText value="#{backend.getMyStringWrapper(_index).content}"/>
</ui:repeat>

Of course, you have to provide a getIndexSequence-method which produces a list of ints ranging from 0 to the size of the strings.

MrD
  • 1,255
  • 1
  • 10
  • 24
  • Ok, facing the fact that I am using JSF 1.2 (as discovered in the discussion above - sorry that I did not mention it), is it still a clumsy approach? I need getter- and setter-methods without an additional argument. So how can this be improved for JSF 1.x? Thanks – MrD Aug 20 '13 at 13:24
0

Do you mean like this?

<p:inputText id="me" value="#{_par.input}"/>

in BackBean:

public class Par implements Serializable {

private String inputText;
private String bezeichnung;

public Par()
{
}

public void setInput(String input)
{
this.inputText = input;
}

public String getInput()
{
return this.inputText
}

public void setBezeichnung(String bezeichnung)
{
this.bezeichnung = bezeichnung;
}

public String getBezeichnung()
{
return this.bezeichnung
}

}
Johan Nordli
  • 1,220
  • 3
  • 13
  • 26
  • Hi, the problem is, what to do if there are more than one items in the variable _par? Therefore I need something like a set or a list. What you are describing only stores a single string value. (or do I misunderstand you?) – LStrike Aug 13 '13 at 08:09
  • Ok look at my exempel now, if _par is an object. This will work – Johan Nordli Aug 13 '13 at 09:02
  • OK, that is indeed an option. But for this I would have to make the field inputText persisted to my database. It won't work with an transient object. In this case _par is only a list of string values (like a key for a map) an inputText should be a non persistant value for a document search. Any ideas for that. If not I have to figure out a workaround. – LStrike Aug 13 '13 at 09:29