开发者

Display values in drill-down SelectOneMenus (Parent-Child)

开发者 https://www.devze.com 2023-04-11 19:32 出处:网络
I have irritating problem when I populate a drill-down selection of two selectOneMenu. The first menu is Sector which controls the other one Categorty. I load the selection for the Category depending

I have irritating problem when I populate a drill-down selection of two selectOneMenu. The first menu is Sector which controls the other one Categorty. I load the selection for the Category depending on Sector and all of this is wor开发者_StackOverflowking fine.

But when I edit a business object that has a Category (has one) Sector attached to it. The Category doesn't get display when first loading the edit.xhtml page. I know the value is correct in the SessionScoped backing bean. If I select another Sector-Category and then go back to the initial Sector, the Category get properly set at it was persisted in the first place.

The POJO classes (Sector-Category) has the hashCode() and equals(Object object) functions.

I have CRUD generated JSF converters for the POJO object, but I don't think this is causing the problem. I think the second selectOneMenu don't display its value as it should for some reason. If I flip the parent (Sector) to something else and the back to the initial state, the correct value from the manged bean get displayed.

Ho can I make the Category selectOneMenu component display the value in the managed bean?

Greetings Chris

Faces Error Message

FacesMessage(s) have been enqueued, but may not have been displayed.
sourceId=null[severity=(ERROR 2), summary=(No activity selected), detail=(No activity selected)]

Edit.xhtml

... 
<h:outputLabel value="Sector:" />                    
<h:selectOneMenu id="sectorSelector" value="#{activityController.selectedSector}" title="#{bundle.CreateSectorLabel_sectorName}" required="false" requiredMessage="#{bundle.CreateSectorRequiredMessage_sectorName}"
        valueChangeListener="#{activityController.changeSectorMenu}"
            disabled="#{activityController.activityStatusOngoing or activityController.activityStatusComplete}">
    <f:ajax event="change" execute="@this" render="categoryMenu"/>
            <f:selectItems value="#{sectorController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>

<h:outputLabel value="Category:" />
    <h:selectOneMenu id="categoryMenu" value="#{activityController.selectedCategory}" title="#{bundle.CreateSectorLabel_sectorName}" 
        required="true" requiredMessage="#{bundle.CreateCategoryRequiredMessage_sector}"
            disabled="#{activityController.activityStatusOngoing}" rendered="true"> 
    <f:selectItems value="#{activityController.categorySelection}"/>
    </h:selectOneMenu>
...

Controller bean for Category

@ManagedBean(name = "categoryController")
@SessionScoped
public class CategoryController implements Serializable{

    ....

    @FacesConverter(forClass = Category.class)
    public static class CategoryControllerConverter implements Converter {

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            CategoryController controller = (CategoryController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "categoryController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Category) {
                Category o = (Category) object;
                return getStringKey(o.getIdCategory());
            }
            else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + CategoryController.class.getName());
            }
        }
    }

Part of POJO object

...
public class Category implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "idCategory")
    private Integer idCategory;
    ...


Option (not so difficult as I recently made a switch) is to include Seam Faces and Persistence modules. Seam Faces module enables ViewScope without @ManagedBean annotation.

But SeamFaces forces us (which is justified) to use CDI annotations (@Named instead of @ManagedBean etc).

Please refer this post. (You can use @EJB and also Inject any bean annotated with @Named)


It was not the Converters as I first thought. It was the rendering of the two selectOneMenu. This is the changes I did to the xhml file. Thank you for your time and effort, greetings Chris.

Edit.xhml

<h:outputLabel value="Sector:" />                    
<h:selectOneMenu id="sectorSelector" value="#{activityController.selectedSector}" title="#{bundle.CreateSectorLabel_sectorName}" required="false" requiredMessage="#{bundle.CreateSectorRequiredMessage_sectorName}"
        valueChangeListener="#{activityController.changeSectorMenu}" immediate="true"
            disabled="#{activityController.activityStatusOngoing or activityController.activityStatusComplete}">
    <a4j:ajax event="change" execute="@this categoryMenu" render="categoryMenu"/>
            <f:selectItems value="#{sectorController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>

<h:outputLabel value="Category:" />
    <h:selectOneMenu id="categoryMenu" value="#{activityController.selectedCategory}" title="#{bundle.CreateSectorLabel_sectorName}" 
        binding="#{activityController.categoryMenu}"
            required="true" requiredMessage="#{bundle.CreateCategoryRequiredMessage_sector}"                                     
            disabled="#{activityController.activityStatusOngoing}">
            <f:selectItems value="#{activityController.categorySelection}"/>
</h:selectOneMenu>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号