Question

The problem is in my content part of the template. ValueChangeEvent of content pages cannot fire anymore when i set them in tag. I cannot get the value of selected item in SelectOneMenu even though i am using omnifaces converter because could not reach the CityChaged event.This problem doesn't occur when i tried without using template and also can get value to persist. Please give me some advice, i got similar errors by using template.Thanks.

This is my template page.

<?xml version='1.0' encoding='windows-1252'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">

<f:view contentType="text/html" id="fview">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <f:metadata>
    <ui:insert name="metadata" />
    </f:metadata>

    <h:head>
          <ui:insert name="head"/>
          <h:outputStylesheet name="css/default.css"/>
    </h:head>

    <h:body>
    <p:ajaxStatus onstart="statusDialog.show();" onsuccess="statusDialog.hide();"  />

        <p:layout fullPage="true" id = "layout1">  
        <p:ajax event="toggle" listener="#{layoutBean.handleToggle}"/>  
        <p:ajax event="close" listener="#{layoutBean.handleClose}" />  

        <p:layoutUnit id= "contentLayout1" position="north" size="100" resizable="false">  
            <ui:include src="/WEB-INF/templates/header.xhtml"/>
        </p:layoutUnit>  

        <p:layoutUnit id= "contentLayout3" position="west" size="300" resizable="true" 
            header="Main Menu" style="height:580px;overflow:hidden;">  
            <ui:include src="/WEB-INF/templates/menu.xhtml"/>
        </p:layoutUnit>  

         <p:layoutUnit id= "contentLayout4" position="center">  
            <ui:insert name="content"/>
         </p:layoutUnit> 

        <p:layoutUnit  id= "contentLayout2" position="south" resizable="true">  
            <ui:include src="/WEB-INF/templates/footer.xhtml"/>
        </p:layoutUnit>  

    </p:layout>

    </h:body>
</f:view>
</html>

This is my content page.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
      template="/WEB-INF/templates/BasicTemplate.xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">


<ui:define name="content">
    <h:form>
        <p:panel header = "Delivery Charges Entry" style="width:930px;">
            <h:panelGrid columns = "4" width="500" border="0">

                <h:outputText value="City ID"/>
                <p:selectOneMenu id= "cboCity" converter="omnifaces.SelectItemsIndexConverter"
                    value = "#{ManageDeliveryCharges.selectedCity}" required = "true"
                    panelStyle="width:150px" effect = "fade" style = "width:187px" var = "pg" >

                    <p:ajax event = "valueChange" listener ="#{ManageDeliveryCharges.CityChanged}"/>
                    <f:selectItem itemValue="#{null}" itemLabel="Select-One" noSelectionOption="true" />
                    <f:selectItems value = "#{ManageDeliveryCharges.citySelectedItems}" var = "city"/>

                    <p:column>
                        #{pg.cityID}
                    </p:column>   

                    <p:column>
                        #{pg.cityName}
                    </p:column>

                </p:selectOneMenu> 
                <p:message for="cboCity"/>

            </h:panelGrid>  

        </p:panel>
    <h:form>

</ui:define>
</ui:composition>       

This is my backing bean.

@ManagedBean(name = "ManageDeliveryCharges")
@RequestScoped
public class ManageDeliveryCharges{

    private City city;
    private List<SelectItem> citySelectedItems = null;
    private City selectedCity;
    private List<City> cityList;

    @ManagedProperty("#{TownshipService}")
    private ITownshipService townshipService;


    @PostConstruct
    public void Page_Load(){
        prepareForAdd();

        cityList = cityService.findAllCity();
        citySelectedItems =new ArrayList<SelectItem>();

        for(City city:cityList){
            SelectItem item =new SelectItem(city,city.getCityName());
            citySelectedItems.add(item);
        }
    }


    public void CityChanged(ValueChangeEvent ex){
        System.out.println("City ID is " + selectedCity.getCityID() + "City Name is " + selectedCity.getCityName());
        deliveryCharges.setCity((City)((UIOutput) ex.getSource()).getValue());


    }   

    public List<SelectItem> getCitySelectedItems() {
        return citySelectedItems;
    }

    public void setCitySelectedItems(List<SelectItem> citySelectedItems) {
        this.citySelectedItems = citySelectedItems;
    }

    public List<City> getCityList() {
        return cityList;
    }

    public void setCityList(List<City> cityList) {
        this.cityList = cityList;
    }

    public void setCityService(ICityService cityService) {
        this.cityService = cityService;
    }

    public IDeliveryChargesService getDeliveryChargesService() {
        return deliveryChargesService;
    }

    public City getCity() {
        return city;
    }

    public void setCity(City city) {
        this.city = city;
    }


}

Update1. CityChanged method is actually like this.

public void CityChanged(AjaxBehaviorEvent ex){
        System.out.println("City ID is " + selectedCity.getCityID() +     "City Name is " + selectedCity.getCityName());
        deliveryCharges.setCity((City)((UIOutput)    ex.getSource()).getValue());
Was it helpful?

Solution

You must use the events which is provided by p:commandButton component. For more details primefaces-p Tag selectOneMenu

p:commandButton having only one event i.e is onchange. Replace with below line.

<p:ajax event = "onchange" listener ="#{ManageDeliveryCharges.CityChanged}"/>

For example p:inputText supports events like onblur, onchange, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup, onselect use these events in p:ajax component of event attribute.

The event names start with on then click on ctrl + space displays supported events.

OTHER TIPS

Your question is not entirely well-written or clear, but 3 things don't look right:

  1. Your use of <p:ajax/> and the ValueChangeEvent in your listener are not correct. The ValueChangeEvent is provided to be used as part of a properly defined valueChangeListener on the component. So what you really should have is:

    p:selectOneMenu id="cboCity" valueChangeListener="#{ManageDeliveryCharges.CityChanged}" converter="omnifaces.SelectItemsIndexConverter"
                value="#{ManageDeliveryCharges.selectedCity}" required="true"
                panelStyle="width:150px" effect ="fade" style="width:187px" var="pg"/> 
    

    With the valueChangeListener defined above, you can use the listener as defined in your backing bean. Which leads to...

  2. A valueChangeListener is fired only when the entire form is submitted i.e. not an ajax request. So again, the <p:ajax/> is not appropriate where you have it. You should have instead:

    <p:selectOneMenu id= "cboCity" onchange="submit();"/>
    

    onchange here will trigger a submit of the entire form

  3. <p:ajax/> doesn't have a valueChange event, only change

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top