Keeping focus
A recent user question, which has been repeated enough times to warrant a blog posting. In short: Why am I losing focus when I use the <f:ajax> tag?
Let's imagine you have a form, with two input fields and two output fields:
<pre>
1 <h:form>
2 <f:ajax event="blur" render="@form">
3 <h:inputText id="onein" value="#{bean.one}">
4 </h:inputText>
5 <h:outputText id="oneout" value="#{bean.one}" />
6 <h:inputText id="twoin" value="#{bean.two}">
7 </h:inputText>
8 <h:outputText id="twoout" value="#{bean.two}" />
9 </f:ajax>
10 <h:commandButton value="Submit" />
11 </h:form>
</pre>
You enter data in field one, tab to field two, and bam! the focus on field two is lost.
Why?
When you tabbed out of field one, you generated a blur event. This calls an Ajax request, which updates the entire form. That, in turn, removes and re-adds all of the elements in that form - including field 2. With that field (momentarily) gone, the focus is lost.
So, how to deal with this?
Simple rule: Don't replace the parent element of the element whose focus you want to keep. There's also a simple corollary: Don't update stuff you don't have to.
Here's the changed markup that works:
<pre>
1 <h:form>
2 <h:inputText id="onein" value="#{bean.one}">
3 <f:ajax render="oneout"/>
4 </h:inputText>
5 <h:outputText id="oneout" value="#{bean.one}" />
6 <h:inputText id="twoin" value="#{bean.two}">
7 <f:ajax render="twoout"/>
8 </h:inputText>
9 <h:outputText id="twoout" value="#{bean.two}" />
10 <h:commandButton value="Submit" />
11 </h:form>
</pre>Note that you could also say render="onein oneout twoout twoin" and it will still work because you aren't updating the parent (the h:form) - even though you're updating the field that has the focus.
Questions? Ask below.
- Login or register to post comments
- Printer-friendly version
- driscoll's blog
- 1805 reads





