Valor do autocomplete [RESOLVIDO]

Boa tarde, gostaria de saber como utilizar o valor digitado no campo do autocomplete em meu Controller, mesmo ele sendo nulo e não sendo um veiculo cadastrado no BD.

                    <p:outputLabel value="Veículo: " style="padding-right: 30px"/>
                    <p:autoComplete id="veiculo" dropdown="true" 
                        label="Veículo" required="false" placeholder="Todos" 
                        readonly="#{portariaController.tipoVeiculo == 'SEM_PLACA' || portariaController.tipoVeiculo == 'SEM_VEICULO'}"
                        value="#{portariaController.veiculo}" 
                        completeMethod="#{veiculoController.completeVeiculos}" 
                        maxResults="10" var="v" itemLabel="#{v.placa}" 
                        converter="#{entityConverter}" itemValue="#{v}" forceSelection="false" >
                        <p:ajax event="itemSelect" update=":formPrincipal:pnlVeiculo" />
                        <p:ajax event="change" update=":formPrincipal:edit"/>
                    </p:autoComplete>

A premissa de um autocomplete é você inserir caracteres (digitar) e o sistema realizar uma pesquisa, apresentando os resultados compatíveis com os critérios de busca (começa com os mesmos caracteres inseridos, contém aquela sequencia de caracteres, etc).
Não vejo sentido em colocar um autocomplete para uma informação que não é persistida.

1 curtida

São 3 necessidades diferente dentro do autocomplete que estou fazendo.

1ª: Pesquisa (como você disse)
2ª: Validar a placa digitada.
3ª: Criar um novo veiculo com a placa digitada, caso não existir.

Porém não consigo pegar o valor digitado neste “input”, para prosseguir, sempre fica nulo.

Boa tarde!

Tenta utilizar o evento de keyup

<p:ajax event="keyup" process="@this" partialSubmit="true"/>

A cada tecla digitada é feito uma requisição e processa apenas o próprio componente, levando assim o valor da caixa de texto para o bean

Caso queira, você pode adicionar um delay na chamada ajax para ela não ser chamada sempre que uma tecla é digitada.

<p:ajax event="keyup" process="@this" partialSubmit="true" delay="300"/>

Olá Mike, obrigado pela ajuda.

Eu não tinha tentado isto, porém não deu certo, continua me trazendo nulo.

Posta o código pra eu ver como ficou

Como você esta fazendo os teste para saber se deu ou não?

EDIT:
O AutoComplete deseja receber um método na propriedade completeMethod, esse método recebe como parâmetro (implicitamente) o valor da caixa de texto, então você pode pegar esse valor e atribuir a um atributo seu

Sim, aqui está.

<p:outputLabel value="Veículo: " style="padding-right: 30px"/>
						<p:autoComplete id="veiculo" dropdown="true" 
							label="Veículo" required="false" placeholder="Todos" 
							readonly="#{portariaController.tipoVeiculo == 'SEM_PLACA' || portariaController.tipoVeiculo == 'SEM_VEICULO'}"
							value="#{portariaController.veiculo}" onkeypress="if (event.keyCode == 13) { onchange(); return false; }"
							completeMethod="#{veiculoController.completeVeiculos}" 
							maxResults="10" var="v" itemLabel="#{v.placa}"
							converter="#{entityConverter}" itemValue="#{v}" forceSelection="false" >
							<p:ajax event="itemSelect" update=":formPrincipal:pnlVeiculo" />
							<p:ajax event="change" listener="#{portariaController.upinsertVeiculo}" update=":formPrincipal:edit"/>
						</p:autoComplete>

Como nota, meu value é um objeto Veiculo. Fiz um teste passando uma String placa, porém também fica nulo. Estou fazendo o teste na função que cria um novo veiculo com a placa que foi digitada no autocomplete.

public void upinsertVeiculo() {
		Veiculo novoVeiculo = new Veiculo();
		novoVeiculo.setTipoVeiculo(this.getTipoVeiculo());
        novoVeiculo.setPlaca(this.getPlaca);
		veiculoService.save(novoVeiculo);
	}

public void upinsertVeiculo() {
		Veiculo novoVeiculo = new Veiculo();
		novoVeiculo.setTipoVeiculo(this.getTipoVeiculo());
        novoVeiculo.setPlaca(this.veiculo.getPlaca);
		veiculoService.save(novoVeiculo);
	}

Das duas formas não funcionaram.

Não da para fazer no completeMethod, pois não será sempre que vai criar um novo, as vezes posso utilizar um veiculo já cadastrado ou como disse acima, também preciso do valor para validar a Placa.

Alguém pode me ajudar?

luis,

Não tenho certeza mas o problema que eu estou vendo é que seu campo auto complete recebe o valor de um objeto Veiculo e voce está tentando inserir uma string.

Se for esse o problema recomendaria você alterar o value para receber uma String e fazer um tratamento no seu controller

Olá matheus, não é este o problema, é que postei apenas o autocomplete com o objeto e o método passando o objeto e a string. Mas na verdade eu tentei das duas formas, passando objeto e outra passando a string no value e não deu certo.

você ainda tem o auto complete passando o value com string?

Tenho:

<p:outputLabel value="Veículo: " style="padding-right: 30px"/>
						<p:autoComplete id="veiculo" dropdown="true" 
							label="Veículo" required="false" placeholder="Todos" 
							readonly="#{portariaController.tipoVeiculo == 'SEM_PLACA' || portariaController.tipoVeiculo == 'SEM_VEICULO'}"
							value="#{portariaController.placa}" onkeypress="if (event.keyCode == 13) { onchange(); return false; }"
							completeMethod="#{veiculoController.completeVeiculos}" 
							maxResults="10" converter="#{entityConverter}" forceSelection="false" >
							<p:ajax event="itemSelect" update=":formPrincipal:pnlVeiculo" />
							<p:ajax event="change" listener="#{portariaController.upinsertVeiculo}" update=":formPrincipal:edit"/>
						</p:autoComplete>

Luis, estou com duas dúvidas:

1 - Quando você preenche o campo com um valor não cadastrado ele é exibido no campo ou fica vazio quando perde o foco

2 - Ao utilizar o autocomplete com o valor de String, você faz a persistência do veiculo somente utilizando a placa?

Pessoal, consegui resolver criando um VeiculoConverter.

@Override
    public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) {
		
		synchronized(entities){
			for(java.util.Map.Entry<Object, String> entry : entities.entrySet()){
				if(entry.getValue().equals(value)){
					return entry.getKey();				
				}			
			}		
			
			if (placaUtils.validaPlaca(value) == false) {
				return null;
			}
			
			if (value != null) {
				Veiculo veiculo = veiculoService.findByPlaca(value);
				if (veiculo == null) {
					veiculo = new Veiculo();
					veiculo.setPlaca(value);
				}
				return veiculo;
			}
			
		}
		return null;
	}