JSF commandLink onclick EL expression re-evaluation - jsf

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"/>

Related

How transform OneSelectMenu of PrimeFaces to BootsFaces

PrimeFaces code:
<p:selectOneMenu onchange= " submit()" value = "${internacionalBean.locale}" valueChangeListener= "#{internacionalBean.cambiarIdioma}" id = "idiomaSelect" style="width:125px">
<f:selectItems value= "#{internacionalBean.countries}" />
</p:selectOneMenu>
I changed p with b, but the valueChangeListener attribute is not defined.
Until we've implemented this feature we've obviously overlooked, you can use onchange="ajax:internacionalBean.cambiarIdioma()" update="#form". Note the slightly different syntax: you have to put ajax: at the beginning to distinguish it from a JavaScript call, and you have to provide the parentheses.
Like BalusC suggests below, you can also try to add an <f:valueChangeListener /> facet.
Would you mind to open a feature request on our bug tracker (https://github.com/TheCoder4eu/BootsFaces-OSP/issues)?

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.

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

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.
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

JSF Compound EL expression

I am trying to validate a inputText box based on the selection of a CheckBox as shown below.
< <h:inputText required="#{param[facesContext.externalContext.response.namespace'form:checkBoxId']}"> >.
The issue is as you see, the component Ids are dynamic, I should be able to use facesContext.externalContext.response.namespace inside the EL expression. Is there a solution to it, appreciate any suggestions.
Thanks.
Just bind the UIComponent to a page scoped property and access its getValue() method.
<h:selectBooleanCheckbox binding="#{checkbox}" />
<h:inputText required="#{not empty checkbox.value and checkbox.value}" />
As to the dynamicness, you can also go around by just giving it a fixed id.
<h:form id="form">
<h:selectBooleanCheckbox id="checkbox" />
<h:inputText required="#{not empty param['form:checkbox'] and param['form:checkbox']}" />
</h:form>
It's however only ugly when it gets lengthy.

Resources