2

Problem: I am passing an EL expression to a composite component, but the EL expression is being evaluated from inside the composite component, rather than before. The intention being that the EL expression evaluates to a string with is sent to the composite component.

I have a composite component, MenuTable:

<cc:interface>
    <cc:attribute name="model" type="nz.co.tradeintel.web.MenuTable"/>
    <cc.attribute name="updateId" /> 
</cc:interface>

<cc:implementation>
    <h:panelGroup id="menuTable">
    <table>
        <ui:repeat id="repeat1" value="#{cc.attrs.model.rows}" var="row">
            <tr>
            <ui:repeat id="repeat2" value="#{row.contents}" var="entry">
                <td>
                    <p:commandLink action="#{cc.attrs.model.setSelected(entry)}" update="#{cc.attrs.updateId}" value="#{entry.toString()}"/>
                </td>
            </ui:repeat>
            </tr>
        </ui:repeat>
    </table>
    </h:panelGroup>
</cc:implementation>

The intention is that I pass an absolute component ID as the attribute updateId like this:

<p:PanelGroup id="updatingPanel">
    <!-- Lots of components.-->
</p:PanelGroup>
<custom:MenuTable updateId="#{component.clientId}:updatingPanel" model="#{menuBackBean.menuTable}" />  

The problem is, the EL expression for the updateId is evaluated from the scope of the <p:commandLink /> within the composite component, and I get the following error:

javax.faces.FacesException: Cannot find component with identifier ":j_idt37:j_idt39:updatingPanel:j_idt61:repeat1:0:repeat2:0:j_idt65:updatingPanel" referenced from "j_idt37:j_idt39:updatingPanel:j_idt61:repeat1:0:repeat2:0:j_idt65".

Note: JSF thinks I am trying to update a component with and ID of updatingPanel which is inside the composite component.

Why is the EL expression not evaluated from the outer scope: <custom:MenuTable/>?

There are a few related answers, but I don't understand them, such as this one.

Using Mojarra 2.1.15

Community
  • 1
  • 1
Kevin
  • 4,070
  • 4
  • 45
  • 67

1 Answers1

7

EL expressions are not evaluated at the moment the component is built, but at the moment the attribute is accessed. In other words, they're runtime and not buildtime. The #{component} refers to the current UI component at the moment the EL expression is evaluated, which is in your particular case the <p:commandLink>. That explains the different outcome.

You need to approach this differently, without using #{component}. One of the ways is

<p:panelGroup binding="#{updatingPanel}">
    ...
</p:panelGroup>
<custom:MenuTable ... updateId=":#{updatingPanel.clientId}" />

If that still doesn't work, then make sure that you don't use <h:form prependId="false">.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I get a new error: `javax.faces.FacesException: Cannot find component with identifier ":j_idt37:j_idt39:updatingPanel" referenced from "j_idt37:j_idt39:j_idt62:repeat1:0:repeat2:0:j_idt66"`. It looks like the generated ID is correct, but is still not being recognized. I have a feeling you solved the problem, and I've uncovered something new. – Kevin Jan 11 '13 at 11:59
  • Try giving the naming container parents a fixed ID. – BalusC Jan 11 '13 at 12:02
  • Same error, with pretty names: `javax.faces.FacesException: Cannot find component with identifier ":sellingAdvice:listingSearher:updatingPanel" referenced from "sellingAdvice:listingSearher:menuTable:repeat1:0:repeat2:0:j_idt64"`. I have all the relevant components within a `` with is rendered on demand. Could this interfere with resolving IDs? – Kevin Jan 11 '13 at 12:09
  • No, the `rendered` condition is not considered when searching for component. However, build time tags like `` and `` will do. Do you have any of them? – BalusC Jan 11 '13 at 12:13
  • No, I have learned the hard way to stay away from `` and ``. When I look at the generated HTML, the ID it apparently cant find is correct, so I'm am lost as to why it is having issue. And the ID is absolute, so I should start searching from the Root. – Kevin Jan 11 '13 at 12:15
  • Which JSF impl/version? Mojarra has for long problems with nested ``. Mojarra 2.1.14 contained several "major" fixes to that. It's currently at 2.1.17. – BalusC Jan 11 '13 at 12:17
  • Mojarra 2.1.15. Yea, I moved from 2.1.13 & 14 due to `` issues. I'll try switch to 2.1.17 now. – Kevin Jan 11 '13 at 12:20
  • 2.1.15 has some issues related to component state management, so a newer version may indeed be worth a shot. – BalusC Jan 11 '13 at 12:21
  • Alas, the same error. I may resort to a fully fledged custom component, or live with setting the `updateId` to `@form`, which works. – Kevin Jan 11 '13 at 12:24
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22581/discussion-between-mowgli-and-balusc) – Kevin Jan 11 '13 at 12:33
  • Please cutdown the code (also try removing one nested ``, etc) and provide an SSCCE which reproduces exactly the problem by copy'n'paste'n'running in a completely blank Mojarra 2.1.17 project with everything set to default (unless otherwise mentioned). – BalusC Jan 11 '13 at 12:35
  • I made a *very* simple example. Interesting result: it works if the form does *not* have `prependId=false`. Once `prepenId` is set to `false` it comes up with the same type of error. Does this make sense? – Kevin Jan 11 '13 at 22:26
  • No, that doesn't make sense. I've however never really used `prependId="false"` in my views, so I don't really recognize this problem. It might be worth reporting an issue to Mojarra guys (I would however also try it in MyFaces). In the meanwhile, I'd just remove that attribute. – BalusC Jan 11 '13 at 22:29
  • I've just had a deja-vu, look at this related Q&A: http://stackoverflow.com/questions/7415230/jsf-namingcontainer-and-uiform-with-prependid This is thus a known problem and a "won't fix". – BalusC Jan 11 '13 at 22:31
  • Ah, an answer. That looks like the culprit. I'll add `prepenid` to the list of things never to use again. If you make a brief answer, or edit this one, I'll accept it as the question answer with a bounty for your great help. – Kevin Jan 11 '13 at 22:36
  • I'll have to wait a while before being able to award a bounty. – Kevin Jan 11 '13 at 22:50