passing value of primefaces tabview activeIndex to a widget managed bean - jsf

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);

Related

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.

How to select first item of a list in <h:selectOneMenu> and render the page during initial load for the first selected item

I have following code:
<h:selectOneMenu value="#{AssetSummaryPageModel.selectedSensorId}" styleClass="facility_dropDown_list" required="true" >
<f:selectItems value="#{AssetSummaryPageModel.childFacilitySelectionList}" required="true" />
<a4j:ajax event="valueChange" execute="#this" status="nameStatus"
render="assetSummaryMainPanel"/>
</h:selectOneMenu>
When I select one item from the dropdown, it is rendering the page for the selected item. But, I want to render the page (with the first item of the dropdown list) during initial load. How can I do that. Any help please!!!!
That's easy. in your AssetSummaryPageModel-Bean you will add a new method with the #PostConstruct annotation so it will be called after the bean has been constructed. In this method you will set selectedSensorId to the first item of your childFacilitySelectionList.
When your page is being rendered, JSF will see that a value was already selected and will set this one as the selected one.
#PostConstruct
public void init() {
selectedSensorId = childFacilitySelectionList.get(0);
}
I got the answer of the question. I decleared the following code in init() method in Pagemodel-Bean and it is being loaded during its initial load:
selectedSensor = getAsset().getCompanyModuleAssets().get(0);
selectedSensorId = selectedSensor.getCoModAssetId();
Thanks :-)

JSF PrimeFaces inputText inside dataTable

JSF-2.0, Mojarra 2.1.19, PrimeFaces 3.4.1
Summary of the problem: Have a p:inputText inside p:dataTable and inputText action fired by p:remoteCommand which passes the dataTable row index as a parameter with f:setPropertyActionListener. But it always passes the last row of the dataTable, not the index of the row which includes currently clicked p:inputText.
As it can be seen from my previous questions, I am trying to use p:inputText as a comment taker for a status like in Facebook or etc. Implementation includes a p:dataTable. It's rows represents each status. Seems like:
<p:dataTable id="dataTable" value="#{statusBean.statusList}" var="status"
rowIndexVar="indexStatusList">
<p:column>
<p:panel id="statusRepeatPanel">
<p:remoteCommand name="test" action="#{statusBean.insertComment}"
update="statusRepeatPanel">
<f:setPropertyActionListener
target="#{statusBean.indexStatusList}"
value="#{indexStatusList}">
</f:setPropertyActionListener>
</p:remoteCommand>
<p:inputText id="commentInput" value="#{statusBean.newComment}"
onkeypress="if (event.keyCode == 13) { test(); return false; }">
</p:inputText>
</p:panel>
</p:column>
</p:dataTable>
Upper code says when the press enter key, fire p:remoteCommand which calls the insert method of the managed bean.
#ManagedBean
#ViewScoped
public class StatusBean {
List<Status> statusList = new ArrayList<Status>();
public int indexStatusList;
public String newComment
//getters and setters
public void insertComment() {
long statusID = findStatusID(statusList.get(indexStatusList));
statusDao.insert(this.newComment,statusID)
}
Let's debug together; assuming there are three statuses shown in the p:dataTable, click in the p:inputText which in the second status(index of 1), type "relax" and press the enter key.
In the debug console, it correctly shows "relax", but it finds the wrong status because indexStatusList has the value of 2 which belongs the last status in the p:statusList. It must be 1 which is the index of p:inputText that clicked on the dataTable row.
I think problem is about p:remoteCommand which takes the last index on the screen.
How it works?
Let's imagine there is a p:commandLink instead of p:remoteCommand and p:inputText:
<p:commandLink action=#{statusBean.insertComment>
<f:setPropertyActionListener target="#{statusBean.indexStatusList}"
value="#{indexStatusList}"></f:setPropertyActionListener>
This component successfully passes the indexStatusList as currently clicked one.
Conceptual problem in this solution lies in way how p:remoteCommand works. It creates JavaScript function whose name is defined in name attribute of p:remoteCommand. As you putted this in dataTable it will iterate and create JavaScript function called test as many times as there is rows in this table, and at the end last one will be only one. So, solution can be in appending index at the name of the remoteCommand but that is bad, because you will have many unnecessary JavaScript functions. Better approach would be to create one function an pass argument to it. So define remoteCommand outside of datatable:
<p:remoteCommand name="test" action="#{statusBean.insertComment}" update="statusRepeatPanel">
and call test function like this in your onkeypress event:
test([{ name: 'rowNumber', value: #{indexStatusList} }])
This will pass rowNumber parameter in your AJAX request. In backing bean's insertComment() method you can read this parameter and do with it anything you want:
FacesContext context = FacesContext.getCurrentInstance();
Map map = context.getExternalContext().getRequestParameterMap();
Integer rowNumber = Integer.parseInt(map.get("rowNumber").toString());
NOTE: as you are updating panel in each row, maybe you can change update attribute of remoteCommand to #parent so this will work for all rows.
EDIT: You can update the specific panel in specific row with following code in Java method:
RequestContext.getCurrentinstance().update("form:dataTable:" + rowNumber + ":statusRepeatPanel")

How to retrieve and show list of values in listbox and text corresponding to list item in textarea

I need to use a list box to show some values from database and do further processing when a single value from the list is selected.
At the PrimeFaces showcase site the example loads fixed (static) data into the listbox and there is one PrimeFaces command for each list item. How do I show items in a list box dynamically, when I may not know the number of items beforehand?
I also need to show some text corresponding to the item selected in list, in a textarea. Do I have to use an event listener for this purpose? I would like to leave the text area blank at the beginning. Only when a value is selected in the list box, then I want to use a bean to retrieve and store data using that textarea. Is this possible? How do I implement this?
How do I show items in a list box dynamically, when I may not know the number of items beforehand?
Use <f:selectItems> which you bind to a List<T> property. Basic example, assuming you're using EJB/JPA to interact with DB:
private Item selectedItem; // +getter+setter
private List<Item> availableItems; // +getter
#EJB
private ItemService service;
#PostConstruct
public void init() {
availableItems = service.list();
}
with
<p:selectOneListbox value="#{bean.selectedItem}" converter="itemConverter">
<f:selectItems value="#{bean.availableItems}" var="item"
itemValue="#{item}" itemLabel="#{item.someLabel}" />
</p:selectOneListbox>
The itemConverter should implement javax.faces.convert.Converter and convert from the Item object to its unique string representation (usually its DB identifier) in getAsString() and convert the other way round getAsObject().
I also need to show some text corresponding to the item selected in list, in a textarea. Do I have to use an event listener for this purpose?
Just put a <p:ajax> (the PrimeFaces equivalent of standard JSF <f:ajax>) in the listbox which updates the textarea. E.g.
<p:selectOneListbox value="#{bean.selectedItem}" converter="itemConverter">
<f:selectItems value="#{bean.availableItems}" var="item"
itemValue="#{item}" itemLabel="#{item.someLabel}" />
<p:ajax update="textarea" />
</p:selectOneListbox>
<p:inputTextarea id="textarea" value="#{bean.selectedItem.someText}" />
It'll be invoked when you select an item.
See also:
Our h:selectOneMenu wiki page - same applies to PrimeFaces p:selectOneListbox
Yes, for demonstration purposes most of the examples are loaded with static data. But if you look at the same example on PF showcase, the second listbox code is as follows:
<h:outputText value="Scrollbar: " />
<p:selectOneListbox id="scroll" value="#{autoCompleteBean.selectedPlayer1}"
converter="player" style="height:100px">
<f:selectItems value="#{autoCompleteBean.players}"
var="player" itemLabel="#{player.name}" itemValue="#{player}" />
</p:selectOneListbox>
and f:selectItems value attribute can point to a collection, an array, a map or a SelectItem instance. So coming to the above example players could be any list that is being populated using a database in the managed bean.
But if the instance is not a SelectItem, the labels are obtained by calling a toString on each object and finally the selected itemValue is set to the selectedPlayer1 attribute but you can also see that there is a converter in between so the incoming itemValue string is converted back to a player object and then set to selectedPlayer1.
And if you want to display the selected item in a text area, you can do something like this:
<h:outputText value="Scrollbar: " />
<p:selectOneListbox id="scroll" value="#{autoCompleteBean.selectedPlayer1}"
converter="player" style="height:100px">
<f:selectItems value="#{autoCompleteBean.players}"
var="player" itemLabel="#{player.name}" itemValue="#{player}" />
<p:ajax update="displayArea"/>
</p:selectOneListbox>
<p:inputTextarea id="displayArea" value="#{autoCompleteBean.selectedPlayer1}" />
Here the inputTextarea is updated using ajax with the value selected by the user.

Resources