Losing checked info in p:datatable while changing page - jsf

I know this is not a bug.
But i need a suggestion, what can i do not to lose checked knowledge of checked lines?
On JSF page:
<h:form prependId="false" id="searchUserFormTable" >
<p:dataTable id="selectUserTable" var="user"
value="#{userListController.lazyDataModel}" paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rows="2" paginatorPosition="bottom" rowKey="#{user}"
lazy="true"
rowsPerPageTemplate="2,10,20,30,40,50"
rendered="#{userListController.lazyDataModel != null}" selection="#{systemMessageEditController.receiverList}"
scrollable="true" scrollHeight="250" resizableColumns="false" >
<p:column selectionMode="multiple" width="18" />
<f:facet name="header">
<h:outputText value=" Users (#{userListController.lazyDataModel.rowCount})" />
</f:facet>
<p:column filterBy="#{user.name}" headerText="Name" filterMatchMode="contains" width="80">
#{user.name}
</p:column>
<p:column filterBy="#{user.surname}" headerText="Surname" filterMatchMode="contains" width="80">
#{user.surname}
</p:column>
<p:column headerText="Gender" width="80">
#{user.gender}
</p:column>
<p:column headerText="City" width="80">
#{user.address.city.name}
</p:column>
<p:column headerText="Status" width="80">
#{user.userStatus}
</p:column>
<p:column headerText="User Detail" width="80">
<h:link value="User Detail" outcome="/view/admin/usermanagement/userInfo.jsf">
<f:param name="userId" value="#{user.id}" />
</h:link>
</p:column>
</p:dataTable>
<p:commandButton value="Tamam" oncomplete="userListDlg.hide();" update=":newMessageForm"></p:commandButton>
</h:form>
All the controller:
#ManagedBean(name="systemMessageEditController")
#ViewScoped
public class SystemMessageEditController {
#ManagedProperty(value = "#{systemMessageService}")
SystemMessageService systemMessageService;
#ManagedProperty(value = "#{securityBean}")
SecurityBean securityBean;
#ManagedProperty(value = "#{systemMessageReceiverService}")
SystemMessageReceiverService systemMessageReceiverService;
#ManagedProperty(value = "#{systemMessageAnswerService}")
SystemMessageAnswerService systemMessageAnswerService;
private SystemMessage systemMessage = new SystemMessage();
private SystemMessageAnswer systemMessageAnswer = new SystemMessageAnswer();
private SystemMessageReceiver systemMessageReceiver = new SystemMessageReceiver();
private User[] receiverList;
private boolean dummy;
public void prepareToEdit(){
systemMessage = systemMessageService.findById(systemMessage.getId());
}
public void prepareToSendMessage(){
systemMessage = new SystemMessage();
receiverList = null ;
}
public void sendMessage(){
if(Util.isNotNull(systemMessage.getTitle())){
boolean success = false;
systemMessageAnswer.setUser(securityBean.getUser());
systemMessage.getSystemMessageAnswerList().add(systemMessageAnswer);
systemMessage.setUserSender(securityBean.getUser());
systemMessageAnswer.setSystemMessage(systemMessage);
if(!systemMessage.isSendAll()){
addMessageReceiver();
}
systemMessage = systemMessageService.save(systemMessage);
systemMessageAnswer = new SystemMessageAnswer();
success = true;
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, FacesUtils.getMessageByKey("systemmessage.send.success"), FacesUtils.getMessageByKey("systemmessage.send.success"));
FacesContext.getCurrentInstance().addMessage("", message);
RequestContext context = RequestContext.getCurrentInstance();
context.addCallbackParam("success", success);
}
else{
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, FacesUtils.getMessageByKey("systemmessage.null.title"), FacesUtils.getMessageByKey("systemmessage.null.title"));
FacesContext.getCurrentInstance().addMessage("", message);
}
}
public void setRead(SystemMessage message){
message.setReaded(true);
systemMessageService.save(message);
}
public void addMessageReceiver(){
for(User user : receiverList){
SystemMessageReceiver messageReceiver = new SystemMessageReceiver();
messageReceiver.setReceiver(user);
messageReceiver.setSystemMessage(systemMessage);
messageReceiver.setReaded(false);
systemMessage.getSystemMessageReceiverList().add(messageReceiver);
}
}
public void deleteMessage(){
boolean success = false;
systemMessageService.delete(systemMessageService.findById(systemMessage.getId()));
success = true;
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, FacesUtils.getMessageByKey("systemmessage.delete.success"), FacesUtils.getMessageByKey("systemmessage.delete.success"));
FacesContext.getCurrentInstance().addMessage("", message);
RequestContext context = RequestContext.getCurrentInstance();
context.addCallbackParam("success", success);
}
public void sendMessageAnswer(){
systemMessageAnswer.setUser(securityBean.getUser());
systemMessageAnswer.setSystemMessage(systemMessage);
systemMessageAnswerService.save(systemMessageAnswer);
if(!systemMessage.isSendAll()){
systemMessage.setSystemMessageReceiverList(systemMessageService.getReceiverListOfMessage(systemMessage));
for(SystemMessageReceiver systemMessageReceiver : systemMessage.getSystemMessageReceiverList()){
if(!systemMessageReceiver.getReceiver().getId().equals(securityBean.getUser().getId())){
systemMessageReceiver.setReaded(false);
systemMessageReceiver.setShowed(false);
systemMessageReceiverService.save(systemMessageReceiver);
}
}
}
systemMessage.getSystemMessageAnswerList().add(systemMessageAnswer);
systemMessageAnswer = new SystemMessageAnswer();
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, FacesUtils.getMessageByKey("systemmessage.send.success"), FacesUtils.getMessageByKey("systemmessage.send.success"));
FacesContext.getCurrentInstance().addMessage("", message);
RequestContext context = RequestContext.getCurrentInstance();
context.addCallbackParam("success", true);
}
public SystemMessageService getSystemMessageService() {
return systemMessageService;
}
public void setSystemMessageService(SystemMessageService systemMessageService) {
this.systemMessageService = systemMessageService;
}
public SystemMessage getSystemMessage() {
return systemMessage;
}
public void setSystemMessage(SystemMessage systemMessage) {
ArrayList<String> fetchedAttributes = new ArrayList<String>();
fetchedAttributes.add("systemMessageAnswerList");
this.systemMessage = systemMessageService.loadWithFetchedAttributes(systemMessage.getId(),fetchedAttributes);
}
public SystemMessageAnswer getSystemMessageAnswer() {
return systemMessageAnswer;
}
public void setSystemMessageAnswer(SystemMessageAnswer systemMessageAnswer) {
this.systemMessageAnswer = systemMessageAnswer;
}
public SecurityBean getSecurityBean() {
return securityBean;
}
public void setSecurityBean(SecurityBean securityBean) {
this.securityBean = securityBean;
}
public SystemMessageReceiverService getSystemMessageReceiverService() {
return systemMessageReceiverService;
}
public void setSystemMessageReceiverService(
SystemMessageReceiverService systemMessageReceiverService) {
this.systemMessageReceiverService = systemMessageReceiverService;
}
public SystemMessageAnswerService getSystemMessageAnswerService() {
return systemMessageAnswerService;
}
public void setSystemMessageAnswerService(
SystemMessageAnswerService systemMessageAnswerService) {
this.systemMessageAnswerService = systemMessageAnswerService;
}
public SystemMessageReceiver getSystemMessageReceiver() {
return systemMessageReceiver;
}
public void setSystemMessageReceiver(SystemMessageReceiver systemMessageReceiver) {
this.systemMessageReceiver = systemMessageReceiver;
}
public User[] getReceiverList() {
return receiverList;
}
public void setReceiverList(User[] receiverList) {
this.receiverList = receiverList;
}
I am losing checked info while jumping one pagination number to another, when i checked some rows, then jump another pagination number in datatable, and go back to old pagination number i loose the checked info, i see nothing has changed.

This is how #ViewScoped works. See the following answer from BalusC:
A view scoped bean lives as long as you interact with the same view (i.e. you return void or null in bean action method). When you navigate away to another view, e.g. by clicking a link or by returning a different action outcome, then the view scoped bean will be trashed by end of render response and not be available in the next request.
which explains that in cases like yours (I just read in one of your comment that you jump to another page before you lose the selection, you should note that in your question too!) the bean is destroyed, so when you navigate back to your dataTable view it gets reconstructed again. This is the reason why receiverList is empty => no selection.
If you want to save your data while navigating between different views, use a bean with scope wider than #ViewScoped, or simply save the selection to a table in your DB.
EDIT
The problem could be in your rowKey attribute. In the current code it points to the user object, in this case make sure that this objects has proper hashCode, equals and toString implementations. If the user class actually has a key or something, it would be easier to change rowKey to rowKey="#{user.id}".

Check the Showcase. I think it works just like you want.

You are probably sending the data via ajax request you should make sure that it process dataTable itself

Related

h:selectBooleanCheckbox being selected in rich:dataTable is lost when using Pagination

I have list of h:selectBooleanCheckBox in rich:dataTabe. Also, there is pagination for the datatable.
The problem is when I click the next page number, the selected checkboxes at the first page of the datatable is gone. Though they are selected, clicking the next/previous page make them deselected.
Any idea about the problem?
These are the annotations for bean.
#ManagedBean(name = "bean")
#ViewScoped
To clarify it, I've attached my facelets and bean code below:
<rich:dataTable value="#{bean.ssTable}" var="data" iterationStatusVar="it" id="myDataTable">
...
<rich:column id="includeInWHMapping" >
<f:facet name="header">
<h:selectBooleanCheckbox value="#{bean.selectAll}" valueChangeListener="#{bean.selectAllCheckBox}">
<f:ajax render="myDataTable" />
</h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox id="selectedForWHProcess" value="#{bean.checked[data]}">
<f:ajax actionListener="#{bean.selectAllRows}" />
</h:selectBooleanCheckbox>
</rich:column>
...
</rich:dataTable>
Bean code:
private Map<StandardStructure, Boolean> checked = new HashMap<StandardStructure, Boolean>();
private boolean selectAll;
/* Controller */
public MyController() {
super(new DataSetParameters());
logger.info("StandardStructureController created.");
Column rowid_col =new Column("rowid", "rowid", "No.", FilterTypes.NUMERIC, true, true, "");
Column fileid_col =new Column("fileid", "fileid", "File ID", FilterTypes.STRING, true, true, "");
Column releasetag_col =new Column("releasetag", "releasetag", "Releasetag ID", FilterTypes.STRING, true, true, "");
Column applicationid_col =new Column("applicationid", "applicationid", "Application ID", FilterTypes.STRING, true, true, "");
Column filename_col =new Column("filename", "filename", "Filename", FilterTypes.STRING, true, true, "ASC");
Column includeInWHMapping_col =new Column("includeInWHMapping", "includeInWHMapping", "Include in WH Mapping?", FilterTypes.NONE, true, true, "");
columns.put("fileid", fileid_col);
columns.put("releasetag", releasetag_col);
columns.put("applicationid", applicationid_col);
columns.put("filename", filename_col);
columns.put("includeInWHMapping", includeInWHMapping_col);
initialize();
setOrderField("importDate");
setOrder("DESC");
dataSetParameters.setColumns(columns);
loadTable();
}
/** getter/setter.. */
public boolean isSelectAll() {
return selectAll;
}
public void setSelectAll(boolean selectAll) {
this.selectAll = selectAll;
}
public Map<StandardStructure, Boolean> getChecked() {
return checked;
}
public void setChecked(Map<StandardStructure, Boolean> checked) {
this.checked = checked;
}
/** Load ssTable */
private void loadTable() {
try{
ssTable = new StandardStructureDao(dataSetParameters).getAllStandardStructure();
}catch (Exception ex){
System.out.println("Exception in loading table:"+ex);
}
}
/** Get ssTable */
public Collection<StandardStructure> getSsTable(){
return ssTable.getDto();
}
/** Pagination */
public void doPaginationChange(ActionEvent event) {
super.doPaginationChange(event);
loadTable();
/* trying to set the value of list of checkboxes after loading the table */
Iterator<StandardStructure> keys = checked.keySet().iterator();
while(keys.hasNext()){
StandardStructure ss = keys.next();
if(checked.get(ss)){ /* getting checked boxes */
/* Got stuck here. */
/* How do we just set the true (boolean) value only
for list of checkboxes though they are in Map?*/
System.out.println("Row id: " + ss.getRowid() + " Checked : " + checked.get(ss));
}
}
}
/** Select all the list of checkbox in datatable */
public void selectAllCheckBox(){
for(StandardStructure item : ssTable.getDto()){
if(!selectAll)
checked.put(item, true);
else
checked.put(item, false);
}
}
/** Select row of data in datatable */
public void selectAllRows(ValueChangeEvent e) {
boolean newSelectAll = (Boolean) e.getNewValue();
Iterator<StandardStructure> keys = checked.keySet().iterator();
logger.info("Rows selected..." + newSelectAll);
while(keys.hasNext()) {
StandardStructure ss = keys.next();
checked.put(ss, newSelectAll);
System.out.println("File::"+ss.getRowid()+":"+newSelectAll);
}
}
Many Thanks!
Since your code is unclear and confusing, I'll provide you the minimal example how pagination with select all on current page MIGHT look like. With no action listeners, just getters and setter. As simple as I could.
First XHTML:
<h:form>
<rich:dataTable value="#{bean.valuesOnPage}" var="data" id="dataTable" rows="20">
<rich:column>
<f:facet name="header">
<h:selectBooleanCheckbox value="#{bean.selectAll}">
<f:ajax render="dataTable" />
</h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox value="#{bean.checked[data]}">
<f:ajax />
</h:selectBooleanCheckbox>
</rich:column>
<!-- other columns -->
</rich:dataTable>
</h:form>
Then the bean:
#ManagedBean(name = "bean")
#ViewScoped
public class MyBean {
// when the view is first loaded this is empty
// until someone will click one of checkboxes
private Map<Object, Boolean> checked = new HashMap<Object, Boolean>();
private boolean selectAll;
private List<Object> valuesOnPage;
private int currentPage = -1;
MyBean() {
setCurrentPage(1);
}
// no setter
public Map<Object, Boolean> getChecked() {
return checked;
}
public int getCurrentPage() {
return currentPage;
}
public boolean getSelectAll() {
return selectAll;
}
// no setter
public List<Object> getValuesOnPage() {
return valuesOnPage;
}
private void loadTable() {
try {
// gets data from data base
valuesOnPage = getData(currentPage);
} catch (Exception ex) {
System.out.println("Exception in loading table:" + ex);
}
}
public void setCurrentPage(int currentPage) {
if (this.currentPage != currentPage) {
this.currentPage = currentPage;
loadTable();
// we don't need it selected, especially if it
// was a paged we've never been on
selectAll = false;
}
}
public void setSelectAll(boolean selectAll) {
this.selectAll = selectAll;
for (Object o : valuesOnPage) {
checked.put(o, selectAll);
}
}
}
Look how and when the data is changing and when it is loaded. Check out that there's no unnessecary new action for checkbox of single row. JSF will take care of that with: value="#{bean.checked[data]}".
And once again: Your keys in map are objects. You have to make sure that equals method is good. In 95% of case the default is not, especially if they are #Entity. Check i.e. this topic.

datamodel must implement when selection is enabled.?

I wanted to remove rows from the data table when the checkbox is ticked and remove button is pressed..
This is the datatable snippet :
<p:dataTable id="cartTable" lazy="true" scrollable="true"
scrollHeight="115" selection="#{Cart_Check.selectedItems}"
value="#{Cart_Check.cart}" var="cart" rowKey="#{cart.sheetno}"
style="widht:100%;margin-top:10%;margin-left:1%;margin-right:30px ;box-shadow: 10px 10px 25px #888888;">
<f:facet name="header">
Checkbox Based Selection
</f:facet>
<p:column selectionMode="multiple" style="width:2%">
</p:column>
//Here the columns are metion
<f:facet name="footer">
<p:commandButton id="viewButton" value="Remove" />
</f:facet>
</p:dataTable>
This is the backing bean
public class checkcart {
private int items;
private ArrayList<User_Cart> cart;
private ArrayList<User_Cart> selectedItems;
public checkcart() {
getvalues();
}
//getter and setter
public void getvalues() {
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext()
.getSession(false);
System.out.println("Cart Request ::::" + session.getAttribute("regid"));
try {
Connection connection = BO_Connector.getConnection();
String sql = "Select * from cart_orderinfo where usrregno=?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, (String) session.getAttribute("regid"));
ResultSet rs = ps.executeQuery();
cart = new ArrayList<>();
while (rs.next()) {
User_Cart user_cart = new User_Cart();
user_cart.setSheetno(rs.getString("sheetno"));
user_cart.setState_cd(rs.getString("state_cd"));
user_cart.setDist_cd(rs.getString("dist_cd"));
user_cart.setLicensetype(rs.getString("license_type"));
user_cart.setFormat(rs.getString("sheet_format"));
user_cart.setQuantity(rs.getInt("quantity"));
cart.add(user_cart);
}
} catch (Exception ex) {
System.out.println(ex);
}
}
}
and when i run this page i get the following error
datamodel must implement org.primefaces.model.selectabledatamodel when selection is enabled.
But when i remove the checkbox then their is no error but it is without a checkbox.
What to do and how to resolve the following error ..Kindly help..
I want something like this :
http://www.primefaces.org/showcase/ui/datatableRowSelectionRadioCheckbox.jsf
You just need to define ListDataModel as shown below,
public class SD_User_Cart extends ListDataModel<User_Cart> implements SelectableDataModel<User_Cart> {
public SD_User_Cart() {
}
public SD_User_Cart(List<User_Cart> data) {
super(data);
}
#Override
public User_Cart getRowData(String rowKey) {
//In a real app, a more efficient way like a query by rowKey should be implemented to deal with huge data
List<User_Cart> rows = (List<User_Cart>) getWrappedData();
for (User_Cart row : rows) {
if (row.getCartId.toString().equals(rowKey)) {//CartId is the primary key of your User_Cart
return row;
}
}
return null;
}
#Override
public Object getRowKey(User_Cart row) {
return row.get.getCartId();
}
}
Change your "cart" object into SD_User_Cart as shown below,
private SD_User_Cart cart;
Then define selection in p:datatable, and add a column as shown below,
<p:column selectionMode="multiple" style="width:18px"/>
Hope this helps:)
You need to define a your private ArrayList<User_Cart> selectedItems; data member in back class public class checkcart like this private User_Cart[] selectedItems; and give setter and getter method for the same it will work.
I had also faced same problem.

#PostConstruct initialize is not getting invoked implicitly

Using -Primefaces 3.4 + JSF 2.0-
I am displaying some drop down values from database and the Postconstruct initialize method is not getting invoke implicitly.
Its working when I am calling the init method from other bean.
xhtml code:
<p:panelGrid style="width:50%" styleClass="panelgrid">
<p:row>
<p:column styleClass="columnA" style="width:10%">#{msgs.partTypeTitle}</p:column>
<p:column styleClass="columnB">
<h:selectOneMenu id="partTypeDpDnId" value="#{ppcrDetails.newPpcr.selectedPartType}" style="width:150px;font-size:13px;" >
<f:selectItems value="#{ppcrDetails.newPpcr.partsType}" />
</h:selectOneMenu>
</p:column>
</p:row>
<p:row>
<p:column styleClass="columnA" style="width:25%">#{msgs.familyTitle}</p:column>
<p:column styleClass="columnB">
<h:selectOneMenu id="familyDpDnId" value="#{ppcrDetails.newPpcr.selectedFamilyValues}" style="width:150px;font-size:13px;">
<f:selectItems value="#{ppcrDetails.newPpcr.familyValues}" />
</h:selectOneMenu>
</p:column>
</p:row>
</p:panelGrid>
-Bean:
#ManagedBean(name = "newPpcr" , eager = true)
#SessionScoped
public class NewPpcr implements Serializable {
#PostConstruct
public void initialize() throws QtException {
LOGGER.log(Level.DEBUG, "QuotationTool: NewPpcr initilize.");
partsType.clear();
List<MdPartsType> partList = partsTypeFacade.findAll();
int partSequence = 0;
for (MdPartsType part : partList) {
partsType.add(new SelectItem(partSequence++, part.getPartType()));
}
familyValues.clear();
List<MdFamily> familyList = familyFacade.findAll();
int familySequence = 0;
for (MdFamily family : familyList) {
familyValues.add(new SelectItem(familySequence++, family.getFamily()));
}
}
But this is not working, So I am calling initialize method from other bean then drop down is populating:
#ManagedBean(name = "ppcrDetails", eager = true)
#SessionScoped
public class PpcrDetails implements Serializable{
private List<SelectItem> partType = new ArrayList<SelectItem>();
private List<SelectItem> familyValues = new ArrayList<SelectItem>();
public List<SelectItem> getPartType() {
try {
partType.clear();
if (partType == null || partType.isEmpty()) {
newPpcr.initialize();
this.partType = newPpcr.getPartsType();
}
} catch (QtException e) {
LOGGER.error(e.getMessage(), e);
}
return partType;
}
public void setPartType(List<SelectItem> partType) {
this.partType = partType;
}
public List<SelectItem> getFamilyValues() {
try {
familyValues.clear();
if (familyValues == null || familyValues.isEmpty()) {
newPpcr.initialize();
this.familyValues = newPpcr.getFamilyValues();
}
} catch (QtException e) {
LOGGER.error(e.getMessage(), e);
}
return familyValues;
}
public void setFamilyValues(List<SelectItem> familyValues) {
this.familyValues = familyValues;
}
From this approach I am able to display the values but it is breaking the some functionality.

Primefaces InputText passing empty value to the backing bean

I am using JSF template with top, left and content views of a chat application. On the left is a list of discussions, displayed using composite components. When I select one discussion, every conversation in the selected discussion is required to the displayed in the content. There is a create button in the content pane which allows to create a new text within the selected discussion. On click of create, a dialog opens to input the message text.
The issue is, when I select a discussion on the left, and then click on the create in the content, the text message from the dialog is passing blank values to the backing bean. The setter method is getting called, but the value passed is blank. I observed that, if I click on create when the page is loaded, without selecting a discussion, it is sending the message with correct value. Every subsequent creates even after selecting a discussion continues to pass the same value.
I am using Primefaces 3.4.2 and glassfish 4.
Below is the center pane xhtml
<h:body>
<h:form id="newForm">
<p:commandLink id="test" value="Create Bubble" />
<p:overlayPanel id="panel" for="test" >
<p:commandButton id="map" icon="ui-icon-map" onclick="map_dlg.show();"/>
<p:commandButton id="map1" icon="ui-icon-document" onclick="survey_dlgcreate.show();"/>
<p:commandButton id="map2" icon="ui-icon-folder" onclick="txt_dlg.show();"/>
</p:overlayPanel>
<a:discussionComp discussion="#{displayDiscussionBean}"/>
</h:form>
<p:focus id="focus" context="textdlg"/>
<p:dialog id="textdlg" modal="true" header="Text bubble" appendToBody="true" hideEffect="fade" widgetVar="txt_dlg">
<h:form id="t3">
<p:outputLabel value="Enter your message"/><p:inputText value="#{displayDiscussionBean.txtMsg}"/>
<p:commandButton icon="Post" action="#{displayDiscussionBean.createTextBubble()}" oncomplete="txt_dlg.hide();"/>
</h:form>
</p:dialog>
</h:body>
Here is what my left panel is.
<!--IMPLEMENTATION-->
<cc:implementation>
<h:form id="leftPanel">
<p:dataTable id="disc" value="#{cc.attrs.discussionModel}" var="discussion" style="margin-top: 2px;height: 100%" selectionMode="single" selection="#{discussionBean.selectedDiscussion}" >
<p:ajax event="rowSelect" update=":detail_panel" />
<f:facet name="header">
Discussions
<h:commandLink action="#{discussionBean.createDiscussion()}">
<p:graphicImage id="add" url="/resources/images/plus.png" style="height: 25px;float: right" />
<p:tooltip for="add" value="Add Discussion" style="font-size: 12px" hideEffect="fade"/>
</h:commandLink>
</f:facet>
<p:column style="font-size: 12px;">
#{discussion.title}
</p:column>
</p:dataTable>
</h:form>
</cc:implementation>
My backing bean (displayDiscussionBean) for the create is a SessionScoped bean, and has get and set methods for the txtMsg. However on submit, set method gets fired, but with blank value. Below is the backing bean.
#Named
#SessionScoped
public class DisplayDiscussionBean implements Serializable {
private static final long serialVersionUID = 1L;
#EJB
private DiscussionEJB discussionEJB;
private TextEJB textEJB;
private DiscussionEntity de;
private HashMap<Integer, TextEntity> textMap;
private String selectedOption;
#Inject
private DiscussionBean discussionBean;
private String msg;
private Integer currentBubbleId;
private Integer currentBubbleType = 55;
#Inject
private Locations loc;
private String txtMsg;
private TreeNode root;
private Integer did;
public Integer getDid() {
return did;
}
public void setDid(Integer did) {
this.did = did;
setDetails();
}
public DisplayDiscussionBean() {
}
public DisplayDiscussionBean(Integer id) {
}
private void setDetails() {
de = discussionEJB.getDiscussionDetails(did);
textMap = new HashMap<>();
root = new DefaultTreeNode("Root", null);
Map<Integer, TreeNode> nodeMap = new HashMap<>();
for (BubbleEntity b : de.getBubbleList()) {
TreeNode node = new DefaultTreeNode(b, null);
nodeMap.put(b.getBubbleId(), node);
TextEntity te = (TextEntity) b;
textMap.put(te.getBubbleId(), te);
}
for (BubbleEntity b : de.getBubbleList()) {
if (b.getParentId() != null) {
TreeNode currNode = nodeMap.get(b.getBubbleId());
TreeNode parentNode = nodeMap.get(b.getParentId());
currNode.setParent(parentNode);
} else {
TreeNode currNode = nodeMap.get(b.getBubbleId());
currNode.setParent(root);
}
}
}
public void createTextBubble() {
if (did == null){
did=discussionBean.getSelectedDiscussion().getDiscussionId();
}
textEJB.createTextBubble(txtMsg, did, null);
}
public DiscussionEntity getDe() {
return de;
}
public void setDe(DiscussionEntity de) {
this.de = de;
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
public HashMap<Integer, TextEntity> getTextMap() {
return textMap;
}
public void setTextMap(HashMap<Integer, TextEntity> textMap) {
this.textMap = textMap;
}
public String getSelectedOption() {
return selectedOption;
}
public void setSelectedOption(String selectedOption) {
this.selectedOption = selectedOption;
}
public Integer getCurrentBubbleId() {
return currentBubbleId;
}
public void setCurrentBubbleId(Integer currentBubbleId) {
this.currentBubbleId = currentBubbleId;
}
public Integer getCurrentBubbleType() {
return currentBubbleType;
}
public void setCurrentBubbleType(Integer currentBubbleType) {
this.currentBubbleType = currentBubbleType;
}
public String getTxtMsg() {
return txtMsg;
}
public void setTxtMsg(String txtMsg) {
this.txtMsg = txtMsg;
System.out.println("set text msg is "+txtMsg);
}
}
Any suggestioins what am I doing wrong here?
Try using only one form instead. Remove the inner form. I too had a similar issue and removing inner form worked for me.
If that doesn't work try adding 'process' or 'execute' attribute to your button which calls your bean method

Unable to find matching navigation case with from-view-id '/index.xhtml' for action : JSF

I am getting the following error :
Unable to find matching navigation case with from-view-id '/index.xhtml' for action '#{medcontroller.getMedGeneric}' with outcome 'javax.faces.model.ListDataModel#7a652236'
I am new to jsf and I'm really clueless about solving this error. I have a ManagedBean with the following code:
MedController.java
#ManagedBean(name = "medcontroller")
#SessionScoped
public class MedController implements Serializable {
int startId;
String gName;
int endId;
DataModel medNames;
//DataModel medGeneric;
MedicineHelper helper;
private int recordCount = 1000;
private int pageSize = 10;
private Medicine current;
private int selectedItemIndex;
public MedController() {
helper = new MedicineHelper();
startId = 1;
endId = 10;
}
public MedController(int startId, int endId) {
helper = new MedicineHelper();
this.startId = startId;
this.endId = endId;
}
public Medicine getSelected() {
if (current == null) {
current = new Medicine();
selectedItemIndex = -1;
}
return current;
}
public DataModel getMedNames() {
if (medNames == null) {
medNames = new ListDataModel(helper.getMedNames(startId, endId));
}
return medNames;
}
public String getgName()
{
return gName;
}
public void setgName(String gName)
{
this.gName = gName;
}
public DataModel getMedGeneric() {
if (medNames == null) {
medNames= new ListDataModel(helper.getMedGeneric(gName));
}
return medNames;
}
void recreateModel() {
medNames = null;
}
public boolean isHasNextPage() {
if (endId + pageSize <= recordCount) {
return true;
}
return false;
}
public boolean isHasPreviousPage() {
if (startId-pageSize > 0) {
return true;
}
return false;
}
public String next() {
startId = endId+1;
endId = endId + pageSize;
recreateModel();
return "index";
}
public String previous() {
startId = startId - pageSize;
endId = endId - pageSize;
recreateModel();
return "index";
}
public int getPageSize() {
return pageSize;
}
public String prepareView(){
current = (Medicine) getMedNames().getRowData();
return "browse";
}
public String prepareList(){
recreateModel();
return "index";
}
}
And here is my JSF file
index.xhtml
<ui:define name="body">
<h:form styleClass="jsfcrud_list_form">
<h:commandLink action="#{medcontroller.previous}" value="Previous #{medcontroller.pageSize}" rendered="#{medcontroller.hasPreviousPage}"/>
<h:commandLink action="#{medcontroller.next}" value="Next #{medcontroller.pageSize}" rendered="#{medcontroller.hasNextPage}"/>
<h:dataTable value="#{medcontroller.medNames}" var="item" border="1" cellpadding="15" cellspacing="10" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px">
<h:column>
<f:facet name="header">
<h:outputText value="BrandName"/>
</f:facet>
<h:outputText value="#{item.brandName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Generic"/>
</f:facet>
<h:outputText value="#{item.generic}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
<h:commandLink action="#{medcontroller.prepareView}" value="View"/>
</h:column>
</h:dataTable>
<h:inputText value="#{medcontroller.gName}" />
<h:commandButton value="Submit" action="#{medcontroller.getMedGeneric}" />
</h:form>
</ui:define>
Please help me solve the error.
Also, I do not have a faces-config.xml file. I am using netbeans ide 7.1.2 web application with jsf and hibernate framework.
Thank you in advance.
The <h:commandButton action> must point to a method which invokes some business logic and returns either void or a String representing the target page you'd like to (re)display. However you returned a whole ListDataModel which isn't making any sense to JSF navigation handler and hence this error.
Something like this should do:
public String getMedGeneric(){
// Do your business logic here.
return "someViewId";
}
This will navigate to someViewId.xhtml. However, if you intend to stick on the same view, just let it return void (or null) and it will redisplay the same view.
public void getMedGeneric(){
// Do your business logic here.
}
By the way, it's really a poor naming convention to prefix action method names with get. This is confusing and makes your code not self-documenting. Rather name it loadMedGeneric() or so. I'm merely guessing as you didn't tell anywhere about the concrete functional requirement, what exactly that button should be doing.
getMedGeneric should return java.lang.String which represent navigation to another page described in faces-config.xml. In your case it return some model so it will not work unfortunatell. Let try to put getMedGeneric() action to actionListener and then in action put navigation String. i.e:
action="navString" actionListener="#{medcontroller.getMedGeneric}"
you should try just
actionListener="#{medcontroller.getMedGeneric}"

Resources