Foro

Ext.ux.MoneyField

0
Saludos, Me puse a buscar alguna clase que sirviera para formatear cantidades monetarias. Mi sorpresa es que no logré encontrar una lo suficientemente estándar que me sirviera y las que encontraba estaban pensadas para el uso del dólar; por tanto me decidí a crear mi MoneyField que formateara por defecto la moneda del euro (separador de millares con puntos, de decimales con coma, el símbolo del euro, etcétera) pero que fuese lo suficientemente general como para adaptarla a cualquier moneda. En el foro general encontré un método bastante bueno. utilizando ese método he creado una clase; pero como mi dominio de extjs es bastante bajo busco sugerencias o ayuda para crear este componente definitivo. La idea es que por un lado tenga la cantidad con el formato visible (en el value) y otro campo oculto que mantenga la cantidad sin formatear. La idea es que heredando de NumberField fueran suficiente todas las validaciones que ésta ya hace por defecto y lo único que variara es a la hora de mostrar la cantidad formateada. Como siempre en programación una cosa es tener una idea sencilla y clara de lo que hay que hacer y otra cosa es que implementarlo sea sencillo. Ahora mismo la clase funciona casi bien si no fuera porque cuando pierde el foco se formatea. La primera vez funciona correctamente; pero si recupera el foco el campo una vez se había introducido el número lo vuelve a formatear. Seguro que me podéis echar una mano para finalizarlo. archivo: MoneyField.js
/**
 * 
 * @author anonimous
 * @version Beta (diciembre 2010)
 * @description clase de  formateo de monedas
 * @class Ext.ux.form.MoneyField
 * @extends Ext.form.NumberField
 * 
 *Pendiente:
 * 1. corregir corregir el onblur una vez que está  formateado la cantidad (elimina los puntos de los millares) 
 * 2. indicar estilo verde si numero >=0 o rojo si numero < 0
 */
  
Ext.namespace('Ext.ux');
Ext.ux.form.MoneyField = Ext.extend(Ext.form.NumberField, { //¿heredar de TextField o NumberField gran dilema...?
	moneySymbol: "\u20ac",	  //moneda euro
	decimalSeparator: ",",	  //separador decimales
	thousandSeparator: ".",	  //separador millares
	hasSpace: true,    	  	  //indicamos si hay un espacio entre la moneda y la cantidad.(boolean)
	leftPosition: false,  	  //colocar el símbolo de moneda a la izquierda si "true"; derecha si "false"
//	decimalPrecision : 2,     //decimal precision (numberfield)
//	allowNegative : false,     // (numberfield)
	applyStyle: false,        //Si queremos visualizar estilo verde cuando >=0 o rojo  cuando <0 (sin implementar)		
	noFormatValue: null,	      //valor de la cantidad sin formato
	style: 'text-align: right',
	
	baseChars : "0123456789",  //(numberfield)
	
	setValue : function(n){
		
		//importe sin formatear
		this.noFormatValue = n;
//		this.noFormatValue = this.noFormatValue==null? n : this.noFormatValue;
				
		var spaceText = this.hasSpace?" ":"";
		
		var m = /(\d+)(?:(\.\d+)|)/.exec(n + ""),
        x = m[1].length > 3 ? m[1].length % 3 : 0;
        var v = (n < 0? '-' : '') // preserve minus sign
        + (x ? m[1].substr(0, x) + this.thousandSeparator : "")
        + m[1].substr(x).replace(/(\d{3})(?=\d)/g, "$1" + this.thousandSeparator)
        + (this.decimalPrecision? this.decimalSeparator + (+m[2] || 0).toFixed(this.decimalPrecision).substr(2) : "");
		console.debug("valor formateado sin moneda:" + v);
//        this.noFormatValue = v;
		
        this.value = this.leftPosition?this.moneySymbol+spaceText+v:v+spaceText+this.moneySymbol;
        console.debug("valor formateado con moneda:" + this.value);
//        Ext.ux.form.MoneyField.superclass.setValue.call(this.value); //(??? no funciona!)
        if(this.rendered){
            this.el.dom.value = (Ext.isEmpty(this.value) ? '' : this.value);
            this.validate();
        }
       
		return this;
	},
	
	//al recuperar el valor nos interesa que esté sin formatear.
	getNoFormatValue: function(){		
		return this.noFormatValue; 
	},
	
	//se valida la cantidad sin formato (sin millares ni moneda)
	//sobreescribir este método o  validatevalue??
	validate : function(){
        if(this.disabled || this.validateValue(this.processValue(this.getNoFormatValue()))){
            this.clearInvalid();
            return true;
        }
        return false;
    }
	
});
Ext.reg('moneyfield', Ext.ux.form.MoneyField);	
archivo: prueba.js
{
								xtype: 'moneyfield',
								id: 'moneda',
							     name:'moneda',							    
								fieldLabel: "moneyfield",
							    width: 200
}
0
Una primera versión beta. Se agradecen colaboraciones. *Pendiente: * 1. indicar estilo verde si numero >=0 o rojo si numero < 0 * 2. tooltip multiidomado indicando que solo pueden insertar números y una coma para millares. * 3. Si le ponemos comas delante del número no formatea bien. */ Ext.namespace('Ext.ux'); Ext.ux.form.MoneyField = Ext.extend(Ext.form.NumberField, { //¿heredar de TextField o NumberField gran dilema...? moneySymbol: "\u20ac", //moneda euro decimalSeparator: ",", //separador decimales thousandSeparator: ".", //separador millares hasSpace: true, //indicamos si hay un espacio entre la moneda y la cantidad.(boolean) leftPosition: false, //colocar el símbolo de moneda a la izquierda si "true"; derecha si "false" applyStyle: false, //Si queremos visualizar estilo verde cuando >=0 o rojo cuando 3 ? m[1].length % 3 : 0; var v = (n < 0? '-' : '') // preserve minus sign + (x ? m[1].substr(0, x) + this.thousandSeparator : "") + m[1].substr(x).replace(/(\d{3})(?=\d)/g, "$1" + this.thousandSeparator) + (this.decimalPrecision? this.decimalSeparator + (+m[2] || 0).toFixed(this.decimalPrecision).substr(2) : ""); console.debug("Valor formateado sin moneda:" + v); // this.noFormatValue = v; this.value = this.leftPosition?this.moneySymbol+spaceText+v:v+spaceText+this.moneySymbol; console.debug("Valor formateado con moneda:" + this.value); // Ext.ux.form.MoneyField.superclass.setValue.call(this.value); //(??? no funciona!) if(this.rendered){ this.el.dom.value = (Ext.isEmpty(this.value) ? '' : this.value); this.validate(); } return this; }, //al recuperar el valor nos interesa que esté sin formatear. getNoFormatValue: function(){ return this.noFormatValue; }, //se valida la cantidad sin formato (sin millares ni moneda) //sobreescribir este método o validatevalue?? validate : function(){ if(this.disabled || this.validateValue(this.processValue(this.getNoFormatValue()))){ this.clearInvalid(); return true; } return false; }, //recibe elfoco reseteamos valores. onFocus: function(foco){ this.value=""; this.noFormatValue=""; if(this.rendered){ this.el.dom.value =""; } }, //llama al método de comunes-3.js y no se tiene que volver a llamar al setvalue. trim: function () { // if((typeof this.getValue())=='string') // this.setValue(this.getValue().replace(/^\s+|\s+$/g,"")); } }); Ext.reg('moneyfield', Ext.ux.form.MoneyField); /** * Función de formateo. */ //Extraído de: http://www.sencha.com/forum/showthread.php?5499-Other-currency-formats-other-than-usMoney/page3 //adaptado para que por defecto reconozca el formato euro /** * @param hasSpace Booleano que indica si quiere que dejemos un espacio entre la cantidad y la moneda * @param dp (decimal precision):Número que indica la cantidad de decimales a mostrar * @param dSeparator (decimal separator): caracter separador de decimales * @param tSeparator (thousand separator): separador de millares * @param symbol moneda que vamos a mostrar * @param leftPosition Booleano que indica si queremos visualizar la moneda a la izquierda. */ if (Ext.util.Format) { if (!Ext.util.Format.CurrencyFactory) { Ext.util.Format.CurrencyFactory = function(hasSpace, dp, dSeparator, tSeparator, symbol, leftPosition) { return function(n) { var spaceText = hasSpace?" ":""; dp = Math.abs(dp) + 1 ? dp : 2; dSeparator = dSeparator || ","; tSeparator = tSeparator || "."; symbol = symbol || "\u20ac"; leftPosition = leftPosition || false; var m = /(\d+)(?:(\.\d+)|)/.exec(n + ""), x = m[1].length > 3 ? m[1].length % 3 : 0; var v = (n < 0? '-' : '') // preserve minus sign + (x ? m[1].substr(0, x) + tSeparator : "") + m[1].substr(x).replace(/(\d{3})(?=\d)/g, "$1" + tSeparator) + (dp? dSeparator + (+m[2] || 0).toFixed(dp).substr(2) : ""); return leftPosition?symbol+spaceText+v:v+spaceText+symbol; }; }; } } // EJEMPLOS DE USO //Código de monedas (Unicode Representation) //libra inglesa \u00A3 //yen japonés \u00A5 //formato euro con espacio entre cantidad y moneda // var eurFormatter = Ext.util.Format.CurrencyFactory(true); // var value = 12345.67; // var resultado = eurFormatter(value); //dolar americano // var usaFormatter = Ext.util.Format.CurrencyFactory(false,2, ".", ",", "\u0024", true); // var value = 12345.67; // var resultado = usaFormatter(value);

¿Conoces a alguien que pueda responder esta pregunta? Comparte el link en Twitter o Facebook

Es necesario registrarse para poder participar en el foro! Si ya tienes una cuenta puedes entrar y comentar en este foro.