Ajax
Ajax é uma tecnologia que permite que partes da tela sejam atualizadas dinamicamente.
O NEO possui suporte a esse recurso. A maneira mais simples de se fazer uma chamada ajax é utilizar
a função Javascript sendRequest incluida no arquivo ajax.js.
function sendRequest(url,params,HttpMethod, callbackfunction, errorcallback)
Essa função recebe os seguintes parâmetros:
- url: É a URL para onde deve ser enviada a requisição
- params: São os parâmetros que devem ser enviados
- HttpMethod: GET ou POST (recomenda-se o uso de POST)
- callbackfunction: função javascript que será o callback (função que irá tratar a resposta do ajax)
- errorcallback: Callback caso aconteça algum erro na requisição (opcional)
Exemplo de utilização dessa função (suponha o seguinte controller e JSP):
package exemplo;
import java.io.IOException;
import org.springframework.web.servlet.ModelAndView;
import br.com.linkcom.neo.controller.Controller;
import br.com.linkcom.neo.controller.DefaultAction;
import br.com.linkcom.neo.controller.MultiActionController;
import br.com.linkcom.neo.core.web.WebRequestContext;
@Controller(path="/modulo/Ajax")
public class AjaxController extends MultiActionController{
public void funcaoAjax(WebRequestContext request) throws IOException{
request.getServletResponse().getWriter().println( "Mensagem do servidor" );
}
}
[JSP]
<%@ taglib prefix="n" uri="neo"%>
<html>
<head>
<n:head/>
</head>
<body>
<script type="text/javascript">
function executarAjax(){
sendRequest('/app/modulo/Ajax','ACAO=funcaoAjax','POST', ajaxCallback, erroCallback);
}
function ajaxCallback(data){
alert(data);
}
function erroCallback(request){
alert('Erro no ajax!\n' + request.responseText);
}
</script>
<button onclick="executarAjax()">Testar ajax</button>
</body>
</html>
Foi criado um botão com um evento javascript que executa o método executarAjax.
A função executarAjax chama a função sendRequest passando como parâmetro a url (incluindo o nome da aplicação) do controller desejado,
o parâmetro ACAO indicando que a action que deve ser executada no controller é a funcaoAjax,
o método Http POST, a função de callback para quando a requisição for concluída e a função caso ocorra algum erro.
A função ajaxCallback recebe um parâmetro data. Esse parametro é o conteúdo do texto que o servidor enviou.
No caso, ao se fazer uma chamada ajax o controller irá imprimir na saída 'Mensagem do servidor'
que chegará na função ajaxCallback através do parâmetro data.
A função ajaxCallback faz um alert dessa variável mostrando o que foi enviado pelo servidor.
Dica: Uma action de um controller pode tanto retornar um ModelAndView quanto não retornar nada.
Quando desejar imprimir na saída padrão, como foi o caso, é útil utilizar o tipo de retorno void.
Combo Reload Group
O NEO também possui uma tag para facilitar a utilização de ajax em combos dependentes.
Essa tag é a comboReloadGroup. Essa tag agrupa determinados combos e cria o javascript para
carregar os itens de um determinado combo de acordo com o valor de outro combo.
Vamos ver um exemplo. Suponha que temos as classes País, Estado e Cidade. A classe Cidade tem uma
referência para Estado e a classe Estado tem uma referência para País. Agora suponhamos um outro bean
com um campo que faz referência à Cidade.
Para criar um combo de cidade na tela, poderiamos utilizar a tag t:property como no exemplo:
[JSP]
<t:property name="cidade"/>
Lembando que um property para uma classe que é uma entidade, é automaticamente um combo. O código
acima monta um combo com todas as cidades encontradas no banco.
Importante: Sempre que precisar utilizar combos no JSP é necessário criar um Servide e um DAO
para o bean em questão. O NEO só preenche as informações corretamente se existir um DAO para a entidade.
Para criar a dependencia entre as propriedades. Podemos aproveitar a propriedade estado de cidade, e a
propriedade pais de estado. Exemplo:
[JSP]
<t:property name="cidade.estado.pais"/>
<t:property name="cidade.estado"/>
<t:property name="cidade"/>
Agora temos 3 combos. Cada um com todos os resultados obtidos do banco de dados. Uma outra forma de
ter os três combos seria ter uma propriedade estado e pais no mesmo bean que possui a propriedade cidade.
Se o bean que possui a propriedade cidade for uma entidade (configurado com @Entity) e ele não possuir
chaves para estado e país deve ser colocada a anotação @Transient no getter de cada propriedade.
Tendo as 3 propriedade no mesmo bean o jsp ficaria dessa forma:
[JSP]
<t:property name="pais"/>
<t:property name="estado"/>
<t:property name="cidade"/>
Importante: A anotação @Transient indica para o hibernate que o campo não é persistido no banco de dados.
Verifique a documentação do Hibernate Annotations para mais informações.
Para indicar que os 3 combos são dependentes precisamos englobá-los na tag comboReloadGroup.
[JSP]
<n:comboReloadGroup>
<t:property name="cidade.estado.pais"/>
<t:property name="cidade.estado"/>
<t:property name="cidade"/>
</n:comboReloadGroup>
A tag comboReloadGroup vai efetuar um reload da tela para atualizar os combos. Se desejar que
essa funcionalidade seja feita via ajax é só utilizar a propriedade useAjax.
[JSP]
<n:comboReloadGroup useAjax="true">
<t:property name="cidade.estado.pais"/>
<t:property name="cidade.estado"/>
<t:property name="cidade"/>
</n:comboReloadGroup>
Quando utilizar a tag comboReloadGroup o método no DAO que será utilizado para fazer as pesquisas
será o findBy, mas é possível especificar outro método para as queries. Suponha que criamos o método
findCidadesHabilitadasByEstado que efetua uma determinada query e que recebe um parâmetro estado.
Para utilizar esse método no reload fazemos o seguinte:
[JSP]
<n:comboReloadGroup useAjax="true">
<t:property name="cidade.estado.pais"/>
<t:property name="cidade.estado"/>
<t:property name="cidade" itens="cidadeDAO.findCidadesHabilitadasByEstado(cidade.estado)"/>
</n:comboReloadGroup>
Os parâmetros da função da propriedade itens devem ser o nome de uma propriedade colocada na tela.
Se determinado bean possuir a propriedade X mas esse X não for colocado na tela, não será possível
utilizar uma função fazendo referência a X.
É possível passar mais de um parâmetro para a função em itens.