quinta-feira, fevereiro 09, 2006

Aprofundando um pouco em Javascript

Javascript está ficando uma linguagem muito legal para programar (Quem sabe um dia chega ao modelo de programação do Ruby... Sonho), mas já começa a despertar as maneira de programas em forma de Orientação a Objetos com suas funcionalidades.

Já fiz diversas coisas com a utilização do Prototype e esta é outra que ajuda na formatação de números decimais. Devem haver diversos outros scripts que fazem a mesma coisa, mas gostei do meu, pois é o primeiro que eu realmente uso Javascript como OO.

A utilização ficou simples
<input onblur="Decimal.format(this, '3#0,00')" type="text" />

Coloquei na perda de foco do campo, mas pode ser colocado em outro lugar (vai da sua cabeça)

O modelo de padrão que estou utilizando é
3#0,00

Onde:
'3' é o número de campos opcionais a frente do primeiro 0
'#' é o símbolo de campos opcionais, se vier só ele a quantidade de opcionais é 1 o número na frente é seu multiplicador
'0,00' é o padrão que deve ser aplicado. Considero a utilização de um campo a frente, um separador que pode ser ',' ou '.' e a quantidade de casas decimais.
Alguns modelos:
entradapadrãoresultado
1230,001,23
123452#0,0123,4
123452#0,00123,45
12,34012#0,0012,34
12.56#0,0012,56
120,00#0.0012.00


Segue o código:
var Decimal = Class.create();
Decimal.format = function(field, pattern, notEmpty) {

if(field.value == "" && notEmpty) {
field.value = "0";
}

var decimal = new Decimal(field, pattern);
decimal.applyPattern();
}
Decimal.prototype = {
initialize: function(field, pattern) {
this.field = field;
this.pattern = pattern;
},

applyPattern: function() {

if(this.field.value == "") {
return;
}

var expressionPattern = new RegExp("([1-9]){0,1}(#){0,1}(0)([,\\.]{0,1})(0*)");
var expressionValue = new RegExp("([0-9]*)[,\\.]{0,1}([0-9]*)");

var resultPattern = expressionPattern.exec(this.pattern);
var resultValue = expressionValue.exec(this.field.value);

var separatorPosition = 0;
var result = "";

resultPattern[1] = !resultPattern[1] || resultPattern[1].length == 0 ? 1 : parseInt(resultPattern[1]);
resultPattern[2] = !resultPattern[2] || resultPattern[2].length == 0 ? 0 : 1;

var totalValue = (resultPattern[1] * resultPattern[2]) + 1;

if( (!resultValue[1] || resultValue[1].length == 0) && (!resultValue[2] || resultValue[2].length == 0) ) {
alert("Formato inválido para o número");
this.field.value = "";
return;
}

resultValue[1] = resultValue[1].length == 0 ? "0" : resultValue[1];


for(var i = 0; i < resultValue[1].length; i++) {
if (i == totalValue) {
separatorPosition = i;
result += resultPattern[4];
}

if (i < (totalValue + resultPattern[5].length)) {
result += resultValue[1].charAt(i);
}
}

if(result.length <= totalValue) {
separatorPosition = result.length;
result += resultPattern[4];
}

var j = 0;
for(var i = separatorPosition; i <= (separatorPosition + resultPattern[5].length);i++) {
if(result.length <= (separatorPosition + resultPattern[5].length) ) {
var eachValue = resultValue[2].charAt(j++)
if(eachValue && eachValue != "") {
result += eachValue;
} else {
result += "0";
}
}
}

this.field.value = result;
}
}


Ainda não fiz testes completos, mas está funcionando até o ponto que testei, se pintar algum problemas posto a correção aqui. :D

Nenhum comentário: