I am not sure if I am making a silly mistake, but this has not been working for me on a very simple case: In my tabview / tabs when I switch from one tab to other I want to save the data that's entered in the form. The Submit button works fine on each tab, but the tabchange event shows all my form data to be null. I have tried process with #all, #form, #this, nothing seems to work. Same with update option.
Here's the XHTML:
<h:form id="form">
<p:growl id="msgs" showDetail="true" keepAlive="5000" />
<p:tabView id="tView" dynamic="true" cache="false" >
<p:ajax event="tabChange" listener="#{deleteMe.onTabChange}" update=":form:msgs" />
<p:tab title="MyTitle I" id="tab1">
<p:fieldset legend="Personal Information" toggleable="false" >
<h:panelGrid columns="2" cellpadding="10">
Value 1: <p:inputText value="#{deleteMe.thingOne}"></p:inputText>
Value 2: <p:inputText value="#{deleteMe.thingTwo}"></p:inputText>
<p:commandButton value="Submit" id="ajax" update=":form:msgs" action="#{deleteMe.onSubmit}" />
</h:panelGrid>
</p:fieldset>
</p:tab>
<p:tab title="MyTitle II" id="tab2">
<p:fieldset legend="Social Information" toggleable="false">
<h:panelGrid columns="2" cellpadding="10">
<p:inputText value="#{deleteMe.thingThree}"></p:inputText>
<p:commandButton value="Submit" id="ajax2" update=":form:msgs" action="#{deleteMe.onSubmit}" />
</h:panelGrid>
</p:fieldset>
</p:tab>
</p:tabView>
</h:form>
And here's my backing bean:
`
import javax.annotation.PostConstruct;
import javax.inject.Named;
import org.primefaces.event.TabChangeEvent;
import org.springframework.context.annotation.Scope;
#Named(value = "deleteMe")
#Scope("view")
public class DeleteBean implements Serializable {
private static final long serialVersionUID = 47L;
private String thingOne;
private String thingTwo;
private String thingThree;
#PostConstruct
public void initialize() {
}
public void onTabChange(TabChangeEvent event) {
System.out.println("Saving draft, current index: "+ event.getTab().getTitle());
System.out.println(thingOne);
System.out.println(thingTwo);
saveDraft();
}
public void onSubmit() {
System.out.println(thingOne);
System.out.println(thingTwo);
System.out.println(thingThree);
saveDraft();
}
public void saveDraft() {
System.out.println("This is thing 1 value: "+thingOne);
System.out.println("This is thing 2 value: "+thingTwo);
System.out.println("This is thing 2 value: "+thingThree);
}
public String getThingOne() {
return thingOne;
}
public void setThingOne(String thingOne) {
this.thingOne = thingOne;
}
public String getThingTwo() {
return thingTwo;
}
public void setThingTwo(String thingTwo) {
this.thingTwo = thingTwo;
}
public String getThingThree() {
return thingThree;
}
public void setThingThree(String thingThree) {
this.thingThree = thingThree;
}
}
`
On tabchange event, it triggers the method, but the values are all null.
SystemOut O This is thing 1 value: null
SystemOut O This is thing 2 value: null
SystemOut O This is thing 2 value: null
Can you please point out if I am making some silly mistake? Thank you.
The correct answer is to use skipChildren="false" on your p:ajax commands.
https://github.com/primefaces/primefaces/issues/2525
<p:ajax event="tabChange"
skipChildren="false"
listener="#{deleteMe.onTabChange}"
update=":form:msgs" />
I have the same problem.
On changing the tab without submitting, data will be lost because of not updating the input text field. You can add ajax for Input text field.
<p:inputText id="thingOneId" value="#{deleteMe.thingOne}">
<p:ajax update="thingOneId"/>
</p:inputText>
skipchildren="true"
works for not loosing the data, but it won't update the value from inputfields.
Saw a workaround for it but I am not sure why it is working this way:
I had to add the remote command with a tabchange listener on tabView.
<p:remoteCommand name="onTabChangeProcess" process="tView, #this"/>
<p:tabView activeIndex="#{deleteMe.activeIndex}" id="tView" onTabChange="onTabChangeProcess()">
<p:ajax event="tabChange" listener="#{deleteMe.onTabChange}" update="tView" process="tView"/>
This made the form to work as expected.
Related
I want to call Java method from Primefaces dialog. I tested this code:
<h:form>
<p:dialog header="New Sensor" widgetVar="dlg" focus="name" modal="true" showEffect="fade">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="name" value="Name" />
........
<p:inputText id="enabled" label="enabled" value="#{newSensor.sensor.enabled}" />
</h:panelGrid>
<f:facet name="footer">
<p:commandButton id="ajax" value="Create Sensor" styleClass="ui-priority-primary" type="button" actionListener="#{newSensor.saveRecord()}"/>
</f:facet>
</p:dialog>
</h:form>
Java bean:
#Named
#RequestScoped
public class NewSensor implements Serializable
{
private SensorObj sensor = new SensorObj();
public SensorObj getSensor()
{
return sensor;
}
public void setSensor(SensorObj sensor)
{
this.sensor = sensor;
}
public void saveRecord(){
System.out.println(">>>>>>>!!!!!! " + sensor.getName());
}
}
Wehn I click the button nothing happens. Can you give some advice how I can fix this issue?
You should remove type="button" in your commandButton because it will prevent the button from sending a request.
Additionally, you are using actionListener in your commandButton.
Your method in the bean should have ActionEvent as its parameter.
public void saveRecord(ActionEvent actionEvent) {
System.out.println(">>>>>>>!!!!!! " + sensor.getName());
}
Please refer here for additional information.
I am developing a project with Primefaces 5.1.
In my project, I used p:idleMonitor, on my Start button click the p:idleMonitor rendered="true" is working .
On my Stop button click the p:idleMonitor rendered="false" not working and the p:idleMonitor is still processing.
Sample Code:
index.xhtml
<p:panel id="mainPanelId">
<p:commandButton value="Start" update="mainPanelId" action="{Sample.start}"/>
<p:commandButton value="Stop" update="mainPanelId" action="#{Sample.stop}"/>
<p:idleMonitor timeout="5000" rendered="#{Sample.idleRendered}">
<p:ajax event="idle" oncomplete="PF('dialogId').show();"/>
<p:ajax event="active" oncomplete="PF('dialogId').hide();"/>
</p:idleMonitor>
<p:dialog id="dialogId" widgetVar="dialogId" header="Idle">
<p:outputLabel value="Idle Mode Actived!"/>
</p:dialog>
</p:panel>
Sample.java
class Sample
{
private boolean idleRendered;
public String start()
{
idleRendered = true;
return null;
}
public String stop()
{
idleRendered = false;
return null;
}
}
A few things you should do differently.
Use <h:form>
Use actionListener by p:commandButton and void methods of your bean
XHTML
<h:form>
<p:panel id="mainPanelId">
<p:commandButton value="Start" update="mainPanelId"
actionListener="#{Sample.start}" />
<p:commandButton value="Stop" update="mainPanelId"
actionListener="#{Sample.stop}" />
<h:outputText value="#{Sample.idleRendered}" />
<p:idleMonitor timeout="5000" rendered="#{Sample.idleRendered}">
<p:ajax event="idle" oncomplete="PF('dialogId').show();" />
<p:ajax event="active" oncomplete="PF('dialogId').hide();" />
</p:idleMonitor>
<p:dialog id="dialogId" widgetVar="dialogId" header="Idle">
<p:outputLabel value="Idle Mode Actived!" />
</p:dialog>
</p:panel>
</h:form>
Bean
#Named("Sample")
#SessionScoped
public class Sample implements Serializable {
private boolean idleRendered = true;
public void start() {
idleRendered = true;
}
public void stop() {
idleRendered = false;
}
public boolean isIdleRendered() {
return idleRendered;
}
public void setIdleRendered(boolean idleRendered) {
this.idleRendered = idleRendered;
}
}
Update:
Looks like a bug, here is a workaround:
<p:outputPanel rendered="#{Sample.idleRendered}">
<p:idleMonitor timeout="5000">
<p:ajax event="idle" oncomplete="PF('dialogId').show();" />
<p:ajax event="active" oncomplete="PF('dialogId').hide();" />
</p:idleMonitor>
</p:outputPanel>
I have a p:inputTextarea and I need the value of it while processing the form. It turned out that every time I submit the form I get all the values except the one from the textarea. #{xyzUI.description} is a String object with regular getters and setters.
<ui:composition>
<h:form id="form1">
<p:panel rendered="...">
<p:panel id="formPanel">
<p:panelGrid columns="2" cellpadding="5">
<!-- other form elements -->
<p:outputLabel>Description:</p:outputLabel>
<p:inputTextarea value="#{xyzUI.description}" style="width: 350px;" counter="display" counterTemplate="{0} characters remaining" maxlength="2000" autoResize="true" rows="4" />
<h:panelGroup />
<h:outputText id="display" />
</p:panelGrid>
<p:commandButton rendered="#{not xyzUI.noChange}" action="#{xyzUI.submitForm}" update="formPanel" ajax="true" value="Apply" >
<p:ajax update="formPanel"></p:ajax>
</p:commandButton>
</p:panel>
</p:panel>
</h:form>
<ui:composition>
In my backing bean the value is always "". I don't know what's wrong.
public void submitForm()
{
...
tmp.setDescription(description); // String is always "" while debugging
myList.add(tmp);
RequestContext.getCurrentInstance().update("content");
}
I ran your code locally and discovered the issue. In the command button, remove the p:ajax call.
PrimeFaces command buttons are ajax enabled by default.
So change this:
<p:commandButton rendered="#{not xyzUI.noChange}" action="#{xyzUI.submitForm}" update="formPanel" ajax="true" value="Apply" >
<p:ajax update="formPanel"></p:ajax>
</p:commandButton>
To this:
<p:commandButton rendered="#{not xyzUI.noChange}" action="#{xyzUI.submitForm}" update="formPanel" value="Apply" />
My backing bean for reference
#ManagedBean
#ViewScoped
public class xyzUI implements Serializable{
private static final long serialVersionUID = 6259024062406526022L;
private String description;
private boolean noChange = false;
public xyzUI(){
}
public void submitForm(){
System.out.println(description);
}
public boolean isNoChange() {
return noChange;
}
public void setNoChange(boolean noChange) {
this.noChange = noChange;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
I'm working with JSF technology. I've 2 views and 2 beans. The first View (homepage.xhtml) sets a text parameter in the first Bean (UserBean) which is like so:
#ManagedBean
#SessionScoped
public class UserBean implements Serializable{
private String searchText;
public UserBean(){}
public String search() {
return "searching?faces-redirect=true&text="+searchText;
}
A commandButton in the view submits the search, and calls the UserBean.search().
I have this view in the searching.xhtml, which is a simple DataList component of PrimeFaces showing a list of a user:
<f:metadata>
<f:viewParam name="text" value="#{searchView.searchText}"/>
<f:event type="preRenderView" listener="#{searchView.init()}"></f:event>
</f:metadata>
<h:head>
<title>Search Results</title>
</h:head>
<h:body>
<h:form id="resultsForm">
<p:dataList var="user" value="#{searchView.results}" type="unordered" itemType="none" paginator="true" rows="10" styleClass="paginated">
<f:facet name="header">
Results for #{searchView.searchText}:
</f:facet>
<p:panel>
<p:commandLink update=":resultsForm:userDetail" oncomplete="PF('userDialog').show()" title="user dettagli" styleClass="ui-icon ui-icon-search" style="float:right;margin-right:50px">
<f:setPropertyActionListener value = "#{user}" target="#{searchView.selectedUser}"/>
<h:outputText value="#{user.firstName}, #{user.lastName}" />
</p:commandLink>
<h:outputText value="#{user.firstName} #{user.lastName} (#{user.email})" style="display:inline-block" />
</p:panel>
</p:dataList>
<p:dialog header="User Info" widgetVar="userDialog" modal="true" showEffect="blind" hideEffect="explode" resizable="false">
<p:outputPanel id="userDetail" style="text-align:center;">
<p:panelGrid columns="2" rendered="#{not empty searchView.selectedUser}" columnClasses="label,value">
<h:outputText value="First name:" />
<h:outputText value="#{searchView.selectedUser.firstName}" />
<h:outputText value="Last Name" />
<h:outputText value="#{searchView.selectedUser.lastName}" />
<h:outputText value="Calendar" />
<h:outputText value="#{searchView.selectedUser.visibility}" />
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
<br/>
</h:body>
In the end, I've this backing bean:
#ManagedBean
#ViewScoped
public class SearchView implements Serializable {
private List<User> results;
private User selectedUser;
private String searchText;
#EJB
private SearchingManager sm;
public void init() {
System.out.println("print search text:" + searchText);
results = sm.search(searchText);
}
public SearchView() {
}
public void setSelectedUser(User selectedUser) {
System.out.println("setter of selected user");
this.selectedUser = selectedUser;
}
public User getSelectedUser() {
System.out.println("getter of selected user");
return selectedUser;
}
It works and shows the results of the search correctly but when it opens the page of results I notice this output:
Informazioni: print search text: Mario
Informazioni: getter of selected user
So I'm wondering why that getSelectedUser() is called without selecting any user. Moreover when I select a user it shows an empty dialog and this is the outcome:
Informazioni: getter of selected user
Informazioni: getter of selected user
Informazioni: getter of selected user
Informazioni: print search text: Mario
Informazioni: getter of selected user
So it recalls the init() function why?
And the worst thing is that if we close the Dialog and reopen it, the result is something like that but with
Informazioni: print search text: null
and it stops because of NullPointerException.
I'm spending days searching about this setPropertyActionListener but I can't understand this behavior of the system.
I am lost. I researched almost every post about setPropertyListener and I do not know what I'm doing wrong. I have this JSF Page:
<ui:define name="content">
<h:form id="itemSearchForm">
<p:commandButton update=":itemForm"
icon="ui-icon ui-icon-search">
<f:setPropertyActionListener target="#{itemDetailManagedBean.itemId}"
value="test"/>
<f:setPropertyActionListener target="#{itemDetailManagedBean.accountType}"
value="test"/>
</p:commandButton>
<p:dataTable id="itemList"
paginator="true"
var="currentItem"
value="#searchItemManagedBean.searchItems}">
.
.
<p:column headerText="Detail">
<p:commandButton update=":itemForm"
oncomplete="PF('itemDetail').show()"
icon="ui-icon ui-icon-search">
<f:setPropertyActionListener target="#{itemDetailManagedBean.itemId}"
value="test"/>
<f:setPropertyActionListener target="#{itemDetailManagedBean.accountType}"
value="test"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
and itemDetailManagedean:
public class ItemDetailManagedBean implements Serializable{
private String itemId,accountType;
public ItemDetailManagedBean() {
}
public SearchForItemBean getSearchBean() {
return searchBean;
}
public String getItemId() {
return itemId;
}
public String getAccountType() {
return accountType;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public void setAccountType(String accountType) {
this.accountType = accountType;
}
}
The problem is, that the first commandButton is working as it should(so it set the properties right). But the second commandButton does not work at all. Both button shows dialog, as they should. I have itemForm on the other part of page.
Got the sollution finally. The problem was actually not in the JSF but in ServiceBean, which had changed the data table content during the loading.