5

In the given case, I want to use a facelet with different ManagedBeans, so the regarding action-bean is given as an parameter:

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" > <h:body> <ui:include src="ratings.xhtml" > <ui:param name="createAction" value="#{myOneCreateAction}" /> <ui:param name="ratings" value="#{context.ratings}" /> </ui:include> </h:body> </html> 

I'm giving the create action as parameter value="#{myOneCreateAction}".

Within that facelet is a component also being used several times on other pages - so I try to refactor it in a composite component.

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:io="http://java.sun.com/jsf/composite/inoutComponents"> <ui:composition> <rich:dataTable id="ratingTblId" value="#{ratings}" var="rating"> <rich:column> <io:removeButton id="removeButton" actionMethod="#{createAction.removeRating}" immediate="true" render=":#{rich:clientId('ratingTblId')}" /> <h:commandButton id="removeButton2" actionListener="#{createAction.removeRating}" immediate="true" > <f:ajax render="ratingTblId" /> </h:commandButton> </rich:column> </rich:dataTable> </ui:composition> </html> 

See, how the method is given as actionMethod="#{createAction.removeRating}" to the component. This component itself looks like following:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:cc="http://java.sun.com/jsf/composite"> <!-- INTERFACE --> <cc:interface> <cc:attribute name="actionMethod" targets="remove" method-signature="void f(javax.faces.event.ActionEvent)"/> <cc:attribute name="render" required="false" /> </cc:interface> <!-- IMPLEMENTATION --> <cc:implementation> <h:commandButton id="remove" actionListener="#{cc.attrs.actionMethod}" onclick="if (!confirm('Do you really?')) { return false; }"> <f:ajax execute="@this" render="#{cc.attrs.render}" /> </h:commandButton> </cc:implementation> </ui:composition> 

and last but not least, the managed bean

Name("myOneCreateAction") @Scope(ScopeType.CONVERSATION) public class MyOneCreateAction { ... public void removeRating(ActionEvent ev) { // do something } ... } 

Surprisingly, while the removeButton2 correctly jumps into the right function, the composite components version returns a

javax.faces.event.AbortProcessingException: Target Unreachable, identifier 'createAction' resolved to null 

instead. Am using Mojarra JSF 2.1.26 with Seam 2.3.1.CR1. There are no nested composite components. When replacing the composite component parameter to #{myOneCreateAction.removeRating}, it works like expected.

Has anybody seen this before? Am I blind? Any work-arounds known... ? Thanks in advance!

2
  • Well explained and composed. Well done for first hit ;-) Did you have a look at that, by the way? Commented Nov 26, 2013 at 16:45
  • Hi @XtremeBiker, and thnx for the positive feedback. Well, yeah, used that as ressource before writing this question. Debugged the whole method and would expect to at least jump into it. But nope, didn't happen. :-( Commented Nov 27, 2013 at 21:39

2 Answers 2

1

As a work-around I rewrote the component to give action bean and action method as two separate parameters resolving them as following

xhtml:

<io:removeButton id="removeButton" actionBean="#{createAction}" actionMethod="removeRating" immediate="true" render=":#{rich:clientId('ratingTblId')}" /> 

composite component:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:cc="http://java.sun.com/jsf/composite"> <!-- INTERFACE --> <cc:interface> <cc:attribute name="actionBean" /> <cc:attribute name="actionMethod" /> <cc:attribute name="render" required="false" /> </cc:interface> <!-- IMPLEMENTATION --> <cc:implementation> <h:commandButton id="remove" action="#{cc.attrs.actionBean[cc.attrs.actionMethod]}" onclick="if (!confirm('Do you really?')) { return false; }"> <f:ajax execute="@this" render="#{cc.attrs.render}" /> </h:commandButton> </cc:implementation> </ui:composition> 

also changing the action methods signature to return String instead of void. That does not look that super sexy anymore, but works. :-/

Sign up to request clarification or add additional context in comments.

Comments

1

I was having the same issue, found out that it has been fixed on version 2.2.15: https://github.com/javaserverfaces/mojarra/issues/4271

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.