Why does composite component "rendered" attribute throw an IllegalArgument Exception? - jsf-2

I create a composite component like this:
<cc:interface>
<cc:attribute name="value"
required="true" />
<cc:attribute name="rendered"
displayName="True to render"
default="true" />
</cc:interface>
When I invoke this component, I get an IllegalArgumentException. I can changed the rendered name to something else (like doIt) and then it works.
Is the rendered attribute reserved somehow? I want my composite component to look like "regular" JSF components.
This is with Mojarra.

Composite components extend UINamingContainer which in turn extend UIComponentBase which in turn already definies the id and rendered attributes. You don't need to specify them yourself. Just remove the <cc:attribute name="rendered">. If you specify the rendered attribute on the composite component tag, then it'll be interpreted and applied on the composite component itself.
If you intend to render specific children of the composite, then better invent a different attribute name. For example, renderSomeChild.

Related

How do you populate a displaytag column title with a Struts2 properties file entry?

In Struts2 you can populate a label for a component with a value from a properties file. The properties file must have the same name as the Struts2 Action Class that will serve up the JSP and be in the same folder as that Action Class.
<s:textfield key="field.label.casereference" name="caseReference" />
I want to do the same thing with a displaytag column. But it doesn't seem to work.
Columns in displaytag have an attribute called titleKey that is suppose to let you do this. But it doesn't seem to work.
<display:table class="displaytag" id="Table2" name="getResultlistCases" clearStatus="true" requestURI="/AbsHearingSrALJ_homePage.action">
<display:column style="width:8%;" property="aljNum" titleKey="field.label.aljNumber" />
<display:column style="width:9%;" property="location" titleKey="field.label.location" />
<display:column style="width:10%;" property="caseName" titleKey="field.label.caseName" />
<display:column style="width:25%;" property="scheduledTime" titleKey="field.label.scheduledTime" />
The titleKey field is not getting the value from the properties file. It works when I use the key field of a Struts2 textfield, but not with a column's titleKey field for displaytag.
Does anyone know if it is possible to get this to work?
Displaytag provides an interface I18nResourceProvider with a few ready
to use implementations which match the behaviour of common frameworks.
This is configured in displaytag.properties using the locale.provider
key. By default the JSTL implementation is used.
And in org.displaytag.localization.I18nJstlAdapter description:
It will make the titleKey attribute of column tag works the same as
fmt:message's key property. This tag must be the descendant of a
fmt:bundle tag in order to use the titleKey.
So you should use following approach (I tested - it worked):
<fmt:bundle basename="action.HelloWorld">
<display:table name="test">
<display:column property="aljNum" titleKey="field.label.aljNumber" />
</display:table>
</fmt:bundle>
Remember also that "basename" in fmt:bundle is a fully-qualified resource name without ".properties" extension.

Configuration of the beans when using <f:param> <f:viewParam>

I'm trying to pass a parameter between a JSF page to another, from a bean to another. I know it is a common question, infact I've tried several approaches before writing it down.
To do that I have put both the beans in session scope and added in the first bean the following:
<p:commandButton value="Submit" type="submit"
actionListener="#{sourceBean.save}" action="success">
<f:setPropertyActionListener
target="#{targetBean.foo}" value="#{sourceBean.foo}" />
</p:commandButton>
The problem is that I don't want these beans to be in session scope but in view scope.
So I tried to put in my first page:
<p:commandButton value="Submit" type="submit"
actionListener="#{sourceBean.save}" action="success">
<f:param name="foo" value="#{sourceBean.foo}"/>
</p:commandButton>
And in the second page:
<f:metadata>
<f:viewParam id="foo" name="foo" value="#{targetBean.foo}"
/>
</f:metadata>
The problem is that the passed String is null so, obviously, I get an error form the Converter.
I think I'm missing something in the configuration of my managed beans. Do I have to link target and source bean in someway?
At this moment I have this configuration:
<managed-bean>
<managed-bean-name>targetBean</managed-bean-name>
<managed-bean-class>guiBeans.TargetBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>sourceBean</managed-bean-name>
<managed-bean-class>guiBeans.SourceBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
Another question: In my app, the value foo.id, that I use during the conversion, is set autonatically by the database when I save the object so when I call:
actionListener="#{sourceBean.save}"
The converter gets the id and turns it into a String (and viceversa, if needed).
So, I wanted to know if in JSF is first called the actionListener or the function that sets the parameters .
Could be this the reason why I get a null String? Thanks a lot.
The <f:param> is evaluated during rendering of the form, not during submitting of the form. Your problem suggests that the #{sourceBean.foo} value is only been set during submitting the form and thus not available during rendering of the form.
You'd basically need to replace action="success" by action="#{bean.action}" with
public String action() {
return "success?foo=" + foo.getId();
}
Or, if you're using navigation cases
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/some.xhtml</to-view-id>
<redirect>
<view-param>
<name>foo</name>
<value>#{sourceBean.foo.id}</value>
</view-param>
</redirect>
</navigation-case>
Unrelated to the concrete problem, the <f:param> doesn't support the converter attribute at all. You'd have to access the desired property directly (which is id in the above example).

Create composite component for f:metadata

I want to create a composite component which adds some common meta data to views, like:
<viewController:metadata controller="orderController"/>
the component:
<composite:interface>
<composite:attribute name="controller" />
</composite:interface>
<composite:implementation>
<f:metadata>
<f:viewParam name="id" value="#{cc.attrs.controller.id}" />
<f:event type="preRenderView"
listener="#{cc.attrs.controller.initConversation}" />
</f:metadata>
</composite:implementation>
i do similar things to add a button bar to all views and it works fine, but it seems its not possible with f:metadata.
Am i right or is there something wrong with my code?
thanks
This isn't possible. The <f:metadata> has to go in the view associated with the view ID. See also the tag documentation (emphasis mine):
Declare the metadata facet for this view. This must be a child of the <f:view>. This tag must reside within the top level XHTML file for the given viewId, or in a template client, but not in a template. The implementation must insure that the direct child of the facet is a UIPanel, even if there is only one child of the facet. The implementation must set the id of the UIPanel to be the value of the UIViewRoot.METADATA_FACET_NAME symbolic constant.

Composite component action attribute reutilization?

I have a JSF 2.0 composite component as follows:
<composite:interface>
<composite:attribute name="id"/>
<composite:attribute name="action1" targets="#{cc.clientId}:#{cc.attrs.id}_1" requiered="true"/>
<composite:attribute name="action2" targets="#{cc.clientId}:#{cc.attrs.id}_2" requiered="true"/>
</composite:interface>
<composite:implementation>
<h:commandLink id="#{cc.attrs.id}_1" value="command link 1"/>
<h:commandLink id="#{cc.attrs.id}_2" value="command link 2"/>
</composite:implementation>
as you can see for now I am using two different attributes named (action1, action2) and target them to the two commandLink's.
what I would like to do is: instead of having action1 & action2, I would like to have only one attribute named "action" and reuse this action for both commandLinks.
Thanks.
You can specify a space separated list of client IDs in targets attribute. See also the <composite:attribute> tag documentation:
If this element has a method-signature attribute, the value of the targets attribute must be interpreted as a space (not tab) separated list of client ids (relative to the top level component) of components within the <composite:implementation> section.

Add custom html attribute to be rendered for jsf2 component

<h:selectBooleanCheckbox />
will render a html checkbox.
How do I add a custom attribute 'myAttribute' with value 6 to it so that the result will be:
<input type="checkbox" data-myAttribute="6" ... />
There is no trivial way to achieve this. Unregistered attribtues are completely ignored. Assuming that you're using Mojarra, your best bet is to extend Mojarra's CheckboxRenderer with a custom one wherein you override the getEndTextToRender() method which writes the extra attribute. To get it to run, just register it in faces-config.xml as a renderer for component family javax.faces.SelectBoolean and renderer type javax.faces.Checkbox.
An alternative is to delegate the job to some onload JavaScript.

Resources