0
votes

For my XPage I developed some Managed Beans to keep data. The page itself contains a Repeat control, it's like this at the moment:

<xp:panel styleClass="form">
    <xp:this.dataContexts>
        <xp:dataContext value="#{javascript:PageData.getForm(compositeData.formName, compositeData.dataSource);}"
            var="myFormData">
        </xp:dataContext>
        <xp:dataContext var="myFields">
            <xp:this.value><![CDATA[#{javascript:return myFormData.getFieldsAsJSON();}]]></xp:this.value>
        </xp:dataContext>
    </xp:this.dataContexts>
    <xp:table style="width:100%" cellspacing="1" cellpadding="0">
        <xp:repeat var="thisfield" rows="#{javascript:compositeData.rows}" disableTheme="true" repeatControls="true"
            disableOutputTag="true" value="#{myFields}">

The PageData object is a bean, it contains info about a form and its fields. The dropdown fields contain options, but they can be dynamically created. When that happens, as a result of a partial refresh, the form is redisplayed but... the repeat 'value' itself (myFields) isn't reloaded into the repeat, so new dropdown options aren't made available.

How can I make XPages reload the 'value' property?

UPDATE More info, as requested...

From the FormData bean:

public Object getFieldsAsJSON() {
    ArrayObject list = null;

    try {
        System.err.print("FormData: getFieldsAsJSON");
        list = new ArrayObject();
        for (Entry<String, FieldData> e : fields.entrySet()) {
            FieldData field = e.getValue();
            list.addArrayValue(field.getJSON());
        }

    } catch (Exception e) {

    }
    return list;
}

and from the FieldData bean:

public ObjectObject getJSON() throws InterpretException {
    ObjectObject json = new ObjectObject();
    json.put("name", FBSUtility.wrap(name));
    json.put("label", FBSUtility.wrap(field.getLabel()));
    json.put("options", FBSUtility.wrap(values));
    return json;
}

IMHO the problem isn't in these beans. It's more an XPages issue, because for some strange reason the structure is only fetched once, and never again. Apparently, XPages considers the json to be static, which it isn't.

Before the bean-era, I had everything in SSJS, creating the JavaScript object on the fly, and it was reloaded every time. Why not anymore, what is the difference? Is there something to tell XPages that the repeat-value is 'stale' and should be re-read?

1
I now do have a work-araound: the object isn't re-evaluated, and thisfield in the example above isn't changed, but... myFields[indexVar].options is !D.Bugger

1 Answers

0
votes

With your current code myFormData and myFields will be recalculated during every partial refresh as well. Is that necessary?

I'm not certain, but looking at what you're seeing, I suspect the repeat control needs the contents of the dataContexts at a particular phase of the XPages lifecycle. But the dataContexts will be recalculated at every phase of the XPages lifecycle, which may result in them being null when the repeat wants to use the values.

My best advice is to debug what's happening at which phases in the partial refresh. You'll probably need to change your code to work around what's calculated when.

I'm not convinced dataContexts set to be computed dynamically are a good approach unless you're using them for rendered properties or read-only data. If you're using a managed bean, lazy-loading the data and retrieving it directly from the bean may be a better approach, as well as making it easier to identify when it's being called.