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;
}
}