Updating JSF data based on selectOneMenu values

I am trying to create a JSF page where the user selects values ​​in two selectOneMenu components. The values ​​in these selections will then be passed to an SQL query to update the table displayed on the page.

I have bound each select item to a corresponding variable in the backup bean, but after changing the value selected in selectOneMenu, the associated property in the bean database does not change and the query returns no results. (As aside, getters are also rendered twice when the page is initially rendered).

I cannot use any other third party components (such as RichFaces, etc.) for this implementation.

Any understanding of this is appreciated!

Here is the code:

notes.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title></title>
 </head>
<body>

<f:view>

<h:form id="notelistform">
    <f:subview id="loginbar">
        <jsp:include page="/jsp/loginbar.jsp" />
    </f:subview>

    <h:outputText value="Worktype:" />
    <h:selectOneMenu value="#{pc_noteListBacker.worktype}"
        title="worktype" id="worktypeList" onchange="submit()">
        <f:selectItems value="#{pc_noteListBacker.selectWorktypes}" />
        <f:valueChangeListener
            type="<package>.web.backer.note.NoteListBacker" />

    </h:selectOneMenu>

    <h:outputText value="Product:" />
    <h:selectOneMenu value="#{pc_noteListBacker.product}" title="product"
        id="productList" onchange="submit()">
        <f:selectItems value="#{pc_noteListBacker.selectProducts}" />
        <f:valueChangeListener
            type="<package>.web.backer.note.NoteListBacker" />
    </h:selectOneMenu>


    <h:dataTable id="notelisttable" value="#{pc_noteListBacker.noteList}"
        var="item" bgcolor="#F1F1F1" border="10" cellpadding="5"
        cellspacing="3" first="0" width="80%" dir="LTR" frame="hsides"
        rules="all" summary="Status and notes note table display."
        binding="#{pc_noteListBacker.noteListTable}">


        <h:column>
            <f:facet name="header">
                <h:outputText value="Note ID" />
            </f:facet>
            <h:outputText value="#{item.noteId}"></h:outputText>
        </h:column>


        <h:column>
            <f:facet name="header">
                <h:outputText value="Note Category" />
            </f:facet>
            <h:outputText value="#{item.noteCategory}"></h:outputText>
            <f:facet name="footer">
                <h:commandButton value="Add" action="#{pc_noteListBacker.insert}">
                </h:commandButton>
            </f:facet>
        </h:column>

        <h:column>
            <f:facet name="header">
                <h:outputText value="Note Subcategory" />
            </f:facet>
            <h:outputText value="#{item.noteSubCategory}"></h:outputText>
        </h:column>


        <h:column>
            <f:facet name="header">
                <h:outputText value="Note" />
            </f:facet>
            <h:outputText value="#{item.note}"></h:outputText>
        </h:column>



        <h:column>
            <h:commandButton value="Edit" action="#{pc_noteListBacker.edit}">
            </h:commandButton>
        </h:column>
        <h:column>
            <h:commandButton value="Delete" action="#{pc_noteListBacker.delete}"></h:commandButton>
        </h:column>
    </h:dataTable>

</h:form>

      

NoteListBacker.java

 package <package>.web.backer.note;

 import java.util.List;
 import java.util.ArrayList;

 import javax.faces.component.UIComponent;
 import javax.faces.component.UIComponentBase;
 import javax.faces.component.UIData;
 import javax.faces.context.FacesContext;
 import javax.faces.event.AbortProcessingException;
 import javax.faces.event.ValueChangeEvent;
 import javax.faces.event.ValueChangeListener;
 import javax.faces.model.ListDataModel;
 import javax.faces.model.SelectItem;
 import javax.swing.JOptionPane;


 public class NoteListBacker implements ValueChangeListener {

private UIData noteListTable;

private Note note;

private NoteCategory noteCategory;

private NoteSubCategory noteSubCategory;

private NoteDao nDao;

private SybaseSqlDao sybaseDao;

private List<Note> noteList;

private List<SelectItem> selectWorktypes;

private List<SelectItem> selectProducts;

private String worktype;

private List<String> worktypeList;

private String product;

private List<Product> productList;

private int noteId;

public NoteListBacker() {

    nDao = new NoteDao();
    sybaseDao = new SybaseSqlDao();
    selectWorktypes = new ArrayList<SelectItem>();
    selectProducts = new ArrayList<SelectItem>();
    noteList = new ArrayList<Note>();
    note = new Note();
    worktypeList = new ArrayList<String>();
    productList = new ArrayList<Product>();
}

public String insert() {
    return "success";
}

public String save() {
    return "notes";
}

public String edit() {
    return "success";
}

public String update() {
    return "notes";
}

public String delete() {
    Note delNote = (Note) noteListTable.getRowData();
    nDao.deleteNote(delNote);
    return "notes";
}

public String cancel() {
    return "notes";
}

public Note getNote() {
    return note;
}

public void setNote(Note note) {
    this.note = note;
}

public NoteDao getNDao() {
    return nDao;
}

public UIData getNoteListTable() {
    return noteListTable;
}

public void setNoteListTable(UIData noteListTable) {
    this.noteListTable = noteListTable;
}

public List<Note> getNoteList() {


    noteList = nDao.selectNotes(worktype, product); //
    return noteList;
}

public void setNoteList(List<Note> noteList) {
    this.noteList = noteList;
}

public void setNDao(NoteDao dao) {
    nDao = dao;
}

public String getProduct() {
    return product;
}

public void setProduct(String product) {
    this.product = product;
}

public String getWorktype() {
    return worktype;
}

public void setWorktype(String worktype) {
    this.worktype = worktype;
}

public NoteCategory getNoteCategory() {
    return noteCategory;
}

public void setNoteCategory(NoteCategory noteCategory) {
    this.noteCategory = noteCategory;
}

public NoteSubCategory getNoteSubCategory() {
    return noteSubCategory;
}

public void setNoteSubCategory(NoteSubCategory noteSubCategory) {
    this.noteSubCategory = noteSubCategory;
}

public int getNoteId() {
    return noteId;
}

public void setNoteId(int noteId) {
    this.noteId = noteId;
}

public SybaseSqlDao getSybaseDao() {
    return sybaseDao;
}

public void setSybaseDao(SybaseSqlDao sybaseDao) {
    this.sybaseDao = sybaseDao;
}

public List<SelectItem> getSelectWorktypes() {
    selectWorktypes.clear();

    worktypeList = this.getWorktypeList();

    for (String strt : worktypeList) {

        SelectItem si = new SelectItem();
        si.setValue(strt);
        si.setLabel(strt);
        si.setDescription(strt);
        selectWorktypes.add(si);
    }

    return selectWorktypes;
}

public void setSelectWorktypes(List<SelectItem> selectWorktypes) {

    this.selectWorktypes = selectWorktypes;
}

public List<String> getWorktypeList() {

    worktypeList = sybaseDao.selectWorktypes();
    return worktypeList;
}

public void setWorktypeList(List<String> worktypeList) {
    this.worktypeList = worktypeList;
}

public List<Product> getProductList() {

    productList = sybaseDao.selectProducts();
    return productList;
}

public void setProductList(List<Product> productList) {
    this.productList = productList;
}

public List<SelectItem> getSelectProducts() {
    selectProducts.clear();

    productList = this.getProductList();

    for (Product prod : productList) {

        SelectItem si = new SelectItem();
        si.setValue(prod);
        si.setLabel(prod.toString());
        si.setDescription(prod.toString());
        selectProducts.add(si);
    }

    return selectProducts;
}

public void setSelectProducts(List<SelectItem> selectProducts) {
    this.selectProducts = selectProducts;
}

public void processValueChange(ValueChangeEvent arg0) {

    if (arg0.getComponent().getId().equalsIgnoreCase("productList")) {
        this.setProduct(arg0.getNewValue().toString());

    }
    if (arg0.getComponent().getId().equalsIgnoreCase("worktypeList")) {
        this.setWorktype(arg0.getNewValue().toString());
    }

}

 }

      

person-config.xml

 <?xml version="1.0"?>

 <!DOCTYPE faces-config PUBLIC
   "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
   "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">

 <faces-config>

<lifecycle>
    <phase-listener>
        <package>.utils.NoCachePhaseListener
    </phase-listener>
</lifecycle>

<managed-bean>
    <managed-bean-name>pc_userBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.UserBacker
    </managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>pc_noteCategoryListBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.note.NoteCategoryListBacker
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>
        pc_noteSubCategoryListBacker
    </managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.note.NoteSubCategoryListBacker
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>pc_noteListBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.note.NoteListBacker
    </managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>pc_statusListBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.status.StatusListBacker
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>pc_statusReasonBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.status.StatusReasonBacker
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>


<!-- Notes -->
<navigation-rule>
    <from-view-id>/jsp/notes/notes.jsp</from-view-id>
    <navigation-case>
        <from-action>#{pc_noteListBacker.edit}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/noteedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>#{pc_noteListBacker.insert}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notenew.jsp</to-view-id>
    </navigation-case>


</navigation-rule>


<!-- Note Categories -->
<navigation-rule>
    <from-view-id>/jsp/notes/notecategories.jsp</from-view-id>
    <navigation-case>
        <from-action>#{pc_noteCategoryListBacker.edit}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notecategoryedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>
            #{pc_noteCategoryListBacker.insert}
        </from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notecategorynew.jsp</to-view-id>
    </navigation-case>


</navigation-rule>

<!-- Note Subcategories -->
<navigation-rule>
    <from-view-id>/jsp/notes/notesubcategories.jsp</from-view-id>
    <navigation-case>
        <from-action>
            #{pc_noteSubCategoryListBacker.edit}
        </from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notesubcategoryedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>
            #{pc_noteSubCategoryListBacker.insert}
        </from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notesubcategorynew.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

<!-- Statuses -->
<navigation-rule>
    <from-view-id>/jsp/statuses/statuses.jsp</from-view-id>
    <navigation-case>
        <from-action>#{pc_statusListBacker.edit}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/statuses/statusedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>#{pc_statusListBacker.insert}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/statuses/statusnew.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

<!-- Status Reasons -->
<navigation-rule>
    <from-view-id>/jsp/statuses/statusreasons.jsp</from-view-id>
    <navigation-case>
        <from-action>#{pc_statusReasonBacker.edit}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/statuses/statusreasonedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>#{pc_statusReasonBacker.insert}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/statuses/statusreasonnew.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

<!-- static and general actions-->
<!-- what page the action is coming from doesn't matter here -->
<navigation-rule>

    <navigation-case>
        <from-outcome>login</from-outcome>
        <to-view-id>/login.jsp</to-view-id>
    </navigation-case>

    <navigation-case>
        <from-outcome>menu</from-outcome>
        <to-view-id>/menu.jsp</to-view-id>
    </navigation-case>

    <!-- Notes -->
    <navigation-case>
        <from-outcome>notes</from-outcome>
        <to-view-id>/jsp/notes/notes.jsp</to-view-id>
    </navigation-case>


    <!-- Note Categories -->
    <navigation-case>
        <from-outcome>notecategories</from-outcome>
        <to-view-id>/jsp/notes/notecategories.jsp</to-view-id>
    </navigation-case>

    <!-- Note Subcategories -->
    <navigation-case>
        <from-outcome>notesubcategories</from-outcome>
        <to-view-id>/jsp/notes/notesubcategories.jsp</to-view-id>
    </navigation-case>

    <!-- Statuses -->
    <navigation-case>
        <from-outcome>statuses</from-outcome>
        <to-view-id>/jsp/statuses/statuses.jsp</to-view-id>
    </navigation-case>



    <!-- Status Reasons -->
    <navigation-case>
        <from-outcome>statusreasons</from-outcome>
        <to-view-id>/jsp/statuses/statusreasons.jsp</to-view-id>
    </navigation-case>


</navigation-rule>
 </faces-config>

      

+2


source to share


2 answers


I just looked at the code, but I'm guessing part of the problem is probably here:

public void processValueChange(ValueChangeEvent arg0) {
        if (arg0.getComponent().getId().equalsIgnoreCase("productList")) {
                this.setProduct(arg0.getNewValue().toString());

        }
        if (arg0.getComponent().getId().equalsIgnoreCase("worktypeList")) {
                this.setWorktype(arg0.getNewValue().toString());
        }
}

      

If you read the doc for valueChangeListener type

it says this:

Fully qualified name of the Java class of the creator and registered ValueChangeListener.



This means that you will have at least three instances <package>.web.backer.note.NoteListBacker

- two created as listeners and the third as a managed bean. The last one is the only one the table is bound to, and any state changes in the listeners are irrelevant.

To fix it:

  • Has no NoteListBacker

    implementation ValueChangeListener

    ; it makes no sense.
  • Either bind the selectOneMenu attribute ValueChangeListener

    to a method #{pc_noteListBacker.valueChange}

    (see the doc for details) OR have a separate implementation ValueChangeListener

    that views pc_noteListBacker

    directly from session using FacesContext

    .
+1


source


I ran into this quite often until I found out what the problem was. When the page is submitted, the JSF will go through the UPDATE_MODEL phase AFTER your call to processValueChange (). This way, changing your BackingBean will be overwritten with the values ​​in the HTTP request and have no effect.

To prevent this from happening, you will have to manually open the navigation box in your ValueChangeListener. You do this by inserting the following line at the end of processValueChange ().

FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(
                FacesContext.getCurrentInstance(), null, "stay_here");

      

"stay_here" refers to the navigation file in your faces-config.xml



<!-- Notes -->
<navigation-rule>
        <from-view-id>/jsp/notes/notes.jsp</from-view-id>
        <navigation-case>
                <from-action>#{pc_noteListBacker.edit}</from-action>
                <from-outcome>success</from-outcome>
                <to-view-id>/jsp/notes/noteedit.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
                <from-action>#{pc_noteListBacker.insert}</from-action>
                <from-outcome>success</from-outcome>
                <to-view-id>/jsp/notes/notenew.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
                <from-outcome>stay_here</from-outcome>
                <to-view-id>/jsp/notes/notes.jsp</to-view-id>
        </navigation-case>

</navigation-rule>

      

Hope it helps.

Hello

+1


source







All Articles