Search code examples
javaicefaces

IceFaces duplicate entries in combos, menus after layout change


My IceFaces 1.8 based application starts with a very simple xhtml that includes a different one based on a bean's property. This property is bound to a combo's item that is included in every page. If the user selects a layout from this combo, the page updates to the new layout.

It is all ok, except that after every single page layout change, the items in the layout selector combo get duplicated, triplicated and so on.

This is the "multiplexer" xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ice="http://www.icesoft.com/icefaces/component">

    <ui:include src="#{system.layout}">
    </ui:include>

</html>

And this is the layout selector that is included into every layout xhtml:

  <ice:form id="layoutSelectForm">
        <ice:outputLabel for="layoutSelector">#{msgs['LayoutSelect.Label']}: </ice:outputLabel>
        <ice:selectOneMenu id="layoutSelector" binding="#{layoutSelect.som}" value="#{layoutSelect.selectedLayout}" 
            valueChangeListener="#{layoutSelect.processValueChange}" partialSubmit="true">
            <f:selectItems value="#{layoutSelect.allLayouts}" />
        </ice:selectOneMenu >
  </ice:form>

Here is the code of the LayoutSelect backing bean:

public class JSFLayoutSelect implements InitializingBean, ValueChangeListener {
    private EventManager eventManager;
    private String mainApplFrmURL;
    private HtmlSelectOneMenu som;
    public List<SelectItem> allLayouts;
    private String selectedLayout;

        @Override
    public void processValueChange(ValueChangeEvent event)
            throws AbortProcessingException {
        eventManager.publish("layout-select/change", event.getNewValue());
        logger.info("Layout changed event occured: " + event.getNewValue());

        try {
            FacesContext.getCurrentInstance().getExternalContext().redirect(mainApplFrmURL);
        } catch (IOException e) {
            logger.error(e.getMessage());
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        allLayouts = new ArrayList<SelectItem>();
        allLayouts.add(new SelectItem("dev", "Core Dev"));
        allLayouts.add(new SelectItem("classic", "Core Classic"));
        allLayouts.add(new SelectItem("modern", "Core Modern"));
        selectedLayout = "dev";
    }

    public List<SelectItem> getAllLayouts() {
        return allLayouts;
    }

    public String getSelectedLayout() {
        return selectedLayout;
    }

        /* some unimportant methods are not here */
}

  <bean name="layoutSelect" class="hu.hgap.comp.impl.JSFLayoutSelect" scope="session">
    <property name="eventManager" ref="SessionEventManager"/>
     <property name="mainApplFrmURL" value="/ICEFacesSpringDemoV2/secured/ApplFrm.faces" />
  </bean>

Can you tell me what shall I do to avoid duplicating combo entries? I see that after changing the layout the very same combo gets rendered again and the combo items are pushed into it again from the server.


Solution

  • What does your backing bean look like? Which scope does it have?

    I had similar experience with binding variables in a session scope bean. When I moved the variable to a request scopre bean the problem disappeared.