I've a strange problem on ajax listener execution of an jsf page using Mojarra 2.1.13 and Richfaces 4.2.3.Final on JBoss AS 6.1. I've tried to reproduce the problem within the following example, but the problem doesn't occur within this example.
index.xhtml
I've inserted the rich:jQuery
element to force jQuery inclusion, becaue in my real application the command button of the form is hidden and executed per jQuery('#one:form:submit').click();
method.
<h:body>
<h:outputScript library="js" name="app.js"/>
<rich:jQuery selector="document" query="ready(function(){app.init();})" timing="domready"/>
<h:panelGroup layout="block">
<c:forEach items="#{testBean.values}" var="value">
<c:if test="true">
<test:component id="#{value}" value="#{value}">
<f:ajax event="click" listener="#{testBean.submit}" render=":out" />
</test:component>
</c:if>
</c:forEach>
<h:outputText value="#{testBean.text}" id="out" />
</h:panelGroup>
</h:body>
resources/test/component.xhtml
The composite component used within the content.
<composite:interface>
<composite:attribute name="value" />
<composite:clientBehavior name="click" event="click" targets="form:submit" default="true"/>
</composite:interface>
<composite:implementation>
<h:form id="form" styleClass="objects">
<h:inputText id="input" value="#{cc.attrs.value}"/>
<h:commandButton id="submit" type="submit" value="submit"/>
</h:form>
</composite:implementation>
com.example.TestBean
@ManagedBean(name = "testBean")
@ViewScoped
public class TestBean {
private static final Logger LOGGER = Logger.getLogger(TestBean.class);
private String text;
private List<String> values;
// Getters + Setter
@PostConstruct
public void postConstruct() {
setText("instanziated");
setValues(new ArrayList<String>());
getValues().add("one");
getValues().add("two");
LOGGER.info("TestBean initialized");
}
public void submit(final AjaxBehaviorEvent event) {
LOGGER.info("executed");
setText("executed");
}
}
In the real application the ajax event is fired when the submit button is clicked but the listener method isn't invoked, but after the first execution everything works like expected, ajax request is sent and listener method is invoked. This apperance happens until the whole page is reloaded.
UPDATE:
As requested within the comments, this is a part of the real application. The application has some draggable elements and the changes were submitted to the server to store the changes on server side. Therefore the operation
is set to drag
to a hidden input field. Furthermore the changes were converted to JSON which is set into a second hidden input value
. When these values were set, the submit button is called to invoke the ajax request.
var app : {
init : function() {
jQuery(".objects").draggable({
// event handling
stop : function(event, ui) {
// send changes to server
app.submitDragOperation(this);
}
});
},
submitDragOperation : function(form) {
app.setOperation(form,
"drag",
JSON.stringify({
top: jQuery(form).css("top"),
left: jQuery(form).css("left")
})
);
app.submitOperation(form);
},
setOperation : function(form, operation, value) {
var inputOpId = helper.fn.escapeColons("#" + jQuery(form).attr("id") + ":operation");
var inputValId = helper.fn.escapeColons("#" + jQuery(form).attr("id") + ":value")
jQuery(inputOpId).val(operation);
jQuery(inputValId).val(value);
},
submitOperation : function(form) {
// evaluate id of submit button
var submitId = helper.fn.escapeColons("#" + jQuery(form).attr("id") + ":submit");
jQuery(document).ready(function() {
jQuery(submitId).click();
});
},
submitDragOperation : function(form) {
app.setOperation(form,
"drag",
JSON.stringify({
top: jQuery(form).css("top"),
left: jQuery(form).css("left")
})
);
app.submitOperation(form);
}
};