Hello everyone! I have the problem that my code isn't triggering the action in my backing bean. The code is as follows:
HtmlCommandButton replyCommentButton = new HtmlCommandButton();
replyCommentButton.setId("replyCommentButton" + commentCounter);
replyCommentButton.setValue("Create reply");
String action = "#{Handler.action_replyToComment}";
MethodExpression methodExpression =  
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().
createMethodExpression(FacesContext.getCurrentInstance().getELContext(), action, null,
new Class<?>[0]);
replyCommentButton.setActionExpression(methodExpression);
In my backing bean called RequestHandlerBean, defined in FacesConfig as Handler, I have the following code:
public void action_replyToComment() {
logger.info("Homemade action called!!!");
System.out.println("Homemade action called!!!");
}
Does anyone spot why nothing happens when I click the button? It isn't triggering the event properly. The source of the html code is as follows:
<input id="replyCommentButton1" type="submit" value="Create reply"   
name="replyCommentButton1"/>
As we can see there's no action defined in the HTML.
Edit 2: I just found out in Javadoc that my action method has to be a public String. I've changed this in my backing bean now so the code in my backing bean is:
public String action_replyToComment() {
logger.info("Homemade action called!!!");
System.out.println("Homemade action called!!!");
return null;
}
Edit2: I've also made sure that I have it encapsulated within a tag, but still no luck. Shouldn't there be a action attribute on the element?
Edit3: My bean is defined in my faces-config like this:
<managed-bean>
<description>
Handles the specific request.
</description>
<managed-bean-name>Handler</managed-bean-name>
<managed-bean-class>no.ngt.tech.rt2.beans.RequestHandlerBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
Also if I choose to output in my JSF page like this:
<a4j:commandButton action="#{Handler.action_replyToComment}" value="Reply" />
That works perfectly
EDIT 4 - MY JSP PAGE Note Ive also tried using the depreciated setAction(methodBinding) now too, but sadly it didnt work either.
<%@ include file="_includes.jsp" %>
<f:view>
<html>
<head>
<title><h:outputText value="#{msgs.title}" /></title>
</head>
<body>
<br /><br /><br />
<%@ include file="_menu.jsp" %>
<rich:tabPanel switchType="client">
<rich:tab id="commentsTab" label="Comments" rendered="#{Handler.editRequest}">
<h:form>
         <ngt:commentTree binding="#{Handler.commentTree}" value="#{Handler.comments}"  />
         <br />
         <a4j:commandButton action="#{Handler.action_replyToComment}" value="testbutton" />
</h:form>    
</rich:tab>
</rich:tabPanel>
</body>
</html>
</f:view>
menu.jsp:
<h:form>
    <rich:toolBar itemSeparator="line" styleClass="toolbar" contentClass="toolbar" height="22">
        <rich:toolBarGroup>
            <rich:menuItem submitMode="server" value="Front" action="#{newRT.action_showFront}" />
        </rich:toolBarGroup>
        <rich:toolBarGroup>
            <rich:menuItem submitMode="server" value="New request" action="#{Step.action_showSteps}" />
        </rich:toolBarGroup>
        <rich:toolBarGroup>
            <rich:menuItem submitMode="server" value="Requests" action="#{Handler.action_showRequestsView}" />
        </rich:toolBarGroup>
        <rich:toolBarGroup>
            <rich:menuItem submitMode="server" value="Control-panel" action="#" />
        </rich:toolBarGroup>
        <rich:toolBarGroup location="right">
            <h:inputText styleClass="barsearch" value="#{Handler.search}" />
            <a4j:commandButton styleClass="barsearchbutton" action="#{Handler.action_GetRequestFromID}"  value="Search" />
        </rich:toolBarGroup>
    </rich:toolBar>
</h:form>
<br/><br/>
Includes.jsp
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="a4j" uri="http://richfaces.org/a4j" %>
<%@ taglib prefix="rich" uri="http://richfaces.org/rich"%>
<%@ taglib prefix="ngt" uri="http://MySpecialTagLib.no/"%>
Edit 7 - Java code for UIComponent:
This is CommentsTreeUI.java:
public class CommentsTreeUI extends UIOutput {
    private static Logger logger = Logger.getLogger(CommentsTreeUI.class.getName());
    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        List<CommentTag> value = (List<CommentTag>) getAttributes().get("value");
        int commentCounter = 0;
        if (value != null) {
            for (CommentTag comment : value) {
                commentCounter++;
                ResponseWriter commentContainerWriter = context.getResponseWriter();
                commentContainerWriter.startElement("div", this);
                commentContainerWriter.writeAttribute("id", "Comment" + commentCounter, null);
                String width = comment.getWidth();
                String height = comment.getHeight();
                String style = comment.getStyle();
                style = (style != null) ? style + ";" : "";
                if (width != null) {
                    style += "width:" + width + ";";
                }
                if (height != null) {
                    style += "height:" + height + ";";
                }
                commentContainerWriter.writeAttribute("style", style, null);
                String newComment = comment.getNewComment();
                if (newComment == null) {
                    newComment = "false";
                }
                String level = comment.getLevel();
                if (level != null) {
                    level = "commentContainerLevel" + level + newComment;
                }
                commentContainerWriter.writeAttribute("class", level, null);
                String title = comment.getTitle();
                if (title != null) {
                    commentContainerWriter.writeAttribute("title", title, null);
                }
                String titleText = comment.getTitleText();
                if (titleText != null) {
                    ResponseWriter titleTextWriter = context.getResponseWriter();
                    UIOutput titleTextComponent = new UIOutput();
                    titleTextWriter.startElement("div", titleTextComponent);
                    titleTextWriter.writeAttribute("class", "commentHeaderText" + newComment, null);
                    titleTextWriter.writeText(titleText + " | ", null);
                    titleTextWriter.startElement("a", titleTextComponent);
                    titleTextWriter.writeAttribute("onclick", "showCommentReply('CommentReply" + commentCounter + "')", null);
                    titleTextWriter.writeAttribute("class", "reply", null);
                    titleTextWriter.writeText("Reply", null);
                    titleTextWriter.endElement("a"); 
                    titleTextWriter.endElement("div");
                }
                String commentBody = comment.getCommentBody();
                if (commentBody != null) {
                    ResponseWriter commentBodyWriter = context.getResponseWriter();
                    UIOutput commentBodyComponent = new UIOutput();
                    commentBodyWriter.startElement("div", commentBodyComponent);
                    commentBodyWriter.writeText(commentBody, null);
                    commentBodyWriter.endElement("div");
                }
                ResponseWriter replyContainerWriter = context.getResponseWriter();
                UIOutput replyContainerComponent = new UIOutput();
                replyContainerWriter.startElement("div", replyContainerComponent);
                commentContainerWriter.writeAttribute("id", "CommentReply" + commentCounter, null);
                replyContainerWriter.writeAttribute("class", "replyContainer", null);
                ResponseWriter replyHeaderWriter = context.getResponseWriter();
                UIOutput replyHeaderComponent = new UIOutput();
                replyHeaderWriter.startElement("div", replyHeaderComponent);
                replyHeaderWriter.writeAttribute("class", "replyHeaderContainer", null);
                replyHeaderWriter.endElement("div");
                ResponseWriter replyFormWriter = context.getResponseWriter();
                UIInput replyFormComponent = new UIInput();
                replyFormWriter.startElement("fieldset", replyFormComponent);
                replyFormWriter.startElement("textarea", replyFormComponent);
                replyFormWriter.writeAttribute("type", "textarea", null);
                replyFormWriter.writeAttribute("rows", "5", null);
                replyFormWriter.writeAttribute("cols", "76", null);
                replyFormWriter.writeText("Write your answer here", null);
                replyFormWriter.endElement("textarea");
                //TODO: Fix so button has action to backing bean
                HtmlAjaxCommandButton replyCommentButton = new HtmlAjaxCommandButton();
                replyCommentButton.setId("replyCommentButton" + commentCounter);
                replyCommentButton.setValue("Create reply");
                String action = "#{RequestHandlerBean.action_replyToComment}";
                //replyCommentButton.setReRender("commentsTree");
                ExpressionFactory factory = context.getApplication().getExpressionFactory();
                Class [] argtypes=new Class[1];
                argtypes[0]=ActionEvent.class;
                MethodExpression replyActionExpression = factory.createMethodExpression(context.getELContext(), action, null, argtypes);
                replyCommentButton.setActionExpression(replyActionExpression);
                MethodExpression methodExpression = context.getCurrentInstance().getApplication().getExpressionFactory().
                        createMethodExpression(context.getCurrentInstance().getELContext(), action, null, new Class<?>[0]);
                replyCommentButton.setActionExpression(methodExpression);
                /*
                replyCommentButton.setAction(context.getApplication().createMethodBinding(action, argtypes));
                */
                replyCommentButton.encodeAll(context);
                //Todo above
                replyFormWriter.writeText(" ", null);
                replyFormWriter.startElement("input", replyFormComponent);
                replyFormWriter.writeAttribute("type", "button", null);
                replyFormWriter.writeAttribute("value", "Cancel ", null);
                replyFormWriter.writeAttribute("onclick", "hideCommentReply('CommentReply" + commentCounter + "')", title);
                replyFormWriter.endElement("input");
                replyFormWriter.endElement("fieldset");
                replyContainerWriter.endElement("div");
                commentContainerWriter.endElement("div");
            }
        } else { //value==null
            ResponseWriter writer = context.getResponseWriter();
            writer.startElement("div", this);
            writer.writeAttribute("id", getClientId(context), null);
            String width = (String) getAttributes().get("width");
            String height = (String) getAttributes().get("height");
            String style = (String) getAttributes().get("style");
            style = (style != null) ? style + ";" : "";
            if (width != null) {
                style += "width:" + width + ";";
            }
            if (height != null) {
                style += "height:" + height + ";";
            }
            writer.writeAttribute("style", style, null);
            String styleClass = (String) getAttributes().get("styleClass");
            if (styleClass != null) {
                writer.writeAttribute("class", styleClass, null);
            }
            String title = (String) getAttributes().get("title");
            if (title != null) {
                writer.writeAttribute("title", title, null);
            }
        }
    }
    @Override
    public void encodeEnd(FacesContext context) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        writer.endElement("div");
    }
This is CommenstTreeTag:
public class CommentsTreeTag extends UIComponentTag {
    String style;
    String styleClass;
    String title;
    String width;
    String height;
    String value;
    Long parentId;
    public void release() {
        // the super class method should be called
        super.release();
        style = null;
        styleClass = null;
        title = null;
        height = null;
        width = null;
        parentId = null;
        value = null;
    }
    @Override
    protected void setProperties(UIComponent component) {
        // the super class method should be called
        super.setProperties(component);
        if (style != null) {
            component.getAttributes().put("style", style);
        }
        if (styleClass != null) {
            component.getAttributes().put("styleClass", styleClass);
        }
        if (width != null) {
            component.getAttributes().put("width", width);
        }
        if (height != null) {
            component.getAttributes().put("height", height);
        }
        if (title != null) {
            if (isValueReference(title)) {
                ValueBinding vb =
                        getFacesContext().getApplication().createValueBinding(title);
                component.setValueBinding("title", vb);
            } else {
                component.getAttributes().put("title", title);
            }
        }
        if (value != null) {
            if (isValueReference(value)) {
                ValueBinding vb =
                        getFacesContext().getApplication().createValueBinding(value);
                component.setValueBinding("value", vb);
                getFacesContext().getApplication().createValueBinding(value);
            } else {
                component.getAttributes().put("value", value);
            }
        }
        if (parentId != null) {
            component.getAttributes().put("parentId", parentId);
        }
    }
    public String getComponentType() {
        return "commentTree";
    }
    public String getRendererType() {
        // null means the component renders itself
        return null;
    }
    public String getHeight() {
        return height;
    }
    public void setHeight(String height) {
        this.height = height;
    }
    public String getWidth() {
        return width;
    }
    public void setWidth(String width) {
        this.width = width;
    }
    public String getStyle() {
        return style;
    }
    public void setStyle(String style) {
        this.style = style;
    }
    public String getStyleClass() {
        return styleClass;
    }
    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}