I have a simple form with an inputText and 2 commandButtons. The inputText displays the backing bean's value fine, but when I change the value for the first time, the set method is not called, and thus the form submit with an empty value. When I change it again, then the set method is called and everything works fine. What is the cause and how can I solve it?
<h:panelGroup id="chatId">
<h:panelGrid rendered="#{chat.validUser == true}">
<h:form id="sendMsgForm" >
<h:panelGroup id="chatId2">
<h:inputText id="chatInput" value="#{chat.msgTo}" autocomplete="off" >
<f:ajax execute="@this @form" />
</h:inputText>
<h:commandButton value="Send" id="sendButton" action="#{chat.send}">
<f:ajax render=":chatLogId :chatId" />
</h:commandButton>
<h:commandButton value="Bye" action="#{chat.bye}">
<f:ajax render=":chatLogId :chatId :chatUserId" />
</h:commandButton>
</h:panelGroup>
</h:form>
</h:panelGrid>
</h:panelGroup>
The backing bean code:
@SessionScoped
public class Chat impl开发者_Go百科ements Serializable, ActionListener, ValueChangeListener {
private String msgTo = "Start typing...";
private boolean validUser = false;
public void bye() {
validUser = false;
tc.disconnect();
}
public void send() {
try {
tc.sendMessage(msgTo);
setMsgTo("");
} catch (Exception e) {
e.printStackTrace();
}
}
// ...
The code snippet by Matt Handy is the correct solution, but the explanation of the cause is incorrect.
You've omitted the execute
attribute of the <f:ajax>
in the commandbutton. It will then default to @this
which means that only the name=value pair of the button itself is been sent to the server side (and thus only the associated action will be invoked; the input values won't be updated). Since you want to submit the entire form instead, you need to explicitly set execute
to @form
.
<h:commandButton value="Send" id="sendButton" action="#{chat.send}">
<f:ajax execute="@form" render=":chatLogId :chatId" />
</h:commandButton>
That it works during change of the input field is because you've put execute="@form"
in the input field instead. The <f:ajax>
inside input fields will by default be executed when you change the value. But in this particular case you don't need it at all. So get rid of it:
<h:inputText id="chatInput" value="#{chat.msgTo}" autocomplete="off" />
Maybe it's because you fire two ajax calls at the same time with concurrent behavior. If you click on the sendButton, the chatId panelGroup is re-rendered (by the ajax call from your submit button) and the form is executed (by the ajax call from your input field).
Try the following for the ajax call of your submit button:
<h:commandButton value="Send" id="sendButton" action="#{chat.send}">
<f:ajax render=":chatLogId :chatId" execute="@form"/>
</h:commandButton>
Want to follow up that the answer to my problem was to consolidate the 3 form tags that I had into two forms. I had 1 form for the chatLogId, 1 for chatId and 1 for chatUserId. The chatLogId is just a dataTable, and I left that alone. I merged the chatId and chatUserId forms into one. When I move off of the inputText field now, the setMsgTo and then the send methods are called. Not sure, but I think my problem might be that the wrong form was updated before. Thanks for all your help. Binh
精彩评论