0

I am trying to bind an input box to an entry in a multivalue field, Something like this:

<xp:repeat id="repeat6" rows="30" var="rows" indexVar="ind">
    <xp:this.value><![CDATA[#{javascript:order.getItemValue("ArtNo")}]]></xp:this.value>
    <xp:inputText id="inputText9" style="width:20px" value="#{order.ArtQuantity[ind]}">
</xp:repeat>

When there are two values in ArtNo field it works but not when there is a single value. My guess here is that when there is only one entry it is no longer an array as I get the this error:

Error getting property '0' from bean of type java.lang.Double - PropertyNotFoundException Error, cannot locate component:

how can I fix my code so that the EL code order.ArtQuantity[ind] always work, i.e is always an array?

thanks

Thomas

Thomas Adrian
  • 3,543
  • 6
  • 32
  • 62

2 Answers2

2

You can alter repeat with simple text binded to #{order.ArtQuantity}. Rendered property can alter these two based on isArray check.

UPDATE

As commented by Knut, shilem's solution does not work. My conclusion:

  • multivalue check does not work - you can't get size() from scalar value returned by getItemValue from field with only one value. Simple change to make it work: getComponent("repeat6").getRowCount() == 1 and for multiple values getComponent("repeat6").getRowCount() > 1. Ugly, I know.
  • Binding to Vector elements does not work. It should (like here: https://stackoverflow.com/a/6743138/206265). It fails with datasource - it seems that applying submitted value for [n]th element is done over some temporary Vector retrieved by first part of the binding order.artQuantity. Document's field is not updated. Seems to be a bug.

Possible workaround is to create dedicated control, that will handle all edits into internal store (backing bean, scoped variable, dataContext) and updates the document once with combined value of all elements of the list.

Frantisek Kossuth
  • 3,524
  • 2
  • 23
  • 42
  • How does it work with let's say ArtQuantity having three elements? How do you get each element within the repeat? The repeat variable is based on ArtNo, not ArtQuantity. So, the index variable `ind` has to be used somewhere... – Knut Herrmann Sep 06 '17 at 06:07
  • Good point. I assume ArtQuantity is shadow field with the same number of elements as ArtNo. In that case for every value in ArtNo one line of repeat shows ArtQuantity value. – Frantisek Kossuth Sep 06 '17 at 15:02
  • Yes, I assume that too. But, if you use `#{order.ArtQuantity}` as inputText value, then for *every* ArtNo *all* ArtQuantity are shown in input text field. – Knut Herrmann Sep 06 '17 at 15:24
  • Look at @shillem's demo. It should work only if `artQuantity` is mantained at the same value count as `artNo`. Or there should be `artNo` reference in rendered formula. – Frantisek Kossuth Sep 07 '17 at 08:33
  • No, it doesn't work. Even with the same value count of ArtNo and ArtQuantity. I tested it. – Knut Herrmann Sep 07 '17 at 08:42
1

The approach you are currently using tells me you have no bean management, let alone any better DAO/DTO pattern in place besides what XPages offers out of the box.

There's an inelegant solution for that (what can one expect? SSJS is the epitome of inelegance):

<xp:repeat value="#{order.artNo}" var="artNo" indexVar="n">
    <xp:inputText value="#{order.artQuantity}"
        rendered="#{javascript: order.getItemValue('artQuantity').size() === 1}">
        <xp:this.converter>
            <xp:convertNumber />
        </xp:this.converter>
    </xp:inputText>
    <xp:inputText value="#{order.artQuantity[n]}"
        rendered="#{javascript: order.getItemValue('artQuantity').size() > 1}">
        <xp:this.converter>
            <xp:convertNumber type="number" />
        </xp:this.converter>
    </xp:inputText>
</xp:repeat>

Basically one of the 2 input controls is rendered based on the number of values present in artQuantity. In this way, any update to any of the artQuantity field instance values will be automatically saved back to the document item. This is the quickest and dirtiest way to do it.

shillem
  • 1,260
  • 7
  • 12