JSF PrimeFace: p repeat ajax update with class not working - ajax

totalListSumA is an ArrayList inside java. Inside debug mode, the arraylist work just fine. New value assigned into this list.
When user input a new value in a box, program will recalculate new sum and display inside the code shown below.
<p:inputNumber
class="caseType1"
rendered="#{inputFormTemplateView.allowEdit}"
inputStyle="text-align: center"
minValue="0"
maxValue="99999999"
decimalPlaces="0"
thousandSeparator=""
emptyValue=""
value="#{inputFormView.selectedInputFormDetail.data[dataField]}" >
<p:ajax update="dataField, #{inputForm4_1View.getColTotal()}"/>
<p:ajax update="#(.totalRow3)"></p:ajax>
</p:inputNumber>
<tr>
<td align='center'>Total</td>
<p:repeat var="item" value="#{inputForm4_1View.totalListSumA}" class="totalRow3">
<td class="cell_cal" style='text-align:center;' >
<h:outputLabel
class="totalRow3"
value="#{item}" />
</td>
</p:repeat>
</tr>
I have tried
h:panelGroup id='...'
ui:repeat id='....'
Still the value remain unchanged inside p:repeat. Any method I can try to get and show the latest value inside totalListSumA?

This is wrong
<p:ajax update="dataField, #{inputForm4_1View.getColTotal()}"/>
<p:ajax update="#(.totalRow3)"></p:ajax>
1) Ajax should have event="change" or other events, but most wrong thing is that calling bean method inside update.
2) Use listener="#{inputForm4_1View.getColTotal()}"
3) Don't use 2 same ajaxes.
Solution:
<p:ajax event="change" update="dataField, #(.totalRow3)" listener="#{inputForm4_1View.getColTotal()}"/>
If this doesn't solve your problem, try update form like update="#form" or update="yourFormId"

Related

primefaces selectonemenu change event not working for null value

I have a selectonemenu that includes some items. And a null item for showing "please choose one"..
MY goal is to query some data when I select one of them. And if i select the "please choose one" do another thing.
But eventually, the change event is fired for normal values but if I select "please choose one" item , it is not fired. Thanks for your help. Here is my code.
<p:selectOneMenu style="width: 200px" id="positionForward" value="#{hrProcessController.queryCriteria.positionForward}" converter="listConverter"
effect="fade" var="u" filter="true" filterMatchMode="startsWith" validator="#{hrProcessController.isOpenPositionForwValid}">
<f:selectItem itemLabel="#{menu['onemenu.choose']}" itemValue="#{null}"/>
<f:selectItems value="#{hrProcessController.positionList}" var="position" itemLabel="#{position.name}" itemValue="#{position}" />
<p:ajax event="change" listener="#{hrProcessController.onPositionSelect}" update="openPositionForward"/>
<p:column>
<h:outputText value="#{u==null ? menu['onemenu.choose'] : u.name}" />
</p:column>
</p:selectOneMenu>
public void onPositionSelect()
{
if(queryCriteria.getPositionForward()!=null)
{
OpenPositionQueryCriteria criteria = new OpenPositionQueryCriteria();
criteria.setPosition(queryCriteria.getPositionForward());
List<OpenPosition> openPositions = openPositionService.searchOpenPosition(criteria);
setOpenPositionList(openPositions);
}
else
{
List<OpenPosition> positions = openPositionService.getActiveOpenPositionList();
setOpenPositionList(positions);
}
}
If you use itemValue="#{null}" or itemValue="", the valueChangeListener method never will be called.
That's a better approach if you want your first item null:
<f:selectItem
itemDisabled="true"
itemLabel="#{null}"
itemValue="#{null}" />
I had the same problem.
Change event WON'T be fired by selecting default value. Why that is so is beyond me. Such things are normal usually.
I didn't find any real solution.
You should try to write custom validator and converter for this.
Try this:
Using a "Please select" f:selectItem with null/empty value inside a p:selectOneMenu
OK, I finally found the solution to this!
you need to add immediate="true" to ajax call.
Adding immediate tells ajax to ignore any potential validation errors and call the onChange anyway.
Try it.
I was with the same issue so I put the selectItem without the propertie itemValue like that:
<f:selectItem itemLabel="#{menu['onemenu.choose']}" />

Trouble using f:ajax in composite component that defines an html list

My setup is the following:
I have a composite component (taskEntry) inside another (taskList).
<ul class="tableView">
<ui:repeat value="#{cc.attrs.taskList}" var="task">
<jid1:taskEntry task="#{task}" />
</ui:repeat>
</ul>
The task entry is defined as:
<li>
<h:outputText value="#{cc.attrs.task.title} " />
<h:commandLink actionListener="#{cc.attrs.taskBean.toggle(cc.attrs.task)}">
<f:ajax execute="#this" render="??" />
</h:commandLink>
</li>
Can you suggest which Id I should render?
If I define an 'id' inside the 'li' (eg. a panelGroup), first ajax call works as expected, second call does nothing, third one gives me an JS error.
Adding a panelgrid to surround the 'li' does not render the panelgrid definition at all.
I do not want to re-render the whole list, just the jid1:taskEntry
The error I get at the 3rd click is:
java.lang.IllegalStateException: Component ID j_idt37:j_idt52:j_idt55:j_idt61 has already been found in the view.

p:pickList not fetching data after pressing p:commandButton

I have a users list page which holds the users in a p:dataTable and in each row I have an update button that shows a p:dialog popup.
The page and the dialog is managed in view scope (implemented in Spring).
When I press the editUserButton in the main page the popup appears with all data and then I type an invalid string into the fields email and username. The validation message appears, but the picklist is not populated with any value.
What could be the problem?
This is the main page (users list) snippet code:
<ui:composition>
<f:view id="bodyView">
<div id="content_body">
<ui:include src="editUserDialog.xhtml"/>
<h:form id="usersListForm">
<table width="85%" align="center">
<tr>
<td>
<p:dataTable id="usersList" var="user"
value="#{usersController.usersList}"
selectionMode="single"
rowKey="#{user.userId}">
<p:columnGroup type="header">
<p:row>
...
<p:column rowspan="2" headerText="Users"/>
...
</p:row>
</p:columnGroup>
...
<p:column id="users" >
<p:commandLink id="editUserButton" oncomplete="addEditUserConfirmation.show()" actionListener="#{addEditUserController.selectionListener}"
update=":addEditCustomerDialogForm:dialogContent">
<f:attribute value="#{user}" name="selectedUser" />
</p:commandLink>
</p:column>
</p:dataTable>
</td>
</tr>
</table>
<br/>
</h:form>
</div>
</f:view>
This is the p:dialog code:
<ui:composition>
<h:form id="addEditUserDialogForm">
<p:dialog id="addEditUserDialog" severity="alert" widgetVar="addEditUserConfirmation" draggable="true" modal="true"
resizable="false" >
<p:outputPanel id="dialogContent">
<div>
<table cellpadding="5">
<tr>
<td>
<p:inputText value="#{addEditUserController.addEditCustomerBean.userName}"
maxlength="250" size="50" label="user name" id="userName">
<f:validator validatorId="UsernameValidator"/>
</p:inputText>
<p:message for="userName"/>
</td>
</tr>
<tr>
<td>
<p:inputText value="#{addEditUserController.addEditCustomerBean.email}"
maxlength="50" size="50" label="E-mail" id="email">
<f:validator validatorId="EmailValidator"/>
</p:inputText>
<p:message for="email"/>
</td>
</tr>
</table>
<table cellpadding="5">
<tr>
<td>
<p:pickList id="customersList" iconOnly="true"
value="#{addEditUserController.customersList}" var="customer"
itemValue="#{customer.value}" itemLabel="#{customer.label}"/>
</td>
</tr>
</table>
</div>
<div align="right">
<p:commandButton value="#{isNewUser ? 'add' : 'update'}" id="updateUserButton"
actionListener="#{addEditUserController.persistUser}"
update="dialogContent"
styleClass="fiftyone-default-button"
oncomplete="handleRequest(xhr, status, args)"/>
</div>
</p:outputPanel>
</p:dialog>
</h:form>
<script type="text/javascript">
function handleRequest(xhr, status, args) {
if(!(args.validationFailed && args.validationFailed == true)) {
addEditUserConfirmation.hide();
}
}
</script>
This is the backing bean code:
import org.primefaces.model.DualListModel;
import javax.annotation.PostConstruct;
import javax.faces.event.ActionEvent;
import java.util.List;
public class AddEditUserController {
private AddEditCustomerBean addEditCustomerBean;
private DualListModel<LabelValueBean> customersList;
// ... constructor getters and setters
public void selectionListener(ActionEvent event) throws Exception {
selectedUser = event.getComponent().getAttributes().get("selectedUser");
// some code
AddEditCustomerBean = new AddEditCustomerBean();
// some code
customersList = getSomeCustomersDualListModel()
}
public void persistUser() throws Exception {
// save user to DB
}
}
First thing I'd do would be to make sure that the method selectionListener is being called (either put a break-point on it or print something and check in the console later).
If it is, you must check if the variable customersList is being updated correctly, if it's not, you probably have a problem with bean scoping.
In your sample code it isn't clear how you are setting the scope for the backing bean, so I assume you're doing it on Spring's XML config file.
Make sure you really have the backing bean in the view scope, by inspecting the contents of the view map: FacesContext.getCurrentInstance().getViewRoot().getViewMap().
Hope it helps!
This is an old question, but I also encountered this issue recently, and now being helpless. Let's see the p:pickList:
<td>
<p:pickList id="customersList" iconOnly="true"
value="#{addEditUserController.customersList}" var="customer"
itemValue="#{customer.value}" itemLabel="#{customer.label}"/>
</td>
We know the [var="customer"] is an iterator, but when validation error happens, this var is assigned to String type, it's odd. When you close this popup then re-populate it again, you will get an error, messages like this: no property label(value) on type of String... the customer var now is a String, so it has no value nor label property.
For now, I use a tricky way, it won't work out always, it depends on your code:
Assume that the value and label are unique, set customersList type of List String, customersList binds the label, find the value of the label when submit at the backend; Why this way can avoid re-populate exception, that's because the iterator is always type of String, no matter validation error occurs or not.
Hope this can help the need.

SelectOneRadio set time on selection

I've been raking my brain trying to figure this one out. I have a really simple requirement that's turning out to be a very interesting problem.
The requirement is to update a time stamp when the user chooses a selection in a radio button list.
So I have a radio button list:
...
<h:selectOneRadio value="#{mybean.myvalue}" >
<f:selectItem itemLabel="A" itemValue="A"/>
<f:selectItem itemLabel="B" itemValue="B"/>
<f:selectItem itemLabel="C" itemValue="C"/>
<f:selectItem itemLabel="D" itemValue="D"/>
<f:ajax render="timeBox" listener="#{measurements.captureTime('timeBox')}"/>
</h:selectOneRadio>
...
And a text box a little further down the page:
...
<h:outputText id="timeBox" value='#{measurements.timeBox}'>
<f:convertDateTime pattern="HH:mm:ss"/>
</h:outputText>
...
And then in the backing bean I have the listener defined:
...
public void captureTime(String id){
if(id.equals("timeBox"){
timeBox = new Date(System.currentTimeMillis());
}
}
...
But when I change the radio button, the value is not updating. I'm pretty sure this is to do with the various phases of JSF (ie. it's not being updated because of the problem in this post: http://balusc.blogspot.ca/2012/03/reset-non-processed-input-components-on.html) but I'm not entirely sure how to fix it.. I'd really like to avoid including another library if possible.
As always let me know if you need more info and I will be happy to oblige.
Thanks!
Edit
The structure of these components is:
<h:form>
<table>
<tr>
<td>
<h:select.../>
</td>
</tr>
<tr>
<td>
<h:output.../>
</td>
</tr>
</table>
</h:form>
The given construct suggests that you've duplicate components with the same ID. Make sure that you don't actually have duplicate components with the same ID.

JSF2 ajax events not triggered in dynamically included pages

I have a AdminHome.xhtml page which has a dynamic include as below:
<h:form id="masterform">
<table class="DEFTABLE">
<tbody>
<tr>
<td class="CREATESTYLE">Create
<h:selectOneMenu styleClass="SELECTBOX" id="createBox" value="#{adminWindowController.actionSelection}">
<f:ajax event="change" execute=":masterform:workspace" listener="#{adminWindowController.invokeAction}" render=":masterform:workspace :masterform:taskbar createBox"/>
<f:selectItem itemValue="NONE" itemLabel="Select one..."/>
<f:selectItem itemValue="CREATE_ENTITY_DEFINITION" itemLabel="Entity Definition"/>
<f:selectItem itemValue="CREATE_ENTITY_GROUP" itemLabel="Entity Group" />
<f:selectItem itemValue="CREATE_USER" itemLabel="User" />
<f:selectItem itemValue="CREATE_USER_GROUP" itemLabel="User Group" />
</h:selectOneMenu>
</td>
</tr>
</tbody>
</table>
<h:panelGroup id="workspace">
<table class="DEFTABLE">
<tr>
<td class="WSHEIGHT" valign="top">
<ui:include src="#{adminworkspace.workspaceContent}"/>
</td>
</tr>
</table>
</h:panelGroup>
</h:form>
The above include will get page names dynamically during various ajax events triggered on AdminHome.xhtml page.
Below is one of the dynamic pages that gets loaded when the selectOneMenu changes.
<ui:composition>
<h:form id="entdefcreateform">
<h:panelGroup id="entdefpanel">
<table>
</table>
<table cellspacing="0">
<tr>
<ui:repeat value="#{adminEntityDefnController.entDefTabList}" var="tab">
<td class="#{tab == uIUtil.getRequestMapValue('activetab','General') ? 'TABBUTTONCTIVE' : 'TABBUTTON'} ">
<h:commandLink action="#{adminWindowController.TabChange}" style="border: none;">
<f:ajax execute=":masterform:entdefcreateform:entdefpanel" render=":masterform:entdefcreateform:entdefpanel"/>
<f:param name="activetab" value="#{tab}"/>
<h:outputText value="#{tab}"/>
</h:commandLink>
</td>
</ui:repeat>
</tr>
</table>
<table class="TABCONTENTTABLE">
<tr valign="top">
<td class="TABCONTENT">
<ui:include src= "#{adminEntityDefnController.entDefTabTable.get(uIUtil.getRequestMapValue('activetab','General'))}"/>
</td>
</tr>
</table>
</h:panelGroup>
</h:form>
</ui:composition>
In JSF2, <ui:include>s are evaluated during restore view phase, not during render response phase. Therefore, they do not work dynamically (anymore). I have had the same problem after migrating from JSF 1.2 to 2.1.
I got it working by changing the action method of the bean. The trick is to return to the same page that fires the ajax request. I'm using PrimeFaces 2.2.1 and the menu fires in ajax way.
The first problem i see in your code is that you could NOT have 2 <form> : one nested in another.
I guess that's why your events don't fire.
I had the same problem in may code !
BTW BalusC could you explain more precisely what you did by
"The trick is to return to the same page that fires the ajax request. I'm using PrimeFaces 2.2.1 and the menu fires in ajax way"
This is not clear for Me
E.g. you have <ui:include src="#{bean.value}", where bean is view scope bean.
It is possible to still use dynamic page loading. You can use either of these 2 solutions:
Set javax.faces.PARTIAL_STATE_SAVING to false in web.xml for you project. It will trigger the jsf1.2 way of state saving.
When <ui:include/> evaluates the value - new instance of view scope bean is created and not taken from context. As a result, the default value for src taken. If you put the bean within the session scope (which is not good) or create new session scope bean which will contain only your page path string (to minimize session size), it will resolve the issue.
Here's another tip if you want to reset this session bean value from navigation from page to page. One of the ways is to create fake method "reset()" and put <c:if test="#{bean.reset}"></if> before <ui:include/> to make this initialization for your page. Reset can look like:
private String lastViewId;
public boolean isReset() {
String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
if (!viewId.equals(lastViewId)) {
lastViewId = viewId;
//make any clean here
}
return false;
}

Resources