In my application I am using ViewScoped Bean and it does not show selected row when a row is selected in primefaces datatable. But if I changed the Bean to a SessionScoped Bean then it shows the selected row perfectly.
my code is like below.
<h:form id="form">
<p:growl id="msgs" showDetail="true" />
<p:dataTable var="pMData" rowIndexVar="rowIndex" value="# {managedBean.dataModel}" selectionMode="single" paginator="true" rows="100"
widgetVar="pMTable" emptyMessage="No Records Found." filteredValue="#{managedBean.filteredRecords}" selection="#{managedBean.selectedRecord}" rowKey="#{pMData.cellid}">
<p:ajax event="rowSelect" listener="#{managedBean.onRowSelect}"
update=":form:display :form:msgs" oncomplete="moreviewDialog.show()" />
<p:ajax event="rowUnselect" listener="#{managedBean.onRowUnselect}" update=":form:msgs"/>
<p:column headerText="Cell Name" filterBy="#{pMData.cellid}" filterStyle="display:none" >
<h:outputText value="#{pMData.modifiedCellID}" />
</p:column>
</p:dataTable>
<p:dialog header="History Data" widgetVar="moreviewDialog" resizable="false" id="moreviewDlg"
showEffect="fade" hideEffect="explode" modal="true">
<h:panelGrid id="display" columns="2" cellpadding="4" style="margin:0 auto;">
<p:lineChart id="category" value="# {managedBean.createCategoryModel(managedBean.selectedRecord.cellid)}" legendPosition="e"
title="NodeB Throughput(kbit/s)" minY="0" maxY="5000" style="height:300px;margin-top:20px"/>
</h:panelGrid>
</p:dialog>
</h:form>
and my managedBean CDI is like this.
#Named(value = "managedBean")
#ViewScoped
public class ManagedBean implements Serializable {
public void setSelectedRecord(PMData selectedRecord1){
this.selectedRecord=selectedRecord1;
}
public PMData getSelectedRecord(){
return selectedRecord;
}
public void onRowSelect(SelectEvent event) {
FacesMessage msg = new FacesMessage("NodeB Selected", String.valueOf(((PMData) event.getObject()).getCellid()));
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onRowUnselect(UnselectEvent event) {
FacesMessage msg = new FacesMessage("Row Unselected",((PMData) event.getObject()).getCellid());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public PMDataModel getDataModel() {
return dataModel;
}
public CartesianChartModel createCategoryModel(String key) { .....}
public List<PMData> getFilteredRecords() {
return filteredRecords;
}
public void setFilteredRecords(List<PMData> filteredRecords) {
// System.out.println("came ");
this.filteredRecords = filteredRecords;
}
}
and PMData and PMDataModel classes are working normally. Can someone help me to select the row while still using viewscoped bean.
I think I found the answer. the error is with the dialogbox. I put dynamic=true in dialogbox. Now working perfectly.
Related
I have a dataTable with dynamic Columns.
So I use primefaces 5.3 and jsf 2.2
Here is code :
<h:form id="form1">
<p:dataTable var="etudiant" widgetVar="etdTable" paginator="true" rows="10"
rowsPerPageTemplate="5,10,15" value="#{etudiantController.etudiants}"
lazy="false" emptyMessage="Aucune etudiant trouvé"
filteredValue="#{etudiantController.filteredEtudiants}">
<p:column filterBy="#{etudiant.nomEtudiant}" filterMatchMode="exact">
<f:facet name="header">
<h:outputText value="Nom" />
</f:facet>
<h:outputText value="#{etudiant.nomEtudiant}" />
</p:column>
[...]
Bean :
private List<Etudiant> etudiants;
private List<Etudiant> filteredEtudiants;
public List<Etudiant> getEtudiants() {
return etudiantService.getAllEtudiants();
}
public List<Etudiant> getFilteredEtudiants() {
return this.filteredEtudiants;
}
public void setFilteredEtudiants(List<Etudiant> filteredEtudiants) {
this.filteredEtudiants = filteredEtudiants;
}
getAllEtudiants() load all students.
Exception :
java.lang.NullPointerException
at org.primefaces.component.datatable.feature.FilterFeature.filter(FilterFeature.java:150)
at org.primefaces.component.datatable.feature.FilterFeature.encode(FilterFeature.java:117)
at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:78)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:924)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863) [...]
java.lang.IllegalStateException: CDATA tags may not nest
at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.startCDATA(HtmlResponseWriter.java:681) at javax.faces.context.ResponseWriterWrapper.startCDATA(ResponseWriterWrapper.java:179)[...]
something is wrong here??
I'm ot sure but did you try to inicialize the list?
try this:
private List<Etudiant> filteredEtudiants = new ArrayList<>();
I am using primefaces 5.1 and still facing problem with p:dialog and p:inputText within that dialog.
Here is the .xhtml content
<ui:define name="content">
<f:metadata> <f:viewAction action="#{vLoginController.initSetup}" /> </f:metadata>
<h:form id="vhome" prependId="false">
<table>
<tr>
<td>
<p:commandButton value="Place Order" action="#{vLoginController.placeOrderHomePage}"
update="logindialog, signupdialog"/>
</td>
</tr>
</table>
<p:dialog id="logindialog" header="Login / Sign up" visible="#{vLoginController.loginDialog}"
draggable="false" resizable="false" modal="true">
<p:messages autoUpdate="true"/>
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="inuserid" value="EmailID:" />
<p:inputText id="inuserid" size="40" value="#{vLoginController.user.userId}" />
<h:outputLabel for="inpassword" value="Password:" />
<p:password id="inpassword" size="20" value="#{vLoginController.user.password}" />
<f:facet name="footer">
<p:commandButton value="Login" process="#form" action="#{vLoginController.validateLogin}" update="logindialog"/>
<p:commandButton value="Sign up" action="#{vLoginController.showSignup}" update="logindialog, signupdialog"/>
</f:facet>
</h:panelGrid>
</p:dialog>
<p:dialog id="signupdialog" header="Sign up / Login" visible="#{vLoginController.signupDialog}"
draggable="false" resizable="false" modal="true">
<p:outputLabel>Test</p:outputLabel>
</p:dialog>
</h:form>
</ui:define>
Here is the supporting Bean
#Named
#SessionScoped
public class VLoginController extends BaseController implements Serializable {
private VUser user;
public VLoginController() {
}
public void placeOrderHomePage() {
loginDialog = true;
signupDialog = false;
}
public String validateLogin() {
// Validate the screen fields
FacesMessage msg = new FacesMessage();
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext context = FacesContext.getCurrentInstance();
if (user.getUserId() == null || user.getPassword() == null) {
msg.setSummary("Enter User ID and Password");
context.addMessage("screenvalidation", msg);
return null;
}
}
}
public class VUser implements Serializable {
public VUser() {
}
private int userSeq;
private String userId;
private String userType;
private String password;
private String salt;
private int active;
}
The userID and password in the user object are always null. Have gone through various forums content and tried like adding outputpanel around them etc., but none works. Have kept the code very similar to what the primefaces showcase says, still doesn't work.
Any solution please.. Please note that there is no problem in showing or hiding the dialog boxes, those logic works perfect. I just need to get the values entered by the user in the dialog fields to the bean..
I am getting a null selected row when I press the showDialog command button
I can't see what is my problem
This is my first form:
<h:form id="firstForm">
<p:commandButton action="#{testBB.showDialog}" id="showDialog"
update=":secondForm" value="#{msg['show.dialog']}" />
</h:form>
This is my second form:
<h:form id="secondForm">
<p:dataTable id="testDatatable"
rendered="#{not empty testBB.list}"
rowKey="#{order.orderNumber}"
selection="#{testBB.selectedRow}"
selectionMode="single"
sortBy="customerName" value="#{testBB.list}" var="order">
<p:column headerText="#{msg['order.number']}">
<h:outputText value="#{order.orderNumber}" />
</p:column>
<p:column headerText="#{msg['total.value']}">
<h:outputText value="#{order.totalValue}" />
</p:column>
</p:dataTable>
</h:form>
My backing bean:
#ManagedBean
#ViewScoped
public class TestBB implements Serializable {
private List<Order> list;
private Order selectedRow;
public void showOrder() {
try {
System.out.println(selectedRow);
} catch (Exception exception) {
}
}
}
And my DTO:
public class Order implements Serializable {
private int orderNumber;
private double totalValue;
public void showOrder() {
try {
System.out.println(selectedRow);
} catch (Exception exception) {
}
}
/** Getters and setters */
}
What is wrong in my code?
Put
<p:ajax event="rowSelect" />
<p:ajax event="rowUnselect" />
inside your datatable for selection/unselection to happen as soon as click happens.
If you need selection only on button click use 'process' like this
<p:commandButton process=":secondForm:testDatatable" update=":secondForm"/>
You need to update the model on rowSelection. This can be done using a <p:ajax event="rowSelect" />. Here is how I think your Datatable should look like:
<p:dataTable id="testDatatable"
rendered="#{not empty testBB.list}"
rowKey="#{order.orderNumber}"
selection="#{testBB.selectedRow}"
selectionMode="single"
sortBy="customerName" value="#{testBB.list}" var="order">
<p:ajax event="rowSelect" />
<p:column headerText="#{msg['order.number']}">
<h:outputText value="#{order.orderNumber}" />
</p:column>
<p:column headerText="#{msg['total.value']}">
<h:outputText value="#{order.totalValue}" />
</p:column>
</p:dataTable>
A good example can be found here (Primefaces Demo).
As Kerem Baydogan suggested you have to include process attribute with your data table id in your command button.
If you are not including process attribute then no components will be processed in the component tree and no modal values will be updated hence you are getting selection as null.
I feel there is no need of updating data table if you are not changing its state.
I'm new to jsf and I'm using Primefaces 4.0 to write a tabView.
I want to do something in my Backing Bean when specific tab is clicked, so I tried this:
page:
<p:tabView effect="fade" effectDuration="normal">
<p:ajax event="tabChange" listener="#{myConsoleBean.onTabChange}" update=":rightForm"/>
<p:tab title="My">
</p:tab>
<p:tab id="statTab" title="Stat">
</p:tab>
</p:tabView>
Backing Bean:
public void onTabChange(final TabChangeEvent event) {
TabView tv = (TabView) event.getComponent();
int activeTabIndex = tv.getActiveIndex();
System.out.println(activeTabIndex);
if(activeTabIndex==1)//Stat tab clicked
{
//do something here...
}
}
Everything works till now,but the Backing Bean is slow for some reason,I want to show a Dialog which contains a progress bar while the Backing Bean is progressing:
Dialog like this:
<p:dialog id="pBarDialog" header="Progressing..." widgetVar="dlg" modal="true" height="70" resizable="false" closable="false">
<h:outputText value="Please wait, we're generating your info..." />
<p:progressBar widgetVar="pbAjax" ajax="true" value="100" styleClass="animated"> </p:progressBar>
</p:dialog>
So, how can I show the dialog when I click the "Stat" tab?
You could do something like this :
public void onTabChange(TabChangeEvent event) {
TabView tv = (TabView) event.getComponent();
int activeTabIndex = tv.getActiveIndex();
System.out.println(activeTabIndex);
if(activeTabIndex==1)//Stat tab clicked
{
//do something here...
}
if(activeTabIndex==2){
RequestContext.getCurrentInstance().execute("PF('dlg').show()"); //For Primeface 4.0
RequestContext.getCurrentInstance().execute("dlg.show()"); //Before Primeface 4.0
}
}
A solution could be to use the visible attribute on the dialog:
<p:dialog id="pBarDialog" header="Progressing..." visible="#{myConsoleBean.showDialog}"
modal="true" height="70" resizable="false" closable="false">
In your bean:
private boolean showDialog;
public void displayDialog() {
showDialog = true;
}
public boolean getShowDialog() {
return showDialog;
}
And then
if(activeTabIndex==1)//Stat tab clicked
{
myConsoleBean.displayDialog();
}
Also be sure that your ajax components updates the dialog
I think I resolved this problem.
I used p:remoteCommand after I saw this thread.
And here's my final codes:
Page:
<p:tabView effect="fade" effectDuration="normal">
<p:ajax event="tabChange" listener="#{myConsoleBean.onTabChange}" oncomplete="dlg.hide()" update=":rightForm"/>
<p:tab title="My">
</p:tab>
<p:tab id="statTab" title="Stat">
<p:remoteCommand actionListener="#{myConsoleBean.goToUrl('myStat.xhtml')}" update=":rightForm" name="showStat" global="true" onstart="dlg.show()" oncomplete="dlg.hide()"></p:remoteCommand>
</p:tab>
</p:tabView>
<p:dialog id="pBarDialog" header="Progressing..." widgetVar="dlg" modal="true" height="70" resizable="false" closable="false">
<h:outputText value="Please wait, we are generating your info..." />
<p:progressBar widgetVar="pbAjax" ajax="true" value="100" styleClass="animated">
</p:progressBar>
</p:dialog>
Bean:
public void onTabChange(TabChangeEvent event) {
TabView tv = (TabView) event.getComponent();
int activeTabIndex = tv.getActiveIndex();
if(activeTabIndex==1)
{
RequestContext.getCurrentInstance().execute("showStat()");
}
}
No matter how, thank you both,Lamq and Emil Kaminski.
I will never find that thread without your help because I type key words from your answers.
I know this is a very common issue which happens for a variety of reasons, but although I have searched about it a lot, I didn't manage to find a solution for my case.
My primefaces commandButton is inside an h:form and is declared as follows:
<p:commandButton action="#{userGroupBean.createOrUpdateItemAction}"
value="#{userGroupBean.actionCreateOrUpdateLabel}"
icon="iconDisk"
update="#form"
oncomplete="window.scrollTo(0,0);" />
My UserGroupBean is ViewScoped.
This button when clicked is supposed to create a userGroup and show a "Successful creation" message. Instead of doing this it just shows "Please wait" loader for a second and then does nothing. There are no errors in the log and through remote debugging I confirmed that it doesn't enter the action method.
The weird thing is that when I run the same code in a local Tomcat installation it runs successfully. Also, on the remote server this application is deployed, this used to work just fine. All happened suddenly, and I have a lot of commandButtons like this one, across my application which still work great. Something seems to go wrong just with this particular page .
I use PrimeFaces 3.1 version, I dont know what other information is usefull to provide.
Any help/ideas is/are appreciated.
EDIT
This is userGroup.xhtml (the page whose buttons do not work) code:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:comps="http://java.sun.com/jsf/composite/components"
template="/WEB-INF/templates/userGroup/edit.xhtml">
<f:metadata>
<f:event type="preRenderView" listener="#{userGroupBean.initUserGroupUsersList}" />
</f:metadata>
<ui:define name="title">
User Group
</ui:define>
<ui:define name="centerUnit">
<h:form>
<h:panelGrid columns="3" styleClass="ui-messages-info ui-corner-all" rendered="#{not empty flash.messages_info}">
<span class="ui-message-info-icon"></span>
#{flash.messages_info}
</h:panelGrid>
<p:messages showDetail="true" globalOnly="true" />
<p:panel header="Settings">
<h:panelGrid columns="3" cellpadding="5">
<h:outputLabel for="title" value="User Group Title:" />
<p:inputText id="title" value="#{userGroupBean.userGroup.title}" />
<p:message for="title" />
</h:panelGrid>
</p:panel>
<p:panel header="Members">
<p:pickList value="#{userGroupBean.usersGroupUsersList}" var="user"
iconOnly="true"
converter="userConverter"
itemLabel="#{user.username}" itemValue="#{user}">
<f:facet name="sourceCaption">Available</f:facet>
<f:facet name="targetCaption">Participating</f:facet>
<p:column style="width:25%">
<p:graphicImage value="#{facesContext.externalContext.request.contextPath}/../file?thumbnail=&downloadPath=#{user.contactDetails.picture.downloadPath}" width="40" height="40" />
</p:column>
<p:column style="width:25%">
<h:outputText value="#{user.username}" />
</p:column>
<p:column style="width: 50%">
<h:outputText value="#{user.contactDetails.lastName} #{user.contactDetails.firstName}"/>
</p:column>
</p:pickList>
</p:panel>
<p:commandButton
action="#{userGroupBean.createOrUpdateItemAction}"
value="#{userGroupBean.actionCreateOrUpdateLabel}"
icon="iconDisk"
update="#form"
oncomplete="window.scrollTo(0,0);" />
<p:separator />
<p:outputPanel style="text-align:right" layout="block" rendered="#{!userGroupBean.userGroup.isNew() and userGroupBean.hasUserModifyUserGroupAuthority()}">
<h:panelGroup>
<p:commandButton value="Delete" title="Do you want to delete this user group?"
action="#{userGroupBean.deleteItemAction}"
update="#form"
icon="iconDelete" />
<p:commandButton value="Leave user group" title="I want to leave this user group"
action="#{userGroupBean.userInSessionLeavesUserGroupAction}"
update="#form"
icon="iconUserGo"/>
</h:panelGroup>
</p:outputPanel>
</h:form>
</ui:define>
The UserGroupBean.java:
#Controller("userGroupBean")
#Scope(value = "view")
public class UserGroupBean extends GenericBean<UserGroup> {
private static final long serialVersionUID = 1L;
final Log logger = LogFactory.getLog(getClass());
#Autowired
private SessionServiceImpl sessionService;
#Autowired
protected UserGroupService userGroupService;
#Autowired
protected UserService userService;
#Override
public String getPageCreateOrUpdate() { return "userGroup.xhtml"; }
#Override
public String getPageList() { return "../../my/userGroups.xhtml"; }
/** Wrapper method which calls getItem() */
public UserGroup getUserGroup() { return getItem(); }
/** Wrapper method which calls setItem() */
public void setUserGroup(UserGroup UserGroup) { setItem(UserGroup); }
protected UserGroup findItemById(Integer userGroupId) {
return userGroupService.findUserGroupById(userGroupId);
}
#Override
protected void resolveCreateRequest(HttpServletRequest req) {
logger.debug("UserGroupBean::resolveCreateRequest()");
setItem( userGroupService.initializeUserGroup("") );
}
#Override
protected String createItem() {
try {
if(!isValidUsersSelection(new ArrayList<User>(usersGroupUsersList.getTarget())))
return null;
List<Integer> userIds = new ArrayList<Integer>();
for(User user: usersGroupUsersList.getTarget())
userIds.add(user.getId());
userGroupService.saveUserGroup(getUserGroup(), userIds);
helperFacesContext.addInfoMessageToFlash("User Group successfully created.");
return getPageCreateOrUpdate()+"?action=update&id="+getItem().getId()+"&faces-redirect=true";
}
catch (Exception e) {
JsfUtils.error("There was an error", e.getMessage());
return null;
}
}
.....
}
And finally the UservConverter.java
#FacesConverter(value = "userConverter")
public class UserConverter extends GenericConverter {
final Log logger = LogFactory.getLog(getClass());
private UserDAO getUserDAO(FacesContext facesContext) {
// #Autowired gives null
return (UserDAO) FacesContextUtils.getWebApplicationContext(facesContext).getBean("userDAO");
}
/**
* converts the String representation of the key back to the Object
*/
#Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) throws ConverterException {
logger.info("UserConverter::getAsObject("+value+")");
Integer userId = Integer.valueOf(value);
try {
return getUserDAO(context).findById(userId);
} catch(Exception e) {
throw new ConverterException(handleException(context,e.getMessage()));
}
}
NEW CLUE: When I restart the server and only after that, when I access this page and manage to create a user group before userGroup.xhtml is fully loaded, the user group is created just fine. If I restart the server and wait till the page is loaded and then create a user group again nothing happens. This problem will drive me crazy at the end.