What exactly is #{component} in EL?
Asked Answered
W

2

4

According to https://code.google.com/p/primefaces/issues/detail?id=4720, The ComponentUtils.resolveWidgetVar(String expression, UIComponent component) function is available in Primefaces since 2013. It can be used in EL by the "#{p:widgetVarFromContext(searchExpression, component)}" function.

This is useful in case of several components have the same id in different NamingContainer, but are still present in the same view. In this case, the #{p:widgetVar(searchExpression)} function only returns the last one found.

I don't understand however how to reference the UIComponent that must be passed as the second argument from EL. The above mentioned bug report suggests we can refer to it using #{component}. Can anyone provide me with an example?

Wholism answered 13/3, 2015 at 15:11 Comment(0)
S
9

The #{component} is an implicit EL variable referring the current UIComponent in EL scope (see also implicit EL objects). You can usually only refer it in component's HTML attribute or in template text children.

E.g. in case of <h:inputText> it will reference an instance of UIInput class which has among others an isValid() method.

<h:inputText id="foo" required="true"
    style="background: #{component.valid ? '' : 'pink'}"
    onclick="alert('Client ID of this component is #{component.clientId}');" />

You can also use binding attribute to let JSF during view build time put a reference to a component instance in the Facelet scope. This way the component reference will be available anywhere in the Facelet during view render time.

<script>alert('Client ID of foo component is #{foo.clientId}');</script>
<h:inputText binding="#{foo}" />

See also:

Savoie answered 13/3, 2015 at 21:47 Comment(0)
B
3

The p:widgetVarFromContext is useful when referring to a PrimeFaces widget inside a composite component. There could be more than one instance of your component on the same page. So writing widgetVar="expression" and PF('expression') is out of the question. There would be multiple widgets with the same name. It is then better to omit the widgetVar attribute and use the generated one which is unique because it is based on the clientId.

You can't use #{p:widgetVar('expression')} within your <cc:implementation> because it leads to a Cannot find component for expression "expression" referenced from "j_id1" error instead of the expected PF('widget_expression').

But you can use #{p:widgetVarFromContext('expression', cc)} which will return something like PF('widget_wrapperform_compositecomponent1_expression'). The cc refers to the root of the composite component instance.

Belford answered 19/5, 2015 at 10:25 Comment(3)
What a lovely answer.Phosphide
Do note that the question is about #{component}, not #{p:widgetVarFromContext()}.Savoie
Indeed it does and your explanation is very complete. But a google search for widgetVarFromContext brought me here time and again. My answer is the one I was looking for when I got here. So I just wrote this to help my future self.Belford

© 2022 - 2024 — McMap. All rights reserved.