[RESOLVIDO] PrimeFaces 3 - Propriedade editable do SelectOneMenu não "existe"

Fala galera, é o seguinte estou com um problema no uso do SelectOneMenu, está quase tudo certo, porém, quero que o SelectOneMenu permita ao usuário digitar ou pelo menos começar a digitar o texto e então o valor ser selecionado/sugerido.

Exemplificando:
Tenho quase 6000 cidades em um componente p:selectOneMenu e o usuário já sabe que a cidade é, por exemplo, São Paulo. Ao invés de ir até o registro São Paulo através do uso do mouse, ela então começa a digitar a String “Sã”, por exemplo, e a combo sugere ou seleciona o primeiro registro com essa ocorrência.

Problema:
O componente p:selectOneMenu não aceita a propriedade editable, de forma que o usuário apenas consegue selecionar (com o mouse) não consegue digitar ou sequer navegar/selecionar com as “setas”. No ShowCase do Primefaces existe um componente selectOneMenu configurado para ser editável e aceitar digitação, porém, não está funcionando, no meu caso, o netBeans acusa a seguinte mensagem:

Mensagem de Erro do NetBeans:
The attribute editable is not defined in the component’s interface

PrimeFaces Exemplo:

<h:outputText value="Editable: " />  
<p:selectOneMenu value="#{pprBean.city}" effect="fold" editable="true">  
      <f:selectItem itemLabel="Select One" itemValue="" />  
      <f:selectItems value="#{pprBean.cities}" />  
</p:selectOneMenu>

Meu Código:

<p:selectOneMenu value="#{cidadeMB.cidade.uf}" effect="fade"  editable="true"
            required="true" requiredMessage="O Campo Unidade Federativa é obrigatório.">
      <f:selectItems value="#{cidadeMB.ufs}" var="uf" itemLabel="#{uf.nome}" itemValue="#{uf}"/>
</p:selectOneMenu>

Já tentei utilizar o p:autoComplete, porém, tem alguns erros que não consegui resolver, e ele não “sugeriu/completou”.

No mais é isso, Agradeço!!!

Oi, com o p:selectOneMenu acho que vc não vai conseguir fazer isso, vc teria que usar o p:autoComplete mesmo, quais foram os erros ao utilizar o p:autoComplete?

Então, com o p:autoComplete o que está acontecendo é o seguinte: só consigo digitar algo se eu for de componente em componente do formulário (via TAB) até chegar nele, ou seja, caso o usuário clique direto no componente (autoComplete) ele não deixa digitar. Mesmo quando vou de componente em componente (via TAB) ele só me permite digitar uma letra, e então realiza as sugestões a partir da letra digitada, porém, preciso que o autoComplete realize o filtro com mais letras.

PrimeFaces - ShowCase

<p:autoComplete id="dd" dropdown="true" value="#{autoCompleteBean.txt6}"   
                    completeMethod="#{autoCompleteBean.complete}" />

Meu Código:

<p:autoComplete id="i_cidadeUf" dropdown="true" value="#{cidadeMB.cidade.uf}"
                                required="true" requiredMessage="O Campo Uf é obrigatório"
                                var="uf" itemLabel="#{uf.nome}" itemValue="#{uf}" effect="fade"
                                queryDelay="0" readonly="false"
                                completeMethod="#{cidadeMB.completaUf}" converter="ufConverter" />

Nesse contexto são mostradas todas as UFs, porém, ocorre os erros que supracitei.

De antemão agradeço!!

Quando ocorre esse problema não mostra nenhum erro no console?

Qual versão do primefecas vc ta usando? Eu uso esse componente com a versão 2 sem maiores problemas.

Então, não aparece nenhum erro/aviso no console!

Minha versão do PrimeFaces é a 3.0.

Quando vc vai direto para o componente ele não fica habilitado para edição? Se fica, quando vc digita algo nele o método completaUf está sendo chamado?
como esta seu método completaUf no bean?

Quando vou direto ao componente ele não permite edição, porém, o método completaUf é chamado porque é ele quem retorna as Unidades da Federação (UFs) disponíveis, mesmo que não tenha nenhum filtro.

Quando vou de componente em componente (só funciona via TAB) ele me permite editar o componente, porém, apenas por alguns instantes, normalmente, um usuário digitaria uma letra ou duas no máximo, com o tempo que o componente fica disponível.

Código do Método completaUf()

public List<Uf> completaUf(String query) {
      if (!query.isEmpty()) {
            List<Uf> sugestoes = new ArrayList<Uf>();
            for (Uf uf : getUfs()) {
                if (uf.getNome().toLowerCase().startsWith(query.toLowerCase())) {
                    sugestoes.add(uf);
                }
            }
            return sugestoes;
        }
        return getUfs();
}

Agradeço desde já!!

cara isso é muito estranho, não tem alguma coisa que ta desabilitando o componente para edição? Pela lógica o método completaUf só deveria ser chamado ao digitar alguma coisa no componente, mas vc ta dizendo que ele é chamado mesmo não permitindo edição, isso não poderia ta ocorrendo.

Tipo é isso que está acontecendo, tanto que tive que realizei uma condição: se a variavel query estiver vazia então retorna tudo.

O funcionamento é até estável no caso de seleção (selecionar um registro), porém, a ideia é permitir a edição para que o usuário tenha mais agilidade.

Você poderia postar o código completo da sua página xhtml?

<?xml version='1.0' encoding='UTF-8' ?>
<!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:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

    <ui:composition template="/pages/template/templateCadastro.xhtml">
        <ui:param name="title" value="Cidades" />
        <ui:param name="idTabela" value="cidades" />

        <ui:define name="botaoNovo">
            <p:commandButton id="btnNovo" value="Novo" update="novoRegistro"
                             onclick="dlgNovo.show()" process="@this"
                             immediate="true" action="#{cidadeMB.limpaCidade}" />
            <p:commandButton id="btnVoltar" value="Voltar"
                             onclick="window.location='${pageContext.request.contextPath}/webRMX/pages/index.jsf'"
                             type="button" ajax="false"/>
        </ui:define>

        <ui:define name="table">
            <p:dataTable id="cidades" var="cidade" value="#{cidadeMB.dataModel}"
                         paginator="true" rows="10" selection="#{cidadeMB.cidadeSelecionada}"
                         selectionMode="single" resizableColumns="true"
                         emptyMessage="Sem Registros." rowsPerPageTemplate="10,20,30"
                         rowKey="#{cidade.id}">

                <p:ajax event="rowSelect" listener="#{cidadeMB.onRowSelect}" update="detalhes" />

                <f:facet name="header">
                    Lista de Cidades
                </f:facet>

                <p:column headerText="Id" sortBy="#{cidade.id}" filterBy="#{cidade.id}" >
                    #{cidade.id}
                </p:column>

                <p:column headerText="Nome" sortBy="#{cidade.nome}" filterBy="#{cidade.nome}">
                    #{cidade.nome}
                </p:column>

                <p:column headerText="UF" sortBy="#{cidade.uf.sigla}" filterBy="#{cidade.uf.sigla}">
                    #{cidade.uf.sigla}
                </p:column>

                <p:column>
                    <p:commandButton id="selectButton" oncomplete="dlgDetalhes.show()" icon="ui-icon-search" title="Detalhes">  
                        <f:setPropertyActionListener value="#{cidade}" target="#{cidadeMB.cidade}" />  
                    </p:commandButton>
                    <p:commandButton id="updateButton" oncomplete="dlgAlterar.show()" icon="ui-icon-arrowrefresh-1-w" title="Alterar" update="alterar" >
                        <f:setPropertyActionListener value="#{cidade}" target="#{cidadeMB.cidade}" />  
                    </p:commandButton>
                    <p:commandButton id="deleteButton" oncomplete="dlgExcluir.show()" icon="ui-icon-close" title="Excluir">
                        <f:setPropertyActionListener value="#{cidade}" target="#{cidadeMB.cidade}" />  
                    </p:commandButton>
                </p:column>

            </p:dataTable>
        </ui:define>

        <ui:define name="formDetalhes">
            <h:panelGrid columns="2">
                <h:outputText value="Id:" />
                <h:outputText value="#{cidadeMB.cidade.id}" />
                <h:outputText value="Nome*:" />
                <h:outputText value="#{cidadeMB.cidade.nome}" />
                <h:outputText value="UF*:" />
                <h:outputText value="#{cidadeMB.cidade.uf.sigla}" />
                <h:outputText value="Data de Criação:" />
                <h:outputText value="#{cidadeMB.cidade.criacao.time}" >
                    <f:convertDateTime type="date" dateStyle="short"/>
                </h:outputText>
                <h:outputText value="Data de Modificação:"/>
                <h:outputText value="#{cidadeMB.cidade.modificacao.time}" >
                    <f:convertDateTime type="date" dateStyle="short"/>
                </h:outputText>
                <h:outputText value="Usuário Criador:" />
                <h:outputText value="#{cidadeMB.cidade.criador.nome}" />
            </h:panelGrid>
        </ui:define>

        <ui:define name="formCadastro">
            <h:panelGrid columns="2">
                <h:outputText value="Nome*:" />
                <p:inputText id="i_cidadeNome" value="#{cidadeMB.cidade.nome}" maxlength="45" 
                             required="true" requiredMessage="O Campo Nome é obrigatório."/>
                <h:outputText value="UF*:" />

                <p:selectOneMenu value="#{cidadeMB.cidade.uf}" effect="fold" editable="true"
                                 required="true" requiredMessage="O Campo Unidade Federativa é obrigatório.">
                    <f:selectItems value="#{cidadeMB.ufs}"/>
                </p:selectOneMenu>

                <p:commandButton id="i_btnSalvar" value="Salvar" update="cidades growl"
                                 action="#{cidadeMB.salvar}" oncomplete="handleComplete(args)" />
                <p:commandButton id="i_btnCancelar" value="Cancelar" onclick="dlgNovo.hide()"
                                 type="button"  />
            </h:panelGrid>
        </ui:define>

        <ui:define name="formAlterar">
            <h:panelGrid columns="2">
                <h:outputText value="Nome*:" />
                <p:inputText id="a_cidadeNome" value="#{cidadeMB.cidade.nome}" maxlength="45" 
                             required="true" requiredMessage="O Campo nome é obrigatório."/>
                <h:outputText value="UF*:" />
                <p:inputText id="a_cidadeUf" value="#{cidadeMB.cidade.uf.sigla}" maxlength="20" 
                             required="true" requiredMessage="O Campo UF é obrigatório."/>

                <p:commandButton id="a_btnAlterar" value="Alterar" update="cidades growl"
                                 oncomplete="handleComplete(args)"
                                 actionListener="#{cidadeMB.alterar}" />
                <p:commandButton id="a_btnCancelar" value="Cancelar" onclick="dlgAlterar.hide()"
                                 type="button" ajax="false"/>
            </h:panelGrid>
        </ui:define>

        <ui:define name="formDeletar">
            <p:commandButton id="btnSim" value="Sim"
                             oncomplete="dlgExcluir.hide()" ajax="false"
                             actionListener="#{cidadeMB.deletar}" update="cidades" />
        </ui:define>
    </ui:composition>

</html>

e onde está o código com o autocomplete?
Vi que vc está colocando editable=“true” no seu p:selectOneMenu, essa propriedade não existe, vc só vai conseguir o que quer usando o p:autoComplete.
Outra coisa vc implementou um Converter para Uf?

Me desculpe código errado, tenho deixado esse código aí como oficial até que o autoComplete funcione.

Quanto à classe Uf, Sim, eu implementei um converter para ela.

Segue o código correto:

[code]

<?xml version='1.0' encoding='UTF-8' ?>
<ui:composition template="/pages/template/templateCadastro.xhtml">
    <ui:param name="title" value="Cidades" />
    <ui:param name="idTabela" value="cidades" />

    <ui:define name="botaoNovo">
        <p:commandButton id="btnNovo" value="Novo" update="novoRegistro"
                         onclick="dlgNovo.show()" process="@this"
                         immediate="true" action="#{cidadeMB.limpaCidade}" />
        <p:commandButton id="btnVoltar" value="Voltar"
                         onclick="window.location='${pageContext.request.contextPath}/webRMX/pages/index.jsf'"
                         type="button" ajax="false"/>
    </ui:define>

    <ui:define name="table">
        <p:dataTable id="cidades" var="cidade" value="#{cidadeMB.dataModel}"
                     paginator="true" rows="10" selection="#{cidadeMB.cidadeSelecionada}"
                     selectionMode="single" resizableColumns="true"
                     emptyMessage="Sem Registros." rowsPerPageTemplate="10,20,30"
                     rowKey="#{cidade.id}">

            <p:ajax event="rowSelect" listener="#{cidadeMB.onRowSelect}" update="detalhes" />

            <f:facet name="header">
                Lista de Cidades
            </f:facet>

            <p:column headerText="Id" sortBy="#{cidade.id}" filterBy="#{cidade.id}" >
                #{cidade.id}
            </p:column>

            <p:column headerText="Nome" sortBy="#{cidade.nome}" filterBy="#{cidade.nome}">
                #{cidade.nome}
            </p:column>

            <p:column headerText="UF" sortBy="#{cidade.uf.sigla}" filterBy="#{cidade.uf.sigla}">
                #{cidade.uf.sigla}
            </p:column>

            <p:column>
                <p:commandButton id="selectButton" oncomplete="dlgDetalhes.show()" icon="ui-icon-search" title="Detalhes">  
                    <f:setPropertyActionListener value="#{cidade}" target="#{cidadeMB.cidade}" />  
                </p:commandButton>
                <p:commandButton id="updateButton" oncomplete="dlgAlterar.show()" icon="ui-icon-arrowrefresh-1-w" title="Alterar" update="alterar" >
                    <f:setPropertyActionListener value="#{cidade}" target="#{cidadeMB.cidade}" />  
                </p:commandButton>
                <p:commandButton id="deleteButton" oncomplete="dlgExcluir.show()" icon="ui-icon-close" title="Excluir">
                    <f:setPropertyActionListener value="#{cidade}" target="#{cidadeMB.cidade}" />  
                </p:commandButton>
            </p:column>

        </p:dataTable>
    </ui:define>

    <ui:define name="formDetalhes">
        <h:panelGrid columns="2">
            <h:outputText value="Id:" />
            <h:outputText value="#{cidadeMB.cidade.id}" />
            <h:outputText value="Nome*:" />
            <h:outputText value="#{cidadeMB.cidade.nome}" />
            <h:outputText value="UF*:" />
            <h:outputText value="#{cidadeMB.cidade.uf.sigla}" />
            <h:outputText value="Data de Criação:" />
            <h:outputText value="#{cidadeMB.cidade.criacao.time}" >
                <f:convertDateTime type="date" dateStyle="short"/>
            </h:outputText>
            <h:outputText value="Data de Modificação:"/>
            <h:outputText value="#{cidadeMB.cidade.modificacao.time}" >
                <f:convertDateTime type="date" dateStyle="short"/>
            </h:outputText>
            <h:outputText value="Usuário Criador:" />
            <h:outputText value="#{cidadeMB.cidade.criador.nome}" />
        </h:panelGrid>
    </ui:define>

    <ui:define name="formCadastro">
        <h:panelGrid columns="2">
            <h:outputText value="Nome*:" />
            <p:inputText id="i_cidadeNome" value="#{cidadeMB.cidade.nome}" maxlength="45" 
                         required="true" requiredMessage="O Campo Nome é obrigatório."/>
            <h:outputText value="UF*:" />

            <p:autoComplete id="i_cidadeUf" dropdown="true" value="#{cidadeMB.cidade.uf}"  
                            required="true" requiredMessage="O Campo Uf é obrigatório"  
                            var="uf" itemLabel="#{uf.nome}" itemValue="#{uf}" effect="fade"
                            completeMethod="#{cidadeMB.completaUf}" converter="ufConverter" />  

            <p:commandButton id="i_btnSalvar" value="Salvar" update="cidades growl"
                             action="#{cidadeMB.salvar}" oncomplete="handleComplete(args)" />
            <p:commandButton id="i_btnCancelar" value="Cancelar" onclick="dlgNovo.hide()"
                             type="button"  />
        </h:panelGrid>
    </ui:define>

    <ui:define name="formAlterar">
        <h:panelGrid columns="2">
            <h:outputText value="Nome*:" />
            <p:inputText id="a_cidadeNome" value="#{cidadeMB.cidade.nome}" maxlength="45" 
                         required="true" requiredMessage="O Campo nome é obrigatório."/>
            <h:outputText value="UF*:" />
            <p:inputText id="a_cidadeUf" value="#{cidadeMB.cidade.uf.sigla}" maxlength="20" 
                         required="true" requiredMessage="O Campo UF é obrigatório."/>

            <p:commandButton id="a_btnAlterar" value="Alterar" update="cidades growl"
                             oncomplete="handleComplete(args)"
                             actionListener="#{cidadeMB.alterar}" />
            <p:commandButton id="a_btnCancelar" value="Cancelar" onclick="dlgAlterar.hide()"
                             type="button" ajax="false"/>
        </h:panelGrid>
    </ui:define>

    <ui:define name="formDeletar">
        <p:commandButton id="btnSim" value="Sim"
                         oncomplete="dlgExcluir.hide()" ajax="false"
                         actionListener="#{cidadeMB.deletar}" update="cidades" />
    </ui:define>
</ui:composition>
[/code] Está na linha 90.

De toda forma agradeço!!

Problema com o AutoComplete resolvido!

O problema estava na utilização do AutoComplete dentro de um Dialog, ou seja, fora do Dialog, funciona perfeitamente, porém, dentro não funcionava.

A solução foi atualizar o primefaces para o 3.0 M4.

Há uma discurssão sobre o problema nesse link: http://code.google.com/p/primefaces/issues/detail?id=3208

Quanto ao componente SelectOneMenu a propriedade editable não existia realmente na versão do primefaces, basta atualizá-lo!

Agradeço ao geraldo.vec pelo empenho em ajudar-me!!!