Sydney
Sydney

Reputation: 12212

Set focus on an element that has been partially rendered

I have a form with an input element that updates a panel containing form elements on a blur event. I want the user to be able to navigate using the tab key. So leaving the first input using the tab should give focus to the first form element of the rendered form.

Input element with blur event:

<h:inputText class="text" id="profileLocation" value="#{cc.attrs.managedBean.profileLocation}">
    <f:validateRegex pattern="([A-Z]{2}[A-Z0-9])(?:\.(\d+))?(\.\d+)?(\.\d+)?" />
    <f:ajax event="blur" render="assertionLocationPanel" listener="#{cc.attrs.managedBean.updateMessageLocation}"/>
</h:inputText>

It will render the assertionLocationPanel defined as:

<p:outputPanel id="assertionLocationPanel">
    <h:inputText value="#{cc.attrs.managedBean.property}">
    </h:inputText>
</p:outputPanel>

When using the tab key, the panel is updated but the focus is not on the input element. I guess this is because of the rendering. If the panel is not updated, the focus is set to the correct element.

Solution

Call a javascript function specified in the onevent attribute:

<f:ajax event="blur" render="profileLocationErrorMessage assertionLocationPanel" listener="#{cc.attrs.managedBean.updateMessageLocation}" onevent="setFocus"/>

the define the JS function as:

<script type="text/javascript">  
    function setFocus() {
        $('#ConditionalComposite-ConditionalForm-1-ProfileLocation-segmentInstanceNumber').focus();
    }  
</script>  

I had to call the JS function setFocus instead of calling $('#ConditionalComposite-ConditionalForm-1-ProfileLocation-segmentInstanceNumber').focus(); in the onevent attribute because it did not work. I kept the generated ids because I use composite, also I redefined javax.faces.SEPARATOR_CHAR to -.

If you using the regular : separator, you have to escape the separator as #ConditionalComposite\\:ConditionalForm1\\:ProfileLocation\\:segmentInstanceNumber.

Upvotes: 4

Views: 10693

Answers (1)

Mustafa
Mustafa

Reputation: 98

Have you tried this;

At first give an id to inputText under outpupanel.

<p:outputPanel id="assertionLocationPanel">
<h:inputText value="#{cc.attrs.managedBean.property}" id="assertioninput">
</h:inputText>

then add ajax complete event like this and oncomplete focus on the input you want.

<a4j:ajax event="complete"  render="assertionLocationPanel" oncomplete="assertioninput.focus();"/>

by the way dont forget to set form prependid=false in order to directly call the id of inputtext

Upvotes: 2

Related Questions