Board index JavaServer Faces General Problem with spinner

Problem with spinner

Components, Ajax Framework, Utilities and More.

Post 08 Apr 2011, 13:19

Posts: 51
Location: Brazil

Hello, I'm using a spinner to set the taxes at the products using a dialog.
The problem is, when I change the value of the spinner it puts the value instantly and if I click in cancel the values are been changed

see the code below:

           <p:dialog widgetVar="findServ"
                          id="findServ"
                          modal="true"
                          height="450"
                          width="800"
                          closable="false"
                          draggable="false"
                          resizable="false"
                          header="Serviços"
                          closeOnEscape="false">
                    <h:form id="formServ">
                        <p:panel>
                            <h:panelGrid columns="2">
                                <h:outputLabel>
                                    Cód:
                                    <h:inputText style="width: 100px;"
                                                 readonly="true"
                                                 value="#{contratoMB.servicoDoContrato.servico.codigo_produto}"
                                                 /> &nbsp;
                                    Nome:
                                    <h:inputText style="width: 350px;"
                                                 readonly="true"
                                                 value="#{contratoMB.servicoDoContrato.servico.nome}"
                                                 />
                                </h:outputLabel>
                                <p:commandButton image="ui-icon-search"
                                                 process="@this"
                                                 onclick="dialogServ.show();"/>
                            </h:panelGrid>
                            <h:panelGrid columns="2">
                                <p:panel style="height: 180px;">
                                    <h:panelGrid columns="2" width="200">

                                        <h:outputLabel value="Unidade: "/>
                                        <h:inputText readonly="true"
                                                     value="Un"
                                                     style="width: 100px;"/>

                                        <h:outputLabel value="Quantidade: "/>
                                        <p:spinner stepFactor="1"
                                                   min="0"
                                                   required="true"
                                                   requiredMessage="Campo [Quantidade] obrigatório"
                                                   value="#{contratoMB.servicoDoContrato.qtde}"
                                                   style="width: 100px;"
                                                   id="quantidade">

                                            <p:ajax event="change"
                                                    process="quantidade"
                                                    listener="#{contratoMB.calculaPreco}"
                                                    update="total_serv"/>
                                        </p:spinner>

                                        <h:outputLabel value="Preço: "/>
                                        <p:spinner min="0.00"
                                                   id="preco"
                                                   stepFactor="0.01"
                                                   value="#{contratoMB.servicoDoContrato.preco_unit}"
                                                   style="width: 100px;">
                                            <p:ajax event="change"
                                                    process="preco"
                                                    listener="#{contratoMB.calculaPreco}"
                                                    update="total_serv" />
                                        </p:spinner>

                                        <h:outputLabel value="Total: "/>
                                        <h:inputText style="width: 100px;"
                                                     id="total_serv"
                                                     readonly="true"
                                                     value="#{contratoMB.servicoDoContrato.preco_totalserv}">
                                            <f:convertNumber type="currency" currencySymbol=""/>
                                        </h:inputText>

                                    </h:panelGrid>
                                </p:panel>
                                <p:panel>
                                    <h:panelGrid columns="2" style="width: 455px;">
                                        <h:outputLabel value="Finalidade: "/>
                                        <h:selectOneMenu value="#{contratoMB.finalidade}"
                                                         converter="converteTAuxMovProdServ">
                                            <f:selectItems value="#{contratoMB.finalidades}"
                                                           var="fin"
                                                           itemLabel="#{fin.finalidade}"
                                                           itemValue="#{fin}"/>
                                        </h:selectOneMenu>
                                        <h:outputLabel value="Periodicidade: "/>
                                        <h:selectOneMenu>
                                            <f:selectItem itemValue="Mensal" itemLabel="Mensal"/>
                                            <f:selectItem itemValue="Bimestral" itemLabel="Bimestral"/>
                                            <f:selectItem itemValue="Trimestral" itemLabel="Trimestral"/>
                                            <f:selectItem itemValue="Semestral" itemLabel="Semestral"/>
                                            <f:selectItem itemValue="Anual" itemLabel="Anual"/>
                                        </h:selectOneMenu>

                                        <h:outputLabel value="Próximo Pgto: "/>
                                        <h:outputLabel >
                                            <h:selectOneMenu>
                                                <f:selectItem itemValue="1" itemLabel="Janeiro"/>
                                                <f:selectItem itemValue="2" itemLabel="Fevereiro"/>
                                                <f:selectItem itemValue="3" itemLabel="Março"/>
                                                <f:selectItem itemValue="4" itemLabel="Abril"/>
                                                <f:selectItem itemValue="5" itemLabel="Maio"/>
                                                <f:selectItem itemValue="6" itemLabel="Junho"/>
                                                <f:selectItem itemValue="7" itemLabel="Julho"/>
                                                <f:selectItem itemValue="8" itemLabel="Agosto"/>
                                                <f:selectItem itemValue="9" itemLabel="Setembro"/>
                                                <f:selectItem itemValue="10" itemLabel="Outubro"/>
                                                <f:selectItem itemValue="11" itemLabel="Novembro"/>
                                                <f:selectItem itemValue="12" itemLabel="Dezembro"/>
                                            </h:selectOneMenu>
                                            de
                                            <p:spinner stepFactor="1"
                                                       value="#{contratoMB.prox_pgto_ano}"
                                                       min="2011"
                                                       style="width: 55px;"
                                                       max="2100"/>
                                        </h:outputLabel>

                                        <h:outputLabel value="Prazo para reajuste: "/>
                                        <h:outputLabel>
                                            <p:spinner min="0"
                                                       value="#{contratoMB.servicoDoContrato.prazo_reajuste}"
                                                       style="width: 80px;"
                                                       stepFactor="3"/>
                                            (meses)
                                        </h:outputLabel>

                                        <h:outputLabel value="Início Vigência: "/>
                                        <p:inputMask mask="99/99/9999" style="width: 80px;"
                                                     required="true"
                                                     requiredMessage="Campo [Início Vigência] obrigatório"
                                                     value="#{contratoMB.inicioVigencia}">

                                        </p:inputMask>

                                        <h:outputLabel value="Término Vigência: "/>
                                        <p:inputMask mask="99/99/9999" style="width: 80px;"
                                                     required="true"
                                                     requiredMessage="Campo [Término Vigência] obrigatório"
                                                     value="#{contratoMB.fimVigencia}">

                                        </p:inputMask>

                                    </h:panelGrid>
                                </p:panel>
                            </h:panelGrid>
                            <h:panelGrid columns="1">
                                <p:panel>
                                    <h:panelGrid columns="2">

                                        <h:outputLabel value="Observação: "/>
                                        <h:inputTextarea cols="117"
                                                         value="#{contratoMB.servicoDoContrato.obs}"
                                                         rows="5"/>

                                    </h:panelGrid>
                                </p:panel>
                            </h:panelGrid>
                        </p:panel>
                        <br/>
                        <p:commandButton image="ui-icon-plus" value="Adicionar"
                                         disabled="#{empty contratoMB.servicoDoContrato.servico}"
                                         action="#{contratoMB.adicionaServico}"
                                         update="pesquisa:listaServicosContrato"
                                         oncomplete="fechaAddServico(xhr, status, args);"/>
                        <p:commandButton image="ui-icon-cancel"
                                         value="Cancelar"
                                         process="@this"
                                         onclick="findServ.hide();"/>
                    </h:form>
                </p:dialog>


You could say: "oh it's because you put an ajax function" but I put it in others forms without ajax and it happened to

Post 11 Apr 2011, 19:50

Posts: 51
Location: Brazil

help .......... :? :cry:

Post 11 Apr 2011, 20:32

Posts: 316
Location: Brazil
it should be fixed, what version of primefaces are you using?
Att,

--

Rafael Mauricio Pestano


Primefaces 5.x + JavaEE7(Glassfish 4.x and Wildfly 8)
Conventions Framework
Blog
@realpestano

Post 27 Apr 2011, 20:31

Posts: 51
Location: Brazil

2.2.. I'm waiting for the 3.0 Final...

Post 27 Apr 2011, 22:23

Posts: 26
Location: Jakarta, Indonesia

I will let you know how I solve this problem.
Well it seems that you want when u click on the spinner. you don't want to automatically update the backing bean data with certain reason.

JSF has a life cycle that you can control.
The default life cycle is

Request -> Render View -> Apply Request Value -> Validation Phase -> Update Model -> Invoke Application -> Render response

Then see my code below
<p:spinner stepFactor="1"
                min="0"
                required="true"
                requiredMessage="Campo [Quantidade] obrigatório"
                value="#{myBean.number}"
                id="quantidade"
                >

    <p:ajax event="change"
                process="quantidade"
                update="output"/>

     <f:valueChangeListener type="com.aliirawan.sample.webapp.MyBean"/>
</p:spinner>
<br/>
<h:outputText id="output" value="#{MyBean.number}"/>


MyBean class should implements ValueChangeListener

public class MyBean implements ValueChangeListener{

   private int number;
 
        //getter and setter for number

        //implements ValueChangeListener
        //Note that ValueChangeListener occured after Validation Phase
        //So just keep that this method invoked after validation Phase (not if you want to skip the validation phase use immediate="true"
   public void processValueChange(ValueChangeEvent e)
         throws AbortProcessingException {
      
      //System.out.println(e.getPhaseId());
      FacesContext context = FacesContext.getCurrentInstance();

      context.responseComplete();  //<-- this code make the life cycle ends.
                //(the next phases, update model, invoke application,render response is skipped)
                //then your backing bean variabel is not updated
   }
}


When do you want the value updated ?
You can use another listener such as ActionListener that have method processAction
this method is invoke after Invoke Application phase before Rendering Response

If you want to check whether the button is clicked by user. You can define in the processValueChange method above
check whether the command button id (that you clicked) is in RequestParameterMap() from FacesContext

Then see this one. I add a button.
  <h:form id="formServ">
                                        <p:spinner stepFactor="1"
                                                   min="0"
                                                   required="true"
                                                   requiredMessage="Campo [Quantidade] obrigatório"
                                                   value="#{myBean.number}"
                                                   id="quantidade"
                                                   >

                                            <p:ajax event="change"
                                                    process="quantidade"
                                                    update="output"/>
                                            <f:valueChangeListener type="com.aliirawan.sample.webapp.MyBean"/>
                                        </p:spinner>
                                        <br/>
                                        <h:outputText id="output" value="#{myBean.number}"/>
                                        <p:commandButton id="buttonUpdate" value="Update" update="output" />
                    </h:form>


and the method i revise into
public void processValueChange(ValueChangeEvent e)
         throws AbortProcessingException {
      
      //System.out.println(e.getPhaseId());
      FacesContext context = FacesContext.getCurrentInstance();

      //retrieve all request parameters
      Map<String,String> map = (Map<String, String>) context.getExternalContext().getRequestParameterMap();
      
      Set<Entry<String, String>> set = map.entrySet();
      Iterator<Entry<String,String>> t = set.iterator();
      while(t.hasNext()){
         Entry<String,String> entry = t.next();
         System.out.println("key=" + entry.getKey()+ ",value="+entry.getValue());
      }
      
      Object o = map.get("formServ:buttonUpdate"); //check whether the buttonUpdate is clicked
      if(o==null){
         //formServ:buttonUpdate not clicked, ends the life cycle!
         context.responseComplete();
      }else{
         //no code, just the life cycle, ends normally
         //from this phase, will go to Update Model (so the data in backing bean is updated using setter)
         //invoke application is used for navigation or redirection to another view
         //since you are using ajax Request, it's not going anywhere
         //finally render the response to client (Render Response phase)
      }
   }



You should read theses:
http://www.roseindia.net/jsf/jsflifecycle.shtml
http://www.ibm.com/developerworks/library/j-jsf2/
I like to explore new things. There's a way for everything. I believe.

Post 28 Apr 2011, 13:04

Posts: 51
Location: Brazil

oh.. Thanks for the answer.


Return to General