Foros del Web » Programando para Internet » Javascript »

Alinear números decimales .

Estas en el tema de Alinear números decimales . en el foro de Javascript en Foros del Web. Hola Foro : Tiempo atrás leí un tema donde alguien preguntaba cómo invertir la escritura en un input . Estaba tratando de encolumnarlos como sumandos ...
  #1 (permalink)  
Antiguo 20/02/2006, 12:12
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 22 años
Puntos: 317
Pregunta Alinear números decimales .

Hola Foro :

Tiempo atrás leí un tema donde alguien preguntaba cómo invertir la escritura en un input. Estaba tratando de encolumnarlos como sumandos y lo que necesitaba era que los números fueran apareciendo desde la derecha, para que se viera más prolijo.

Por supuesto que lo que estaba pidiendo era un text-align:right, algo repetido por todo el Foro y en montones de tutoriales; así que dejé ir la pregunta para no tener que decirle esto mismo de mala manera.

Días después caí en un detalle que se me había pasado (y a quien hizo la pregunta también) : ¿cómo alineamos los decimales?. Se supone que hay que encolumnar los puntos o comas, por lo que un left o right o center con respecto al largo de la cadena no sirve.

Apretando hasta la última sinapsis evoque una recomendación para HTML 4.0 que hubiera permitido el efecto, pero jamás se implementó. Sin embargo, sí apareció algo en CSS, y lo encontré justa antes de empezar a trabajar en un escript de alineación.

Código:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title></title>
<style>
td { text-align: "." }

</style>
</head>
<body>
<table border="1">
<col width="300">
<tr><th>Titulo</th></tr>
<tr><td> 0.75</td></tr>
<tr><td> 2.52</td></tr>
<tr><td> 33.33</td></tr>
<tr><td> 111.11</td></tr>
<tr><td> 91.</td></tr>
<tr><td> 91</td></tr>
<tr><td> .2</td></tr>
</table>

</body>
</html>
La pregunta es : ¿funciona en algún navegador?

Y si no : ¿está previsto que lo haga? ¿existe hoy algún código (seguramente propietario) que permita alinear por un caracter?
¿O me pongo a trabajar en el escript?
  #2 (permalink)  
Antiguo 13/03/2006, 16:09
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 22 años
Puntos: 317
Bien. Como de los -hasta la fecha- 40 visitantes al tema nadie me respondió, voy a asumir que no funciona en ninguno de los navegadores más comunes.
Y después de hacer varias pruebas con diferentes métodos, voy a asumir que nunca lo hará.

Dije más arriba que hubo una propuesta de agregarlo al HTML, y más tarde pude recordar que no se aplicaba a una tabla sino a un pre , lo que resulta perfectamente lógico : es un contenedor que por omisión usa fuente de ancho fijo y no ajusta las líneas de texto ni salta sin un break.

Y es que con encolumnar los puntos decimales no alcanza, porque los números no se van a mantener encolumnados -por supuesto, tienen todos distinto ancho- así que lo mejor es escribirlos usando una fuente monospace. Por otro lado, los números van alineados a la derecha, y recién después alineamos los puntos.
Ninguna de estas 2 condiciones está implícita en text-align: ".", especialmente la segunda, ya que nos impide usar text-align: right en la misma celda.

Pero volvamos al principio y veamos qué pasa con los input's.

Aquí tenemos un problema adicional, y es que son editables y nos obligan a hacer ajustes con cada cambio en los valores. También tenemos que saber si lo que ingresan es un número; y si no, poner un aviso, convertirlo a "0" (cero) o darle un tratamiento como string.

Es practicamente imposible poner padding o márgenes dentro de una caja de texto, así que lo único que se me ocurrió es usar una monospace y rellenar con espacios a la derecha hasta que los puntos queden encolumnados.

El ejemploes un beta; es decir, que ya funciona, pero hay que terminar de pulirlo y corregir algún bug (el más grave es el que tiene la conversión a número, ya que paseFloat() pone un límite a la cantidad de dígitos y si nos pasamos los corta)

Código:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<title>CENTRA PUNTO DECIMAL EN INPUTS. </title>
<script type="text/javascript">
var contenidos , relleno , decimales , anchoDecimales, valores, anchoDecimalesMax;
var anchoNumerosMax = 0;
relleno = new Array();

function centra(){
anchoDecimalesMax = 0;
contenidos = new Array();
decimales = "";
decimales = new Array();

/*IDENTIFICA LOS INPUT NOMBRE "centrado"*/
valores = document.formulario.centrado;
//alert(valores.length)

for(c=0; c<valores.length; c++){

/*IDENTIFICA TEXTO O NÚMEROS EN CADA INPUT Y LOS AJUSTA ELIMINANDO CEROS DE MÁS*/
valores[c].value = (parseFloat(valores[c].value) == valores[c].value*1) ? parseFloat(valores[c].value) : valores[c].value;

//alert(valores[c].value)
//alert(parseFloat(valores[c].value))
//alert(valores[c].value*1)

	/*ARMA UN ARRAY "contenidos" CON TODOS LOS VALORES*/
contenidos[c] = valores[c].value;
//alert("contenidos = "+contenidos)
}


for(c=0; c<valores.length; c++){
	/*SI EL VALOR DEL "contenidos" ES UN NÚMERO Y TIENE PUNTO DECIMAL ...*/
if((contenidos[c]*1 == contenidos[c]) && (contenidos[c].indexOf(".") != -1)){
	/*...MIDE LA CANTIDAD DE DECIMALES QUE QUEDARÁN A LA DERECHA DEL PUNTO Y LA GUARDA EN ARRAY "decimales". COMPARA LA CANTIDAD CON "anchoDecimales" PARA SABER SI ES MAYOR...*/

decimales[c] = contenidos[c].substring( contenidos[c].lastIndexOf(".") ).length;

anchoDecimalesMax = (decimales[c] > anchoDecimalesMax) ? decimales[c] : anchoDecimalesMax;

//alert("Nro. con punto. (decimales "+c+")=" +decimales+ " \r\n anchoDecimalesMax" +[c]+ " = "+anchoDecimalesMax)

valores[c].style.textAlign = "right";
}

else if( (contenidos[c]*1 == contenidos[c]) && contenidos[c].indexOf(".") == -1 && contenidos[c] != ""){
	/*...SI EL VALOR DEL "contenidos" ES UN NÚMERO ENTERO SIN PUNTO DECIMAL ASIGNA AL ARRAY Y A LA REFERENCIA UN VALOR DE "0" DECIMALES*/

decimales[c] = 0;
anchoDecimalesMax = (decimales[c] > anchoDecimalesMax) ? decimales[c] : anchoDecimalesMax;

//alert("Nro. sin punto. (decimales "+c+")=" +decimales+ "\r\n anchoDecimalesMax" +[c]+ " = "+anchoDecimalesMax)

valores[c].style.textAlign = "right";
}

else {
	/*...SI EL VALOR DE "contenidos" ES UN TEXTO ASIGNA AL ARRAY Y A LA REFERENCIA UN VALOR "-1"...*/

decimales[c] = -1;
anchoDecimalesMax = (decimales[c] > anchoDecimalesMax) ? decimales[c] : anchoDecimalesMax;

//alert("texto (anchoDecimales "+c+")=" +anchoDecimales+ " \r\n anchoDecimalesMax" +[c]+ " = "+anchoDecimalesMax)

valores[c].style.textAlign = "left";
}

}
//alert("anchoDecimalesMax = "+anchoDecimalesMax);
//alert("decimales = "+decimales);


for(c=0; c<valores.length; c++){

//alert("decimales"+[c]+" = " +decimales[c])

	/*VACÍA EL ARRAY "relleno" PARA CADA VALOR*/

relleno[c] = "";

if(decimales[c] != -1){
	/*SI NO ES TEXTO...*/

while(decimales[c] < anchoDecimalesMax){
	/*...MIENTRAS LOS DECIMALES DEL VALOR SEN MENOS QUE LOS DEL VALOR MÁS GRANDE, SE RELLENAN CON ESPACIOS A LA DERECHA...*/
decimales[c]++;
relleno[c] = relleno[c] + " ";
}
//alert(c+" "+decimales[c]+" numero")
}
else{
	/*... Y SI ES TEXTO NO SE RELLENA*/

relleno[c] = "";
//alert(c+" "+decimales[c]+" texto o nada")
}
valores[c].value += relleno[c];

//alert("relleno"+[c]+" = |" +relleno[c]+ "|")
}


for(c=0; c<valores.length; c++){
	/*DESPUÉS DE AGREGADO EL RELLENO, SE RECALCULA EL NUEVO ANCHO MÁXIMO DE LOS VALORES...*/

anchoNumerosMax = (valores[c].value.length > anchoNumerosMax) ?  valores[c].value.length : anchoNumerosMax;
valores[c].size = "1";
}
//alert("anchoNumerosMax = "+anchoNumerosMax)

for(c=0; c<valores.length; c++){
	/*...Y SE ASIGNA COMO ATRIBUTO size A LOS INPUT*/

valores[c].size = anchoNumerosMax;
}

}

//onload = centra;

</script>

<style type='text/css'>

.centraPunto{text-align:right; font:bold 16px monospace; }

.negativo {color:#ff0000; }

</style>
</head>
<body>

<form name="formulario">
0 <input type=text value="123456789012345.6" name=centrado class=centraPunto size="" onblur="centra()">
<br>
1 <input type=text value="12.345" name=centrado class=centraPunto size="" onblur="centra()" >
<br>
2 <input type=text value="-123.45" name=centrado class="centraPunto negativo" size="" onblur="centra()" >
<br>
3 <input type=text value="12345" name=centrado class=centraPunto size="" onblur="centra()" >
<br>
4 <input type=text value="Texto" name=centrado class=centraPunto size="" onblur="centra()" >
<br>
5 <input type=text value=".12345" name=centrado class=centraPunto size="" onblur="centra()" >
<br>
6 <input type=text value="1.2345" name=centrado class=centraPunto size="" onblur="centra()" >
<br>
<input type=reset value="RESET">

</form>
<p>
<input type=button onclick="centra(); this.disabled=true" value="CENTRA PUNTO DECIMAL">
</p>

</body>
</html>
Tengo hechas 3 versiones para tabla; la primera -la que mejor funcionaba- era incompatible con Firefox y seguramente con algún otro; las demás andan en IE / FF, pero creo que puedo hacer una cuarta, más limpia y parecida a la de los input's.
  #3 (permalink)  
Antiguo 23/03/2006, 11:39
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 22 años
Puntos: 317
Más arriba comenté que para dejar los números bien encolumnados era necesaria una fuente monospace. sin embargo, la mayoría de los diseñadores crean sus tipografías tratando de hacer a los números del mismo ancho, justamennte para facilitar el encolumnado.

Aún así, ésto no vale para las fuentes sicopatonas, hand-writing o diseñadores desprolijos; por lo que el siguiente ejemplo de tabla alínea los puntos independientemente de la fuente utilizada y de lo que ocurra con los dígitos.

Código:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<title>CENTRA PUNTO DECIMAL EN COLUMNAS. </title>
<script type="text/javascript">


var clasesCentradas = ["centraPunto0","centraPunto1"];	/*NOMBRES DE CLASE EN CADA COLUMNA*/

function centra(){
alert("Tabla original.");
//alert("Total clasesCentradas = "+clasesCentradas.length)

var contenidos = new Array();
var contenidosPunteados = new Array();
var enteros = new Array();
var decimales = new Array();
var anchoEnteros = new Array();
var anchoDecimales = new Array();
var anchoEnterosMax = 0;
var anchoDecimalesMax = 0;
var inicioCentrado = 0;

var celdas = document.getElementById("alineadas").getElementsByTagName("td").length;
//alert(celdas)
/*CUENTA EL TOTAL DE CELDAS*/

for(t=0; t<clasesCentradas.length;t++){
//alert("clase = "+clasesCentradas[t])
/*REVISA TANTAS VECES COMO CLASES A CENTRAR EXISTAN*/

for(c=0; c<celdas; c++){
/*RECORRE TODAS LAS CELDAS*/

//alert("clase celda "+c+" = "+document.getElementById( "alineadas" ).getElementsByTagName( "td" )[c].className)

if(document.getElementById( "alineadas" ).getElementsByTagName( "td" )[c].className.indexOf(clasesCentradas[t]) != -1){
contenidos[inicioCentrado] = document.getElementById( "alineadas" ).getElementsByTagName( "td" )[c].innerHTML;

//alert("inicioCentrado = "+inicioCentrado+" \r\ncontenidos = "+contenidos)
/*SI LA CELDA TIENE CLASE A CENTAR, LEE EL CONTENIDO*/

contenidosPunteados[inicioCentrado] = c;
//alert("contenidosPunteados = "+contenidosPunteados.length)
/*...Y LO GUARDA EN ARRAY*/

inicioCentrado += 1;
}
}

var punteadasTotal = contenidosPunteados.length;
//alert(contenidos + "¬" + punteadasTotal)
/*TOTAL DE CELDAS A CENTRAR*/

for(c=0; c<punteadasTotal; c++){
contenidos[c] = (contenidos[c].indexOf(".")!=-1) ? contenidos[c] : contenidos[c] + ".";

var divide = contenidos[c].split(".");

//alert(divide);
/*SI NO TIENE PUNTO SE LO AGREGA Y DIVIDE PARTE ENTERA DE DECIMAL*/

var entero = divide[0]+".";
document.getElementById("dummy").innerHTML = entero;
anchoEnteros[c] = document.getElementById('dummy').offsetWidth;
anchoEnterosMax = (anchoEnteros[c]>anchoEnterosMax)? anchoEnteros[c] : anchoEnterosMax;

//alert("ancho entero "+c+"= "+anchoEnteros);

enteros[c] = entero;
/*LEE LA PARTE ENTERA, MIDE EL ANCHO, REGISTRA EL ANCHO MÁXIMO Y GUARDA LOS VALORES EN ARRAY*/

var decimal = divide[1];
document.getElementById("dummy").innerHTML = decimal;
anchoDecimales[c] = document.getElementById('dummy').offsetWidth;
anchoDecimalesMax = (anchoDecimales[c]>anchoDecimalesMax)? anchoDecimales[c] : anchoDecimalesMax;

//alert("ancho decimal "+c+"= "+anchoDecimales);

decimales[c] = decimal;
/*LEE LA PARTE DECIMAL, MIDE EL ANCHO, REGISTRA EL ANCHO MÁXIMO Y GUARDA LOS VALORES EN ARRAY*/
}

document.getElementById("dummy").innerHTML = "_";

for(c=0; c<punteadasTotal; c++){
var parteEntera = enteros[c];
var parteDecimal = decimal[c];

document.getElementById( "alineadas" ).getElementsByTagName( "td" )[contenidosPunteados[c]].innerHTML = 
"<div style='padding:0; background:yellow; margin-right:" +(anchoDecimalesMax - anchoDecimales[c])+ "px;'>" +enteros[c] + decimales[c]+ "</div>";
}
//alert(anchoEnterosMax)
//alert(anchoDecimalesMax)
/*REESCRIBE EL CONTENIDO DE CADA CELDA DENTRO DE UN div Y POSICIONA CON RESPECTO AL PUNTO DECIMAL*/

inicioCentrado = 0;
anchoEnterosMax = 0;
anchoDecimalesMax = 0;
}
//alert(enteros);
//alert(decimales);

}

onload = centra;
</script>

<style type='text/css'>
#alineadas {margin-top:50px;}

#alineadas td{padding:0; vertical-align:bottom; font:bold 16px arial , sans-serif; white-space:nowrap; }

.centraPunto0 , .centraPunto1{text-align:right; }

.negativo {color:#ff0000; }

#dummy {position:absolute; t¬op:-100px; left:0; padding:0; background-color:#cccccc; font:bold 16px arial , sans-serif; }
</style>
</head>
<body>
<span id="dummy">_</span>

<table border=1 id="alineadas">
<tbody>
<tr><td class="a">a</td>
<td class="centraPunto0">0</td>
<td class="centraPunto1">.1</td>
<td>z</td></tr>
<tr><td>a</td>
<td class="centraPunto0">123.456</td>
<td class="centraPunto1">32.1</td>
<td>z</td></tr>
<tr><td>a</td>
<td class="centraPunto0">12.1111111111111119</td>
<td class="centraPunto1 negativo">-4.321</td>
<td>z</td></tr>
<tr><td>a</td>
<td class="centraPunto0">1.0000000000000009</td>
<td class="centraPunto1">5.4321</td>
<td class="z">z</td></tr>
</td></tr></tbody>
</table>

</body>
</html>
Ahora lo más importante : ¿Cómo hago para pedir que lleven el tema al foro de javascript?. Ya no tiene nada que hacer en CSS...
  #4 (permalink)  
Antiguo 23/03/2006, 11:52
Avatar de JavierB
Colaborador
 
Fecha de Ingreso: febrero-2002
Ubicación: Madrid
Mensajes: 25.052
Antigüedad: 22 años, 9 meses
Puntos: 772
Hola furoya

Puedes enviar un MP al moderador del foro o esperar a que alguien (por ejemplo, yo) pulse en el triangulito de reportar mensaje y pida que lo muevan a JavaScript.

Saludos,
  #5 (permalink)  
Antiguo 26/03/2006, 09:12
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 22 años
Puntos: 317
Con razón ¡yo no puedo ver mis propios triangulitos!

Gracias!.
  #6 (permalink)  
Antiguo 15/10/2011, 08:24
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 22 años
Puntos: 317
Respuesta: Alinear números decimales .

Vuelvo acá porque estuve mirando el HTML 5 y sus variantes de input.
Resulta que type=number es para hacer un spin, pero no agrega mucho para los formatos de números en formularios, y éste asunto del encolumnado del punto decimal —como verán— ya es muy viejo para que no lo hayan solucionado de alguna forma.

Me puse a actualizar el código para los editables, pero no me tomé tanto trabajo como en el anterior, no cubre tantas posibilidades. Habría que esperar a que los desarrolladores de navegadores lo implementen por las suyas.
Igual, les dejo lo que tengo hecho hasta que me cansé y pisé la tierra : viendo los calendarios, paletas de colores, slidebars y hasta el espín que mencioné más arriba, que resolvieron tan fácil mientras nosotros nos matábamos para conseguirlos con JS, CSS y HTML, ni en broma me voy a poner a mejorarlo. (¡Y encima que éste no anda en Chrome!)

Código HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>AJUSTA DECIMALES.</title>
<script type="text/javascript">

var anchoNum, columna, totInputs, totDecNum1, cadaInput;
var maxDec = 0;
var vuelta = 0;

function inicia() {
anchoNum = document.getElementById("muestra").offsetWidth / 2;
ajusta();
}


function ajusta(){

columna = document.getElementById("lista0");

totInputs = columna.getElementsByTagName("input").length;

for (i=0; i<totInputs; i++) {
var vInput = columna.getElementsByTagName("input")[i].value;

if(vInput.indexOf(".") == -1) {vInput = vInput + ".";}

columna.getElementsByTagName("input")[i].value = vInput;

var cortaNum = vInput.split(".");
var totDecNum0 = (cortaNum != "") ? cortaNum[1].length : 0;

maxDec = (maxDec < totDecNum0) ? totDecNum0 : maxDec;


cadaInput = columna.getElementsByTagName("input")[i];

if(cadaInput.value != ".") {
totDecNum1 = cadaInput.value.split(".")[1].length;

//alert("maxDec "+maxDec+"; "+totDecNum1+" decim en input "+i)

var espaciado = (maxDec - totDecNum1) * anchoNum;

//alert("maxDec "+maxDec+" - cant decimales "+totDecNum1+" * "+ anchoNum +"="+ espaciado +"px de padding en input" +i)

cadaInput.style.paddingRight = espaciado +"px";
cadaInput.style.width = 140 - espaciado +"px";
cadaInput.value = cadaInput.value;
}

else {
cadaInput.value = "";
//alert(i+" vacio");
}

}
/* LAS SIGUIENTES LINEAS SON PARA QUE EL ESCRIPT DE "2 VUELTAS" */
if(vuelta == 0){
vuelta = 1;
setTimeout(ajusta, 10);
}
else{
vuelta = 0;
maxDec = 0;
}

}

onload = inicia;
</script>
<style type="text/css">
#lista0 { border: red 2px solid; width: 144px; }

.punto { height: 18px; width: 140px; text-align: right; 
font: 14px/14px arial, helvetica, sans-serif; 
overflow: hidden; }

#muestra { font: 14px/14px arial, helvetica, sans-serif; 
position: absolute; left: 0; top: -50px; }

.punto:focus { background-color: lime; }
</style>
</head>
<body>

<div id=lista0>

<span id=muestra>00</span>
<input type=text maxlength=9 class=punto onchange=ajusta()><br>
<input type=text maxlength=9 class=punto onchange=ajusta()><br>
<input type=text maxlength=9 class=punto onchange=ajusta()><br>
<input type=text maxlength=9 class=punto onchange=ajusta()><br>
<input type=text maxlength=9 class=punto onchange=ajusta()><br>
<input type=text maxlength=9 class=punto onchange=ajusta()><br>

</div>

</body>
</html> 

Cómo se llama este componente?

slidebar / trackbar en html

Cambio de tamaño del colorwheel

Fechas (externo)

Fechas y horas (manejo de tiempo) (externo)

Etiquetas: alineacion, columna, decimal, encolumnar, input, numero, punto, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 20:04.