Carregando um combobox através via AJAX
O Exemplo
Considere que temos uma lista de cursos e que cada curso possui diversas turmas, que por sua vez possui alunos.
Para simular as lista de cursos utilizaremos o script abaixo com o nome de cursos:
cursos = [ {'id':'1','nome':'Matemática'}, {'id':'2','nome':'Português'}, {'id':'3','nome':'Física'} ] return cursos |
Para simular as turmas utilizaremos o script abaixo com o nome de turmas. Este script aceita dois parâmetro: id_curso e geraCombo=True.
turmas = [ {'id':'1', 'nome':'Turma A 1º Série', 'id_curso':'1'}, {'id':'2', 'nome':'Turma B 2º Série', 'id_curso':'1'}, {'id':'3', 'nome':'Turma A', 'id_curso':'2'}, {'id':'4', 'nome':'Turma B', 'id_curso':'2'}, {'id':'5', 'nome':'Turma C', 'id_curso':'3'}, {'id':'6', 'nome':'Turma A 1º Série', 'id_curso':'3'}, {'id':'7', 'nome':'Turma B', 'id_curso':'3'}, {'id':'8', 'nome':'Turma C', 'id_curso':'3'}, ] if id_curso: aux = [] for turma in turmas: if str(turma['id_curso']) == str(id_curso): aux += [turma,] turmas = aux if geraCombo: print "<select id='lstTurmas'><option></option>" for turma in turmas : print "<option value="+ turma['id']+">"+turma['nome']+"</option>" print "</select>" return printed return turmas |
Agora criaremos uma page template (listaTurmasPorCurso) com o código abaixo:
<html> <head> <title tal:content="template/title">The title</title> <script src="prototype.js"></script> <script> function ajaxComboBox(){ var id_curso = $F('lstCursos'); var url = 'turmas'; var pars = 'id_curso=' + id_curso; var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: mostraResposta }); } function mostraResposta(requisicaoOriginal) { //copia a combobox para o span $("resultado").innerHTML = requisicaoOriginal.responseText; } </script> </head> <body>
Cursos: <select id="lstCursos" onchange="ajaxComboBox()"> <option></option> <option tal:repeat="item here/cursos" tal:attributes="value python:item['id']" tal:content="python:item['nome']"></option> </select> <br/> Turmas: <span id="resultado"></span>
</body> </html> |
Com este código, cada vez que o usuário selecionar um curso será mostrado um combobox dentro da tag span resultado com todas as turmas do respectivo curso.
O mais importante a ser observado aqui é a utilização do objeto Ájax. Este possui o método Request, que faz uma chamada assíncrona a uma determinada url (serviço remoto). Este método recebe como parâmetro uma url e options. O parâmetro option nos possibilita informar qual será o método a ser utilizado na requisição (GET/POST); quais parâmetro devem ser enviados (parameters) e qual a função a ser chamada após completado a requisição (onComplete).
Obs.: Se consultarmos a documentação deste método encontraremos outros parâmetro que podem ser informados.
Melhorando o exemplo
Para melhorar nosso exemplo vamos fazer com que apareça na tela também uma lista de alunos conforma a turma selecionada. Para isto devemos acrescentar algumas coisinhas:
No script turmas, acrescente onchange=’listaAlunos()’ conforme se segui:
turmas = [ {'id':'1', 'nome':'Turma A 1º Série', 'id_curso':'1'}, {'id':'2', 'nome':'Turma B 2º Série', 'id_curso':'1'}, {'id':'3', 'nome':'Turma A', 'id_curso':'2'}, {'id':'4', 'nome':'Turma B', 'id_curso':'2'}, {'id':'5', 'nome':'Turma C', 'id_curso':'3'}, {'id':'6', 'nome':'Turma A 1º Série', 'id_curso':'3'}, {'id':'7', 'nome':'Turma B', 'id_curso':'3'}, {'id':'8', 'nome':'Turma C', 'id_curso':'3'}, ] if id_curso: aux = [] for turma in turmas: if str(turma['id_curso']) == str(id_curso): aux += [turma,] turmas = aux if geraCombo: print "<select id='lstTurmas' onchange='listaAlunos()'><option></option>" for turma in turmas : print "<option value="+ turma['id']+">"+turma['nome']+"</option>" print "</select>" return printed return turmas |
Crie o script alunos com o seguinte código:
alunos = [ {'id':'1', 'nome':'Alessandro', 'id_curso':'1', 'id_turma':'1'}, {'id':'2', 'nome':'Alessandra', 'id_curso':'1', 'id_turma':'1'}, {'id':'3', 'nome':'Maria', 'id_curso':'1', 'id_turma':'2'}, {'id':'4', 'nome':'João', 'id_curso':'1', 'id_turma':'2'}, {'id':'5', 'nome':'Carlos', 'id_curso':'2', 'id_turma':'3'}, {'id':'6', 'nome':'Geraldo', 'id_curso':'2', 'id_turma':'3'}, {'id':'7', 'nome':'Reuber', 'id_curso':'3', 'id_turma':'8'}, {'id':'8', 'nome':'Lailiana', 'id_curso':'3', 'id_turma':'8'}, {'id':'9', 'nome':'Aline', 'id_curso':'3', 'id_turma':'8'}, {'id':'10', 'nome':'Galdino', 'id_curso':'1', 'id_turma':'1'}, {'id':'11', 'nome':'Rafael', 'id_curso':'1', 'id_turma':'1'}, {'id':'12', 'nome':'Márcia Keila', 'id_curso':'2', 'id_turma':'4'}, {'id':'13', 'nome':'Priscila', 'id_curso':'2', 'id_turma':'4'}, {'id':'14', 'nome':'Bárbara Luíza', 'id_curso':'2', 'id_turma':'4'}, {'id':'15', 'nome':'Carlos', 'id_curso':'3', 'id_turma':'7'}, {'id':'16', 'nome':'Arthur', 'id_curso':'3', 'id_turma':'7'}, {'id':'17', 'nome':'Karlla', 'id_curso':'3', 'id_turma':'7'}, {'id':'18', 'nome':'Luciano', 'id_curso':'1', 'id_turma':'2'}, {'id':'19', 'nome':'Karl', 'id_curso':'1', 'id_turma':'2'}, {'id':'20', 'nome':'Eduardo', 'id_curso':'2', 'id_turma':'1'}, ] if id_curso: aux = [] for aluno in alunos : if str(aluno ['id_curso']) == str(id_curso): aux += [aluno,] alunos = aux if id_turma: aux = [] for aluno in alunos : if str(aluno['id_turma']) == str(id_turma): aux += [aluno ,] alunos = aux return alunos |
Este script recebe dois parâmetros: id_curso=None, id_turma=None.
Modifique agora o códidg da page template listaTurmasPorCuro conforme abaixo:
<html> <head> <title tal:content="template/title">The title</title> <script src="prototype.js"></script> <script> function ajaxComboBox(){ var id_curso = $F('lstCursos'); var url = 'turmas'; var pars = 'id_curso=' + id_curso; var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: mostraResposta }); } function mostraResposta(requisicaoOriginal) { //copia a combobox para o span $("resultado").innerHTML = requisicaoOriginal.responseText; $("lstAlunos").innerHTML = ""; } function listaAlunos() { var id_turma = $F('lstTurmas'); if (id_turma != ''){ var url = 'listaAlunos'; var pars = 'id_turma=' + id_turma;
var myAjax = new Ajax.Updater( {success: 'lstAlunos'}, url, { method: 'get', parameters: pars, onFailure: mostraErro }); }
} function mostraErro(request) { alert('Foi mal. Deu pau...'); } </script> </head> <body>
Cursos: <select id="lstCursos" onchange="ajaxComboBox()"> <option></option> <option tal:repeat="item here/cursos" tal:attributes="value python:item['id']" tal:content="python:item['nome']"></option> </select> <br/> Turmas: <span id="resultado"></span> <fieldset> <legend>Alunos</legend> <span id='lstAlunos'></span> </fieldset>
</body> </html> |
Desta vez, em vez de utilizarmos o método Ajax.Request utilizandos o Ájax.Updater.
Este método é parecido com o primeiro exceto pelo acréscimo do primeiro parâmetro:
{success: 'lstAlunos'} e do onFailure. O primeiro informa qual elemento (tag) receberá o resultado da requisição enquanto que o último diz qual método será chamado quando ocorrer um erro na chamada.
Conclusão
Como você pode ver, não é nenhum bicho de sete cabeças utilizarmos AJAX dentro do ZOPE.. Com este exemplo vimos mais uma vez como é fácil utilizarmos tecnologia AJAX deixando a página amigável para o usuário.