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

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.

Related

passing value of primefaces tabview activeIndex to a widget managed bean

I am having a tabMenu using menu items each of the menu items has a parameter "i" that is linked to the activeIndex to indicate which page to load when the tab is clicked.
The problem I faced is that I need to get this parameter value of i to call another widget that is doing an action / processing. Is there any way I can get this parameter value of i and pass it to my widget managed bean (the widget contains a command button that is supposed to call a method in the widget managed bean and do some processing based on the menu that is selected).
The widget is saperate from the tabMenu, but still is on the same page as the tab menu. Is there a way to do this?
TabMenu is something like this:
<p:tabMenu activeIndex="#{param.i}">
<p:menuitem value="AAA" outcome="/ABC/DEF/123.xhtml">
<f:param name="i" value="0" />
</p:menuitem>... continued similar menuitem for 3 times with values for i 0-3
</p:tabMenu>
My widget contains a command button that looks like this:
<h:commandButton outcome="widget" action="#{mbean.callWidgetMethod}" >
</h:commandButton>
Can anyone please guide me? Thanks in advance.
OK, I found the answer
In the xhtml :
<h:commandButton outcome="widget" action="#{bean.callWidgetMethod}" >
<f:param name="i" value="#{param['i']}" />
</h:commandButton>
In the Managed Bean:
Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String param = params.get("i");
System.out.println("i = "+param);

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

JSF Number Validation

Is there any inbuilt number validator tag in JSF that checks whether an input entered in h:inputext field is a number?
The first question was answered. Edited to explain the next problem:
<h:inputText id="maxrecs" value="#{simpleBean.numRecords}" required="false" maxlength="4" >
<f:convertNumber longOnly="true"/>
</h:inputText>
Backing Bean
private long numRecords = null;
If I use String or Integer object in the backing bean , value is not being set. Now when I use primitive int, 0 is being printed on the screen. I would like the screen to be empty.
You can use f:convertNumber (use the integerOnly attribute).
You can get more information here.
You can use:
<f:validateLongRange minimum="20" maximum="1000" />
Where minimum is the smallest number allowed and maximum is the largest.
Look here for more details
JSF Number validation for inputtext
mention f:converterNumber component in between h inputText component and mention the attributes integerOnly and type.
<h:inputText id="textMobileId" label="Mobile" styleClass="controlfont" value="#{UserRegistrationBean.textMobile}">
<f:convertNumber integerOnly="true" type="number" />
</h:inputText>
If you enter abcd in Mobile textbox at the time when you click on commandbutton it automatically shows an error like
Mobile: 'abcd' is not a number.
i8taken solution converts number into long without validation message (at least in my case: JSF2 / global messages per page). For proper validation message you can
1. check value in action method in bean;
or
2. use converter attribute for inputText:
<h:inputText id="maxrecs" value="#{simpleBean.numRecords}" maxlength="4" converter="javax.faces.Integer" />
You can simply use the passthrough, so first add this library
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
and after use this
<h:inputText id="numberId" pt:type="number" />

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

Dynamic Action in JSF page

I have a JSF page. My CommandButton action method value is dependent on the bean variable value.
Example:
Bean headerBean has varaible actionValue with value "someBean.doAction1()"
When I use , It says headerBean.actionValue is not a method which is right.
How can I get the action value as "someBean.doAction1" instead of headerBean.actionValue.
Thanks,
You can use the brace notation for that.
<h:commandButton value="submit" action="#{someBean[headerBean.actionValue]}" />
When the #{headerBean.actionValue} returns a String of for example doAction1, then this will effectively invoke #{someBean.doAction1}.
If the bean name to be called is currently actually in the actionvalue (headerBean.actionValue returning someBean.doAction1), you need to split it into a field that returns the bean name and one that returns the method name and then use
<h:commandButton value="submit" action="#{requestScope[headerBean.beanName][headerBean.actionValue]}" />
If headerBean.beanName returns 'someBean' and headerBean.actionValue returns doAction1 the above will call #{somebean.doAction1}.

Resources