Dojo faz de a criação de widgets um processo muito simples e rápido. Nesse tutorial demonstrarei os passos necessários para criar dos widgets utilizando conceitos de herança para o reaproveitamento do código. A versão do Dojo utilizada será a 0.9.0beta.
Dos inputs bem comuns na criação de aplicações web são datas e números inteiros. O HTML não tem suporte pra tais tipos de input, pelo que temos que utilizar um de tipo texto e aplicar nele certas funções que nos ajudem a restringir valores no campo e/ou validar ele. Não seria bem melhor si o HTML tivesse inputs de tipo data e número inteiro, que tenham suas obrigações encapsuladas e assim não tenhamos que nos preocupar na hora de desenhar a página? A boa noticia é que a especificação do HTML 5 promete oferecer tais componentes e muitos mais, mas a noticia ruim é que ainda vai levar um tempo. Para nossa fortuna, podemos criar widgets personalizados que nos ajudem a satisfazer nossas necessidades.
Criaremos então dois widgets, um pra inputs de datas e outro pra inputs de números inteiros. Pelo fato dos dois serem inputs, eles vão ter o mesmo desenho e algumas propriedades (value, size, maxlength,…) e métodos (focus, getValue, setValue, …) em comum, pelo que serão herdeiros do mesmo widget. O sistema de widgets do Dojo (Dijit) possui dentro de seu pacote dijit.form um widget com tais características (dijit.form.TextBox), que foi criado com a intenção de servir como classe base para outros widgets com finalidades mais especificas, como os dois que estamos por criar. Como nossos widgets serão herdeiros do TextBox, chamaremos eles de DateTextBox e IntegerTextBox, seguindo algumas práticas de programação.
Antes de começar a programar, nossa estrutura das pastas devera ficar do seguinte modo:
raiz
dojo.0.9.0beta
dijit …
dojo …
dojox …
mos
widget
form
DateTextBox.js
IntegerTextBox.js
themes
whitie
whitie.css
util …
TextBox.html
Editaremos primeiro o arquivo DateTextBox.js, o código dele completo é:
if (!dojo._hasResource["mos.widget.form.DateTextBox"]) {
dojo._hasResource["mos.widget.form.DateTextBox"] = true;
dojo.provide("mos.widget.form.DateTextBox");
dojo.require("dijit.form.Textbox");
dojo.declare(
"mos.widget.form.DateTextBox",
dijit.form.Textbox,
{
maxlength: 10,
size: 7,
onkeyup: function() {
var value = this.getValue();
switch (value.length) {
case 2 :
case 5 :
this.setValue(value + "/");
break;
}
}
}
);
}
A primeira instrução verifica si o package foi carregado no cache anteriormente. Caso não tinha sido carregado, procede. Essa verificação serve pra evitar duplo processamento e melhorar a performance. A terceira instrução define o nome do package e a seguinte carrega o package passado como parâmetro (dojo.dijit.TextBox). dojo.declare declara nosso widget e recebe três parâmetros: o nome do nosso widget, o nome do widget qual estamos herdando e a classe do nosso widget (propriedades e métodos).
Sabemos que as datas no formato dd/mm/yyyy possuem somente dez caracteres, pelo que nossa propriedade maxlength terá aquele valor e o size será 7, de modo que nosso TextBox não fique muito grande. Para que o tutorial não fique muito grande e complicado, faremos uma implementação simples no método onkeyup. Posteriormente poderíamos melhorar nosso widget validando o valor no evento onblur e/ou onchange.
Seguiremos agora com o IntegerTextBox. O código dele e muito similar ao do DateTextBox, com a diferença que não implementaremos o evento onkeyup mas sim o onblur. No evento onblur, substituiremos o valor atual por um valor válido, filtrando os caracteres inválidos. Esse filtro será realizado no método parse, que é chamado desde o método getValue, definido no dijit.form.TextBox. Nosso IntegerTextBox fica de seguinte maneira:
if (!dojo._hasResource["mos.widget.form.IntegerTextBox"]) {
dojo._hasResource["mos.widget.form.IntegerTextBox"] = true;
dojo.provide("mos.widget.form.IntegerTextBox");
dojo.require("dijit.form.Textbox");
dojo.declare(
"mos.widget.form.IntegerTextBox",
dijit.form.Textbox,
{
onblur: function() {
this.setValue(this.getValue());
},
parse: function(value) {
return value.replace(/\D/g, "");
}
}
);
}
Continuaremos com nossa pagina, chamada nessa caso de TextBox.html:
TextBox
DateTextBox
IntegerTextBox
Nosso arquivo HTML é bem simples, importamos nosso arquivo com os estilos (whitie.css) e o core do Dojo (dojo.js). djConfig é uma propriedade que é tomada em conta na hora de carregar o core do Dojo para saber qual atitudes tomar. Nesse caso estamos indicando que desejamos que o Dojo procure widgets no momento de carregar e que no caso de algum erro, faça um debug dele. Notem também que importamos o package dojo.parser. O dojo.parser é encarregado de converter nodos em formato JSON para assim serem interpretados na criação dos widgets. Para inserir widgets no nosso código, basta com adicionar a propriedade dojoType, com o nome completo do widget como valor, num elemento qualquer.
A página pode ser testada aqui, ou tanbem podem descarregar os arquivos, incluindo o Dojo, de aqui, para assim ser testado no ambiente local.
Depois de analizar o resultado, muitas pessoas devem se perguntar como aquele div chegou a ser um input e com aquele estilo. Explicarei um pouco o processo a continuação.
Ao carregar o core do Dojo, ele lê o valor da propriedade parseOnLoad e ao ser verdadeira, começa a recorrer todos os nodos do nosso documento em procura da propriedade dojoType. Ao achar um elemento com a propriedade dojoType, o parser entra em ação e converte aquele nodo num objeto, que substitui os valores da classe do widget pelos especificados no nodo. No caso do nossos widgets, eles herdaram todas as propriedades e métodos do dijit.form.TextBox e dando uma olhada na declaração dele, encontramos a propriedade templateString. O valor dela e um código HTML:
Nosso nodo é substituido por aquele codigo HTML. dojoAttachPoint serve para conectar os valores separados por ; a uma propriedade da classe. Nesse caso temos como valores textbox e focusNode. Si em algum momento da nossa classe utilizamos this.textbox, estaremos referenciando o elemento HTML com o valor textbox na propriedade dojoAttachPoint, um elemento de tipo input no nosso caso. Todos os widgets que herdam de dijit.form._FormWidget, como dijit.form.TextBox, possuem um método chamado focus que serve, obviamente, para dar focus no widget. Nesse caso o template de nosso widget é composto por somente um elemento, mas poderia ser por n elementos, de diferentes tipos. O valor focusNode funciona como indicador de que aquele elemento recebera o focus quando for chamado o evento, pelo que somente um elemento vai poder ter aquele valor. dojoAttachEvent identifica os eventos que estarão ativos e ${propriedade} é substituído pelo valor da propriedade especificada, no momento de converter o nodo num widget. E importante tanbem mencionar que si nosso template fosse muito grande, podriamos incluir ele num arquivo e referenciar o arquivo mediante a propiedade templatePath.
Com um pouco de criatividade, podem se criar widgets muito eficientes que ajudem a encapsular e centralizar métodos e propriedades, reduzir o código e assim tornar ele mais limpo e menos propicio a erros, como também mais fácil de ser mantido e refactorado no futuro.
2 respostas ate agora ↓
1 Samyr Pereira // Dec 30, 2007 at 6:34 pm
Desculpe meu despreparo, mas para confirmar; depois de pesquisar pela internet me parece que para criar um widget só usando classes como o DOJo ou UWA, (seria correto chama-las de framework?). Eu não poderia criar minhas proprias classes ou isso resultaria em um código muito grande e complexo?
Obrigado e um abraço
2 Diego Carrion // Jan 1, 2008 at 7:04 am
Samyr, você pode sim.
No artigo eu criei duas classe chamadas DateTextBox e IntegerTextBox que herdan de uma classe própria do Dojo: TextBox.
São classes pequena mas da para obter uma idéia do simples que é.
Qualquer dúvida é somente avisar.
Deixar um comentário