Set focus on an element that has been partially rendered - jsf

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.

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

Related

Primefaces Diagram - Generating IDs for DOM Elements

I'm trying to create a <p:diagram> with elements which contain input fields, but the problem is that for each added element, the name and ID are the same for each input field.
What I've tried to do to give each field a unique id is adding a bean-generated ID for each element, but this just gets omitted in the final code. Here's my EL/xhtml:
<p:diagram value="#{Controller.model}" style="height:600px;width:1500px" styleClass="ui-widget-content" var="lrvEl" scrollable="true">
<f:facet name="element">
<div onmouseleave="nodeOnMouseOut(this)" onclick="nodeOnClick(this)">
<h:outputText value="#{lrvEl.title}" style="display:block;margin-top:1em;width:100%;height:10px;padding-left:4px"/>
<h:outputText value="#{lrvEl.description}" style="display:block;margin-top:1em;width:100%;height:10px;padding-left:4px"/>
<h:inputText id="inputEpValue_#{lrvEl.id}" name="inputEpValue_#{lrvEl.id}" onchange="setScoreVal('#{lrvEl.id}', this)" rendered="#{lrvEl.isScore()}" style="display:block;margin-top:1em;height:10px;padding-left:4px">
</h:inputText>
</div>
</f:facet>
<p:ajax event="connect" listener="#{Controller.onConnect}" />
<p:ajax event="disconnect" listener="#{Controller.onDisconnect}" />
<p:ajax event="connectionChange" listener="#{Controller.onConnectionChange}" />
</p:diagram>
The important bit here is the <h:inputText id='inputEpValue_#{lrvEl.id}' ... > - this comes out on the page as the following:
editor:LRVContent:overlayForm_lm:inputEpValue
as if the value wasn't set, however, as you can see in the onchange field I use the same constellation. This gets rendered as onchange="setScoreVal('ep:2', this)" so that works.
Can I not dynamically set IDs for elements in this fashion? Is there another way?
Edit:
The actual Reason I want to do this is that, if I have more than one input with the same generated ID, the focus(/cursor) will automatically jump into the last generated input field when I click on any one of them, meaning I won't be able to actually change the value of any of those fields.

JSF commandLink onclick EL expression re-evaluation

I have a JSF command like this:
<h:commandLink id="testId" onclick="if (#{bean.isPageOpen}) dlg.show();" />
The boolean bean.isPageOpen was false initially so the dlg widget was not opened. Now when I change the condition i.e. bean.isPageOpen returns true, the widget still does not get open.
Is the EL expression evaluated only once and never again for JSF commandLink?
Thanks,
-csn
Javascript codes is producing on page load. If you check your page source , You can see your onclick like this.
onclick="if (false) dlg.show();"
If you want to use updated value in your bean.You might use structure like this.I'm using primefaces.
<p:inputText id="textId" value="#{{bean.isPageOpen}" />
<h:commandLink id="testId" onclick="refresh(); if (document.getElementById('textId').value=='true') dlg.show();" />
<p:remoteCommand name="refresh" actionListener="#{bean.updateisPageOpen}" update ="textId"/>

h:button not passing f:param from a JSF component

I have a JSF 2 page with an <h:button>. I want to pass two <f:param> to the outcome page.
Value of <f:param> pOne comes from the page bean.
Value of <f:param> pTwo comes from an input field on the page.
pTwo's value is not stored on the page bean.
pTwo's input field value is set by javascript when user clicks on an image map within same page.
The problem is that the request passes null for param pTwo.
If I set the value of pTwo to a static value, value="12345", then 12345 is passed.
So, why does <f:param> not pass the value of a input field from the source page?
Thanks!
<input type="text" id="pTwo"/>
<h:button value="Go" outcome="destPage">
<f:param name="pOne" value=#{myBean.pOne}"/>
<f:param name="pTwo" value=#{pTwo}"/>
</h:button>
You cannot reference the value of the input field in an EL expression like this. Not even if you use h:inputText.
Furthermore, JSF calculates the link for the button including the parameters when the page is rendered on server side. So when the user sees the page and enters something in the input field, the URL for the link is already fixed and won't change.
To solve this in a similar way, you could use h:commandButton instead of h:button, submit the form including the value for pTwowith h:inputText and return a redirect to the new page. The XHTML for this could look like this:
<h:form>
<h:inputText value="#{bean.pTwo}"/>
<h:commandButton action="#{bean.goToDest}" value="Go"/>
</h:form>
The referenced action method could look like this:
public String goToDest() {
return "destPage?faces-redirect=true&pOne=" + pOne + "&pTwo=" + pTwo;
}
try use the following code:
<h:commandButton action="#{bean.goToDest}" value="Go" >
<f:setPropertyActionListener target="#{yourDestinyManagedBean.pOne}" value="#{yourManagedBean.pOne}" />
<f:setPropertyActionListener target="#{youDestinyManagedBean.pTwo}" value="#{yourManagedBean.pTwo}" />
</h:commandButton>
You can see an example here.

Conditional display of p:overlayPanel

How can I show/hide the overlay panel conditionally from #ManagedBean based on some result.
In the below code: p:overlayPanel is for p:commandButton. I want to show overlay panel conditionally from Action method.
Right now it is showing every time I click the commandbutton.
<h:form id="form">
<h:outputLabel value="Town Name:"/>
<h:inputText value="#{myBean.town}"/>
<p:commandButton id="checkBtn" value="Check" action="#{myBean.action}"/>
<p:overlayPanel widgetVar="overL" id="over" for="checkBtn">
<h:outputText value="This town is not Listed in our records"/>
</p:overlayPanel>
</h:form>
Note : I'm using **Primefaces 3.5**
Give the overlay panel a widget name and set showEvent to none (this kills the default behavior and assign a javascript handle to the panel):
widgetVar="myOverlay" showEvent="none"
add oncomplete attr to you button, something like:
oncomplete="if(args && !args.validationFailed) myOverlay.show();"

How to call action when select noSelectionLabel?

I have this code above which works perfectly when i select some of the items on him... The a4j:support works fine and rerender my another field correctly...
The problem is if i choose one item, and then i back to "noSelectionLabel"...
When i do this for some reason my a4j:support dont work, i dont get into my method "setarFormulario" and i dont rerender my another field...
<s:decorate template="layout/form.xhtml">
<ui:define name="label">Evento:</ui:define>
<h:selectOneMenu value="#{home.instance.evento}" required="true">
<s:selectItems value="#{eventoService.obterTodos()}" var="evento" label="#{messages[evento.nome]}" noSelectionLabel="#{messages['br.com.message.NoSelection']}" />
<s:convertEntity />
<a4j:support event="onchange" action="#{home.setarFormulario}" reRender="camposFormulario" ajaxSingle="true" />
</h:selectOneMenu>
</s:decorate>
How can i get into my method even if i select the noSelectionLabel? Then my home.instance.evento must be null.. or something like this...
Yor field h:selectOneMenu is required then selecting noSelectionLabel value will cause a validation error and if you had validation error, then the action="#{home.setarFormulario}" would never be called.
As a workaround you can set to true the attribute hideNoSelectionLabel for your s:selectItems then the noSelectionLabel will be hidden when a value is selected
<h:message for="id of the selectonemenu component " ></h:message>
or
remove the required =true from the selectonemenu tag

Resources