commnadButton só salva com dois cliques

Pessoal,

Não sei porque, mas meu commandButton só está salvando se eu clicá-lo duas vezes.
Ainda não achei o motivo desse problema e gostaria de solucioná-lo o mais rápido possível.

Segue o meu código:

<h:form id="formManterProduto">                   

                    <p:focus for="nome"/>                                                                  

                    <table>
                        <tr>
                            <td>
                                <h:outputLabel for="codigo" value="C&oacute;digo:" styleClass="labelNegrito"
                                               rendered="#{produtoController.produto.id != null}"/>        
                            </td>
                            <td>
                                <h:inputText id="codigo" value="#{produtoController.produto.id}" 
                                             disabled="true" size="10" rendered="#{produtoController.produto.id != null}"/>  
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h:outputLabel for="nome" value="Produto (*):" styleClass="labelNegrito"/>
                            </td>
                            <td>
                                <p:inputMask id="nome" value="#{produtoController.produto.nome}"
                                             mask="" size="60" maxlength="200"
                                             required="true" 
                                             requiredMessage="Por favor, digite o nome do produto."/>  
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h:outputLabel for="descricao" value="Descrição:" styleClass="labelNegrito"/>
                            </td>
                            <td>
                                <p:inputMask id="descricao" value="#{produtoController.produto.descricao}"
                                             mask="" size="60" maxlength="200"/>  
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h:outputLabel for="categoria" value="Categoria (*):" styleClass="labelNegrito"/>
                            </td>
                            <td>
                                <p:selectOneMenu id="listaCategorias" widgetVar="listaCategorias"
                                                 value="#{produtoController.produto.subCategoria.categoria}"                                                  
                                                 converter="categoriaConverter"
                                                 required="true"
                                                 requiredMessage="Por favor, selecione uma categoria.">
                                    <f:selectItem itemLabel="Selecione..."/>
                                    <f:selectItems value="#{categoriaController.listaCategoriasParaCombobox}"/>                                                                               
                                </p:selectOneMenu>  

                                <p:spacer width="10"/>

                                <p:commandLink value="[+] Nova Categoria"                                        
                                               title="Incluir uma nova categoria"                                               
                                               action="#{categoriaController.prepararParaIncluir}"
                                               oncomplete="incluirCategoriaDialog.show()"
                                               update=":formNovaCategoria"
                                               immediate="true"/>                                                                  
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h:outputLabel for="subCategoria" value="Subcategoria (*):" styleClass="labelNegrito"/>
                            </td>
                            <td>
                                <p:selectOneMenu id="subCategorias" widgetVar="subCategorias"
                                                 value="#{produtoController.produto.subCategoria}"                                                  
                                                 converter="subCategoriaConverter"
                                                 required="true"
                                                 requiredMessage="Por favor, selecione uma subcategoria.">
                                    <f:selectItem itemLabel="Selecione..."/>
                                    <f:selectItems value="#{subCategoriaController.listaSubCategoriasParaCombobox}"/>                                                                               
                                </p:selectOneMenu>                                                                  

                                <p:spacer width="10"/>

                                <p:commandLink value="[+] Nova Subcategoria"                                        
                                               title="Incluir uma nova subcategoria"                                               
                                               action="#{subcategoriaController.prepararParaIncluir}"
                                               oncomplete="incluirSubCategoriaDialog.show()"
                                               update=":formNovaSubCategoria"
                                               immediate="true"/>                                                                  
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h:outputLabel for="unidade" value="Unidade (*):" styleClass="labelNegrito"/>
                            </td>
                            <td>
                                <p:selectOneMenu id="listaUnidades" widgetVar="listaUnidades"
                                                 value="#{produtoController.produto.unidade}"                                                                                  
                                                 converter="unidadeConverter"
                                                 required="true"
                                                 requiredMessage="Por favor, selecione uma unidade.">
                                    <f:selectItem itemLabel="Selecione..."/>
                                    <f:selectItems value="#{unidadeController.listaUnidadesParaCombobox}"/>                                                                               
                                </p:selectOneMenu>

                                <p:spacer width="10"/>

                                <p:commandLink value="[+] Nova Unidade" 
                                               title="Incluir uma nova unidade"                                               
                                               action="#{unidadeController.prepararParaIncluir}"
                                               oncomplete="incluirUnidadeDialog.show()"
                                               update=":formNovaUnidade"
                                               immediate="true"/>                                                                             
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h:outputLabel for="estoqueMinimo" value="Estoque M&iacute;nimo (*):" styleClass="labelNegrito"/>  
                            </td>
                            <td>
                                <p:inputMask id="estoqueMinimo" value="#{produtoController.produto.estoqueMin}"
                                             mask="9?9999" size="8" maxlength="11"
                                             required="true"
                                             requiredMessage="Por favor, informe um estoque m&iacute;nimo."/>                        
                               
                                <p:spacer width="20"/>

                                <h:outputLabel for="estoqueMaximo" value="Estoque M&aacute;ximo:" styleClass="labelNegrito"/>

                                <p:spacer width="10"/>

                                <p:inputMask id="estoqueMaximo" value="#{produtoController.produto.estoqueMax}"
                                             mask="9?9999" size="8" maxlength="11"/>                                           
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h:outputLabel for="localizacao" value="Localiza&ccedil;&atilde;o:" styleClass="labelNegrito"/>
                            </td>
                            <td colspan="3">
                                <p:inputMask id="localizacao" 
                                             value="#{produtoController.produto.localizacao}"
                                             mask="" size="60" maxlength="200"/>                             
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h:outputLabel for="perecivel" value="Perec&iacute;vel (*):" styleClass="labelNegrito"/>
                            </td>
                            <td>
                                <p:selectOneMenu id="perecivel" value="#{produtoController.produto.perecivel}"
                                                 required="true"
                                                 requiredMessage="Por favor, informe se o produto é perecível.">                            
                                    <f:selectItem itemValue="" itemLabel="Selecione..."/>   
                                    <f:selectItem itemValue="false" itemLabel="N&atilde;o"/>   
                                    <f:selectItem itemValue="true" itemLabel="Sim"/>
                                </p:selectOneMenu>                                                                
                            </td>
                        </tr>
                        <tr>
                            <td>                              
                                <h:outputLabel for="ativo" value="Ativo (*):" styleClass="labelNegrito"/>
                            </td>
                            <td>
                                <p:selectOneMenu id="ativo" value="#{produtoController.produto.ativo}" 
                                                 required="true"
                                                 requiredMessage="Por favor, informe se o produto está ativo.">                                    
                                                     
                                    <f:selectItem itemValue="" itemLabel="Selecione..."/> 
                                    <f:selectItem itemValue="true" itemLabel="Sim"/>
                                    <f:selectItem itemValue="false" itemLabel="N&atilde;o"/>                                              
                                </p:selectOneMenu>      
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h:outputLabel for="obs" value="Observa&ccedil;&otilde;es:" styleClass="labelNegrito"/>
                            </td>
                            <td>
                                <p:inputMask id="obs" value="#{produtoController.produto.obs}"
                                             mask="" maxlength="150" size="60"/>
                            </td>                                    
                        </tr>
                    </table>  

                    <p:messages autoUpdate="true" redisplay="true"/>                                                                                     

                    <p:commandButton icon="ui-icon-disk" value="Salvar"                                     
                                     action="#{produtoController.salvar}"
                                     update=":formManterProduto"/>     
                    
                    <p:commandButton icon="ui-icon-close" value="Cancelar"
                                     onclick="manterProdutoDialog.hide()"
                                     update=":formPrincipal"
                                     immediate="true"/>
                </h:form> 

Se precisarem dos models e dos controllers, para facilitar a descoberta desse problema, é só falar.

Desde já agradeço.

** O problema está no commandButton de salvar:

 <p:commandButton icon="ui-icon-disk" value="Salvar"                                     
                                     action="#{produtoController.salvar}"
                                     update=":formManterProduto"/>  

Pessoal,

Ainda não resolvi o problema desse botão e nem sei onde pode estar.

Alguém pode me ajudar?

o botão de salvar, só salva depois que eu clico duas vezes.

Olá Jefferson,

Não sei se é isso, mas tenta mudar de action para actionListner.

Posta depois o seu Bean com o método salvar.

Pessoal,

Desculpa a demora em responder, mas ainda continuo com esse problema.

Já troquei de action para actionListener e não resolveu.

Alguem pode me ajudar?

  <p:commandButton icon="ui-icon-disk" value="Salvar"                                     
                                 actionListener="#{produtoController.salvar}"
                                 update=":formManterProduto"/> 
 public void salvar() throws IOException {

        this.produtoDao.saveOrUpdate(this.produto);

        this.produto = new Produto();      

        String url = "produto.sgm";
        
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
        
        ec.redirect(url);
    }

Tenta:

<p:commandButton icon="ui-icon-disk" value="Salvar" action="#{produtoController.salvar}" update="@form"/>

O nome do seu Bean ou o mapeamento é : “ProdutoController” mesmo .

O CTRL + click em cima do salvar vai para o método salvar() mesmo, você já testou ?

O nome do meu BEAN é esse: @ManagedBean(name = “produtoController”)

O clik + CTRL vai para o método correto sim, acabei de fazer o teste.

Coloquei o @form dentro do update e nada mudou, continuo tendo que clicar duas vezes para salvar.

Como você chega nessa tela ? … é através de um click em algum menu que redireciona para ela, ou é através de algum direcionamento pela url ? … é através de algum comando javascript, como por exemplo para abrir uma dialog ?

Posta aqui no tópico.

Eu pergunto isso, porque pode ter algum redirecionamento feito com ajax antes que não tenha sido completado ou com erro e por isso que acaba sendo necessário clicar duas vezes erroniamente.

Aconteceu uma vez isso comigo.

Essa tela é chamada por esse botão:

 <p:commandButton value="Incluir Novo" icon="ui-icon-disk"
                                         alt="Incluir um novo produto" 
                                         title="Incluir um novo produto"
                                         actionListener="#{produtoController.prepararParaIncluir}"
                                         oncomplete="manterProdutoDialog.show()"
                                         update=":formManterProduto"/> 

Uma coisa que você pode fazer que vai funcionar com certeza , mas o seu redirect (no método) nao vai funcionar (eu acho) é colocar no botao salvar : "ajax=“false”

<p:commandButton icon="ui-icon-disk" value="Salvar" actionListener="#{produtoController.salvar}" update="@form" ajax="false"/>

Tenta lá …

Pois é, gustavo. Voce tem razao, resolveu o problema do clique, mas surgiram outras. Não está redirecionando nem validando os campos obrigatórios.

Segue o codigo completo.

<ui:composition template="../template/template.xhtml"
                xmlns:p="http://primefaces.org/ui"
                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:c="http://java.sun.com/jsp/jstl/core">    

    <ui:define name="conteudo">   
      <h:form id="cabecalho_atalhos">
             <p:commandButton value="Incluir Novo" icon="ui-icon-disk"
                                         alt="Incluir um novo produto" 
                                         title="Incluir um novo produto"
                                         actionListener="#{produtoController.prepararParaIncluir}"
                                         oncomplete="manterProdutoDialog.show()"
                                         update=":formManterProduto"/>                                          

                        <p:commandButton icon="ui-icon-arrowthickstop-1-w" value="Voltar"
                                         onclick="javascript:history.back(1)"
                                         immediate="true"/>
      </h:form> 
<h:form id="formPrincipal"> 
 <p:dataTable id="produtos" var="produto" value="#{produtoController.produtos}"                             
                         paginator="true" rows="10"
                         paginatorTemplate="{FirstPageLink} {PreviousPageLink} 
                         {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"                              
                         rowsPerPageTemplate="5,10,20,30"   
                         paginatorPosition="bottom" 
                         rowKey="#{produto}"                             
                         selection="#{produtoController.produtoSelecionado}"                           
                         selectionMode="single"           
                         emptyMessage="Nenhum produto cadastrado!">
 <p:column style="text-align: left; width: 30px;"> 
                    <f:facet name="header">  
                        C&oacute;d.
                    </f:facet> 
                    <h:outputText value="#{produto.id}" style="color: black;" rendered="#{produto.ativo}"/>  
                    <h:outputText value="#{produto.id}" style="color: blue;" rendered="#{!produto.ativo}"/>  
                </p:column>  

                <p:column style="text-align: left;">  
                    <f:facet name="header">  
                        Produto
                    </f:facet>
                    <h:outputText value="#{produto.nome}" style="color: black;" rendered="#{produto.ativo}"/>  
                    <h:outputText value="#{produto.nome}" style="color: blue;" rendered="#{!produto.ativo}"/>  
                </p:column> 
 <p:column style="text-align: center;">
                    <f:facet name="header">  
                        Ações
                    </f:facet>
                    <p:commandButton icon="ui-icon-pencil"
                                     alt="Editar/Visualizar os dados do produto" 
                                     title="Editar/Visualizar os dados do produto" 
                                     action="#{produtoController.prepararParaEditarEVisualizar}"
                                     oncomplete="manterProdutoDialog.show()"
                                     update=":formManterProduto"
                                     style="height: 20px; width: 20px;">
                        <f:setPropertyActionListener 
                            value="#{produto}" target="#{produtoController.produtoSelecionado}" />
                    </p:commandButton>  
                    
                    <p:commandButton icon="ui-icon-plus"
                                     alt="Visualizar mais detalhes do produto" 
                                     title="Visualizar mais detalhes do produto" 
                                     action="#{produtoController.prepararParaEditarEVisualizar}"
                                     oncomplete="detalhesProdutoDialog.show()"
                                     update=":formDetalhesProduto"
                                     style="height: 20px; width: 20px;">
                        <f:setPropertyActionListener 
                            value="#{produto}" target="#{produtoController.produtoSelecionado}" />
                    </p:commandButton>                                        
                </p:column>                                                
                    
            </p:dataTable>  

                <p:commandButton value="Incluir Novo" icon="ui-icon-disk"
                                 alt="Incluir um novo produto" 
                                 title="Incluir um novo produto"
                                 actionListener="#{produtoController.prepararParaIncluir}"
                                 oncomplete="manterProdutoDialog.show()"
                                 update=":formManterProduto"/>    

                <p:commandButton icon="ui-icon-arrowthickstop-1-w" value="Voltar"
                                 onclick="javascript:history.back(1)"/>

            </h:panelGrid>
        </h:form>

Dialog para cadastrar/editar poduto

<p:dialog header="Gerenciar produto" widgetVar="manterProdutoDialog" 
                  minWidth="480" minHeight="200" resizable="true" closable="true"                       
                  showEffect="slide" hideEffect="slide">

            <h:outputText value="Campos com (*) s&atilde;o de preenchimento obrigat&oacute;rio!"
                          style="font-style: italic;"/>
            <p:separator/>

            <h:form id="formManterProduto">                   

                <p:focus for="nome"/>                                                                  

                <table>
                    <tr>
                        <td>
                            <h:outputLabel for="codigo" value="C&oacute;digo:" styleClass="labelNegrito"
                                           rendered="#{produtoController.produto.id != null}"/>        
                        </td>
                        <td>
                            <h:inputText id="codigo" value="#{produtoController.produto.id}" 
                                         disabled="true" size="10" rendered="#{produtoController.produto.id != null}"/>  
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <h:outputLabel for="nome" value="Produto (*):" styleClass="labelNegrito"/>
                        </td>
                        <td>
                            <p:inputMask id="nome" value="#{produtoController.produto.nome}"
                                         mask="" size="60" maxlength="200"
                                         required="true" 
                                         requiredMessage="Por favor, digite o nome do produto."/>  
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <h:outputLabel for="descricao" value="Descrição:" styleClass="labelNegrito"/>
                        </td>
                        <td>
                            <p:inputMask id="descricao" value="#{produtoController.produto.descricao}"
                                         mask="" size="60" maxlength="200"/>  
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <h:outputLabel for="categoria" value="Categoria (*):" styleClass="labelNegrito"/>
                        </td>
                        <td>
                            <p:selectOneMenu id="listaCategorias" widgetVar="listaCategorias"
                                             value="#{produtoController.produto.subCategoria.categoria}"                                                  
                                             converter="categoriaConverter"
                                             required="true"
                                             requiredMessage="Por favor, selecione uma categoria.">
                                <f:selectItem itemLabel="Selecione..."/>
                                <f:selectItems value="#{categoriaController.listaCategoriasParaCombobox}"/>                                                                               
                            </p:selectOneMenu>  

                            <p:spacer width="10"/>

                            <p:commandLink value="[+] Nova Categoria"                                        
                                           title="Incluir uma nova categoria"                                               
                                           action="#{categoriaController.prepararParaIncluir}"
                                           oncomplete="incluirCategoriaDialog.show()"
                                           update=":formNovaCategoria"
                                           immediate="true"/>                                                                  
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <h:outputLabel for="subCategoria" value="Subcategoria (*):" styleClass="labelNegrito"/>
                        </td>
                        <td>
                            <p:selectOneMenu id="subCategorias" widgetVar="subCategorias"
                                             value="#{produtoController.produto.subCategoria}"                                                  
                                             converter="subCategoriaConverter"
                                             required="true"
                                             requiredMessage="Por favor, selecione uma subcategoria.">
                                <f:selectItem itemLabel="Selecione..."/>
                                <f:selectItems value="#{subCategoriaController.listaSubCategoriasParaCombobox}"/>                                                                               
                            </p:selectOneMenu>                                                                  

                            <p:spacer width="10"/>

                            <p:commandLink value="[+] Nova Subcategoria"                                        
                                           title="Incluir uma nova subcategoria"                                               
                                           action="#{subcategoriaController.prepararParaIncluir}"
                                           oncomplete="incluirSubCategoriaDialog.show()"
                                           update=":formNovaSubCategoria"
                                           immediate="true"/>                                                                  
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <h:outputLabel for="unidade" value="Unidade (*):" styleClass="labelNegrito"/>
                        </td>
                        <td>
                            <p:selectOneMenu id="listaUnidades" widgetVar="listaUnidades"
                                             value="#{produtoController.produto.unidade}"                                                                                  
                                             converter="unidadeConverter"
                                             required="true"
                                             requiredMessage="Por favor, selecione uma unidade.">
                                <f:selectItem itemLabel="Selecione..."/>
                                <f:selectItems value="#{unidadeController.listaUnidadesParaCombobox}"/>                                                                               
                            </p:selectOneMenu>

                            <p:spacer width="10"/>

                            <p:commandLink value="[+] Nova Unidade" 
                                           title="Incluir uma nova unidade"                                               
                                           action="#{unidadeController.prepararParaIncluir}"
                                           oncomplete="incluirUnidadeDialog.show()"
                                           update=":formNovaUnidade"
                                           immediate="true"/>                                                                             
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <h:outputLabel for="estoqueMinimo" value="Estoque M&iacute;nimo (*):" styleClass="labelNegrito"/>  
                        </td>
                        <td>
                            <p:inputMask id="estoqueMinimo" value="#{produtoController.produto.estoqueMin}"
                                         mask="9?9999" size="8" maxlength="11"
                                         required="true"
                                         requiredMessage="Por favor, informe um estoque m&iacute;nimo."/>                        

                            <p:spacer width="20"/>

                            <h:outputLabel for="estoqueMaximo" value="Estoque M&aacute;ximo:" styleClass="labelNegrito"/>

                            <p:spacer width="10"/>

                            <p:inputMask id="estoqueMaximo" value="#{produtoController.produto.estoqueMax}"
                                         mask="9?9999" size="8" maxlength="11"/>                                           
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <h:outputLabel for="localizacao" value="Localiza&ccedil;&atilde;o:" styleClass="labelNegrito"/>
                        </td>
                        <td colspan="3">
                            <p:inputMask id="localizacao" 
                                         value="#{produtoController.produto.localizacao}"
                                         mask="" size="60" maxlength="200"/>                             
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <h:outputLabel for="perecivel" value="Perec&iacute;vel (*):" styleClass="labelNegrito"/>
                        </td>
                        <td>                          
                            <p:selectOneRadio id="perecivel" value="#{produtoController.produto.perecivel}">  
                                <f:selectItem itemValue="true" itemLabel="Sim"/>
                                <f:selectItem itemValue="false" itemLabel="Não"/>
                            </p:selectOneRadio>
                        </td>
                    </tr>
                    <tr>
                        <td>                              
                            <h:outputLabel for="ativo" value="Ativo (*):" styleClass="labelNegrito"/>
                        </td>
                        <td>                           
                            <p:selectOneRadio id="ativo" value="#{produtoController.produto.ativo}">  
                                <f:selectItem itemValue="true" itemLabel="Sim"/>
                                <f:selectItem itemValue="false" itemLabel="Não"/>
                            </p:selectOneRadio> 
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <h:outputLabel for="obs" value="Observa&ccedil;&otilde;es:" styleClass="labelNegrito"/>
                        </td>
                        <td>
                            <p:inputMask id="obs" value="#{produtoController.produto.obs}"
                                         mask="" maxlength="150" size="60"/>
                        </td>                                    
                    </tr>
                </table>  

                <p:messages id="errosManterProduto"/>                                                                                      

                <p:commandButton icon="ui-icon-disk" value="Salvar"                                     
                                 action="#{produtoController.salvar}"
                                 update="@form"/>     
                <!--update=":formManterProduto"-->

                <p:commandButton icon="ui-icon-close" value="Cancelar"
                                 onclick="manterProdutoDialog.hide()"
                                 update=":formPrincipal"
                                 immediate="true"/>
            </h:form> 

        </p:dialog> 

Pois é, foi como eu tinha te falado, com o ajax false não dá para instanciar o FacesContext e com isso vc nao consegue redirecionar.

O seu método “prepararParaIncluir” faz alguma coisa com javaScript ? Posta ele.

Outra tentativa, tenta mudar no botao o "oncomplete=“manterProdutoDialog.show()” por onsucess=“manterProdutoDialog.show()” e vê se o dialog vai abrir .

Meu método está assim:

public void prepararParaIncluir() {
        this.produto = new Produto();
    }

Coloquei onsuccess, mas nada mudou.

Cara, to tentando te ajudar porque já passei por um problema igual, mas não estou lembrando como resolvi hehhe

Tenta colocar isso no seu código:

Vê se a rodinha do ponteiro do mouse fica girando infinitamente , depois que o dialog fica aberto.

Pode ser colocado em qualquer lugar do código?

Coloquei dentro do meu dialog para cadastro do produto e nada mudou. Aparece uma rodinha girando do lado do cursor, apenas isso, mas executa tudo normal (tenho que continuar dando dois cliques)

Colocando esse código o cursor vira uma mão ao abrir o dialog

se a rodinha do mouse está rodando mesmo com o dialog aberto , quer dizer que tem alguma coisa com ajax que nao foi finalizada na hora de abrir o dialog. Você pode ver que quando vc clica no botao pela primeira vez , a rodinha deve parar de rodar, não é isso que acontece ? Agora é tentar saber porque o ajax nao está sendo completado depois que o dialog é aberto.

apaga ele depois

Quando eu coloco essa linha de codigo dentro do meu dialog, acontece o seguinte:
eu clico no botao incluir novo, gira uma roda do lado do cursor, o dialog é aberto, mas a roda para de girar. Quando eu vou mexer no dialog aberto o cursor se mantem como uma mão, mas eu consigo fazer tudo normalmente, inclusive tenho que dar 2 cliques ainda para salvar.
Não sei mesmo o que é.