miércoles, 30 de enero de 2013

Limitar número de enteros y de decimales por Javascript

Hace poco he tenido que lidiar con un código demasiado manual, de modo que he tenido que echar mano de Javascript para meter una limitaciones en textbox (input), y no permitir la introducción de un número máximo de decimales y de enteros.
Por supuesto, googleando encontraba cosas, pero no terminaron de convercerme, así que con un poco de esto y otro de aquello, et voila:

La invocación, como siempre en el onkeypress:


1
<asp:TextBox ID="txtValidate" runat="server" onkeypress="return validateFloatKeyPress(this, event, 4, 6);"></asp:TextBox>


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/// <summary>
/// Validamos el número de enteros y decimales
/// </summary>
/// <param name="el">Elemento que lanza el método</param>
/// <param name="evt">Evneto</param>
/// <param name="ints">Número de enteros permitidos</param>
/// <param name="decimals">Número de decimales permitidos</param>
function validateFloatKeyPress(el, evt, ints, decimals) {

    // El punto lo cambiamos por la coma
    if (evt.keyCode == 46) {
        evt.keyCode = 44;
    }
    
    // Valores numéricos
    var charCode = (evt.which) ? evt.which : event.keyCode;
    if (charCode != 44 && charCode > 31
        && (charCode < 48 || charCode > 57)) {
        return false;
    }
    
    // Sólo una coma
    if (charCode == 44) {
        if (el.value.indexOf(",") !== -1) {
            return false;
        }

        return true;
    }

    // Determinamos si hay decimales o no
    if (el.value.indexOf(",") == -1) {
        // Si no hay decimales, directamente comprobamos que el número que hay ya supero el número de enteros permitidos
        if (el.value.length >= ints) {
            return false;
        }
    }
    else {

        // Damos el foco al elemento
        el.focus();

        // Para obtener la posición del cursor, obtenemos el rango de la selección vacía
        var oSel = document.selection.createRange();

        // Movemos el inicio de la selección a la posición 0
        oSel.moveStart('character', -el.value.length);

        // La posición de caret es la longitud de la selección
        iCaretPos = oSel.text.length;

        // Distancia que hay hasta la coma
        var dec = el.value.indexOf(",");

        // Si la posición es anterior a los decimales, el cursor está en la parte entera
        if (iCaretPos <= dec) {
            // Obtenemos la longitud que hay desde la posición 0 hasta la coma, y comparamos
            if (dec >= ints) {
                return false;
            }
        }
        else { // El cursor está en la parte decimal
            // Obtenemos la longitud de decimales (longitud total menos distancia hasta la coma menos el carácter coma)
            var numDecimals = el.value.length - dec - 1;
                
            if (numDecimals >= decimals) {
                return false;
            }
        }
    }
    
    return true;
}