Dynamic Javascript date mask

Asked

Viewed 535 times

2

Recently I had to perform a mask for dates with automatic filling, I searched a lot and did not find answers that solved my doubts.

When typing '4' in the first field, the '0' should already be inserted and so on.

Well, I was able to come up with a code that met my needs, however, I think I may have gotten a little confused/extensive.

You would have some hint, idea, to optimize this code?

I hope the code can help anyone who needs it. Thank you for your attention!

var before = "  /  /    ";
var cont = true;
var copied = false;

//A máscara realiza comparações de "antes" e "depois" no keydown e //keyup

function beforeDate(field, e) {
    var start = field.selectionStart;
    var end = field.selectionEnd;
    var key = e || window.event;
    key = key.keyCode;

//Ações de ctrl+V, C ou X
  
    var ctrl = e.ctrlKey ? e.ctrlKey : ((key === 17) ? true : false); // ctrl detection
    if (((key == 86) || (key == 65) || (key == 67) || (key == 88)) && ctrl) {
        if (key == 86 || key == 88) {
            copied = true;
        }
        createSelection(field, 0, 10);
        return;
    }

  //Caso o usuário tenha selecionado parte da data
  //Preserva as barras e espaços
  
    if (start != end) {
        if ((key >= 48 && key <= 57) || (key >= 96 && key <= 105) || key == 8 || key == 46 || key == 32 || (key == 86 && ctrl) || (key == 67 && ctrl)) {
            for (var i = start; i < end; i++) {
                if (field.value.charAt(i) != "/") {
                    field.value = field.value.substring(0, i) + " " + field.value.substring(i + 1, 10);
                }
            }
            before = field.value;
            createSelection(field, field.value.indexOf(" "), field.value.indexOf(" "));
            return false;
        } else if (key >= 37 && key <= 40) {
            return true;
        } else {
            return false;
        }
    }

  //Setas
  
    if (key >= 37 && key <= 40) {
        return true;
    } else if (key == 33) {
        createSelection(field, 0, 0);
        return;
    } else if (key == 34) {
        createSelection(field, field.value.length, field.value.length);
        return;
    } else if ((key >= 48 && key <= 57) || (key >= 96 && key <= 105) || key == 46) {
      //Executar a ação uma vez por tecla
        if (cont) {
            cont = false;
            if (field.value.charAt(2) != "/") {
                field.value = setCharAt(field.value, 2, "/");
            }
            if (field.value.charAt(5) != "/") {
                field.value = setCharAt(field.value, 5, "/");
            }
            createSelection(field, start, start);
            before = field.value;
            return;
        }
        return false;
    } else if (key == 8) {
      //Backspace pressionado
        if (start != 0) {
            if ((field.value.charAt(start - 1)) != "/") {
                before = field.value;
                field.value = setCharAt(field.value, start - 1, " ");
                createSelection(field, start - 1, start - 1);
                return false;
            } else {
                before = field.value;
                createSelection(field, start - 1, start - 1);
                return false;
            }
        }
    }
};

//Evento Keyup
function afterDate(field, e) {
    var key = e || window.event;
    key = key.keyCode;
    var after = field.value;
    var cursor = field.selectionStart;
    cont = true;

    //Caso o usuário tenha colado uma data
    if (copied) {
        putMaskAgain(field);
        copied = false;
    }

    if (!((key >= 48 && key <= 57) || (key >= 96 && key <= 105) || key == 46)) {
        return false;
    } else {
        if ((key >= 48 && key <= 57) || (key >= 96 && key <= 105)) {
            if (key >= 96) {
                key -= 48;
            }
            var char = String.fromCharCode(key);
            var aux = field.value.charAt(cursor);

            if (aux != " " && aux != "/" && (field.value.charAt(cursor + 1)) == " ") {
                field.value = setCharAt(field.value, cursor, char);
                field.value = setCharAt(field.value, cursor + 1, aux);
                return;
            }
            console.log(cursor);
           //Valida a entrada dos dias nas posições 0, 1 e 2
            switch (cursor) {
                case 0:
                    if (char > 3) {
                        field.value = setCharAt(field.value, 0, 0);
                        field.value = setCharAt(field.value, 1, char);
                        cursor += 3;
                    } else {
                        field.value = setCharAt(field.value, 0, char);
                        cursor += 1;
                    }
                    break;
                case 1:
                    if (field.value.charAt(0) == " ") {
                        if (char > 3) {
                            field.value = setCharAt(field.value, 0, 0);
                            field.value = setCharAt(field.value, 1, char);
                            cursor += 2;
                        } else {
                            field.value = setCharAt(field.value, 0, char);
                        }
                    } else {
                        field.value = setCharAt(field.value, 1, char);
                        cursor += 2;
                    }
                    break;
                case 2:
                    if (field.value.charAt(0) == " " && field.value.charAt(1) == " ") {
                        if (char > 3) {
                            field.value = setCharAt(field.value, 0, 0);
                            field.value = setCharAt(field.value, 1, char);
                            cursor += 1;
                        } else {
                            field.value = setCharAt(field.value, 0, char);
                        }
                    } else if (field.value.charAt(0) != " " && field.value.charAt(1) == " ") {
                        field.value = setCharAt(field.value, 1, char);
                        cursor += 1;
                    } else if (field.value.charAt(0) == " " && field.value.charAt(1) != " ") {
                        if (char > 3) {
                            field.value = setCharAt(field.value, 0, 0);
                            cursor += 1;
                        } else {
                            field.value = setCharAt(field.value, 0, char);
                        }
                    } else {
                        if (char > 1) {
                            field.value = setCharAt(field.value, 3, 0);
                            field.value = setCharAt(field.value, 4, char);
                            cursor += 3;
                        } else {
                            field.value = setCharAt(field.value, 3, char);
                            cursor += 2;
                        }
                    }
                    break;
                //Valida entrada dos meses nas posições 3,4 e 5
                case 3:
                    if (char > 1) {
                        field.value = setCharAt(field.value, 3, 0);
                        field.value = setCharAt(field.value, 4, char);
                        cursor += 3;
                    } else {
                        field.value = setCharAt(field.value, 3, char);
                        cursor += 1;
                    }
                    break;
                case 4:
                    if (field.value.charAt(3) == " ") {
                        if (char > 1) {
                            field.value = setCharAt(field.value, 3, 0);
                            field.value = setCharAt(field.value, 4, char);
                            cursor += 2;
                        } else {
                            field.value = setCharAt(field.value, 3, char);
                        }
                    } else {
                        field.value = setCharAt(field.value, 4, char);
                        cursor += 2;
                    }
                    break;
                case 5:
                    if (field.value.charAt(3) == " " && field.value.charAt(4) == " ") {
                        if (char > 1) {
                            field.value = setCharAt(field.value, 3, 0);
                            field.value = setCharAt(field.value, 4, char);
                            cursor += 1;
                        } else {
                            field.value = setCharAt(field.value, 4, char);
                        }
                    } else if (field.value.charAt(3) != " " && field.value.charAt(4) == " ") {
                        field.value = setCharAt(field.value, 4, char);
                        cursor += 1;
                    } else if (field.value.charAt(3) == " " && field.value.charAt(4) != " ") {
                        if (field.value.charAt(4) > 1) {
                            field.value = setCharAt(field.value, 3, 0);
                            cursor += 1;
                        } else {
                            field.value = setCharAt(field.value, 3, field.value.charAt(4));
                            field.value = setCharAt(field.value, 4, char);
                        }
                    } else {
                        field.value = setCharAt(field.value, 6, char);
                        cursor += 2;
                    }
                    break;
                default:
                    field.value = setCharAt(field.value, cursor, char);
                    cursor += 1;
                    break;
            }
            createSelection(field, cursor, cursor);
            return false;
        }

       //Delete pressionado
        if (key == 46) {
            var dropped = "undefined";

            for (var i = 0; i <= 9; i++) {
                if (before.charAt(i) != after.charAt(i)) {
                    dropped = before.charAt(i);
                    break;
                }
            }
            if (dropped != "undefined") {
                if ((i - cursor) != 0) {
                    i -= (i - cursor);
                }
                if (cursor == 0 || cursor == 3) {
                    field.value = after.substring(0, i + 1) + " " + after.substring(i + 1, 10);
                } else if (cursor == 1 || cursor == 4) {
                    field.value = after.substring(0, i) + " " + after.substring(i, 10);
                } else if (cursor == 2) {
                    i + 1;
                    field.value = before.substring(0, 3) + before.substring(4, 10);
                    field.value = field.value.substring(0, 4) + " " + field.value.substring(4, 10);
                } else if (cursor == 5) {
                    i + 1;
                    field.value = before.substring(0, 6) + before.substring(7, 10);
                    field.value = field.value + " ";
                } else {
                    field.value = field.value + " ";
                }
                createSelection(field, i, i);
            }
        }
    }

};

//Criar seleção/Mover o cursor intermitente
function createSelection(field, start, end) {
    if ((navigator.userAgent.indexOf("MSIE") != -1) || (!!document.documentMode == true)) {
        if (field.createTextRange) {
            var selRange = field.createTextRange();
            var range = field.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
            field.focus();
        } else if (field.setSelectionRange) {
            field.focus();
            field.setSelectionRange(start, startr);
        } else if (typeof field.selectionStart != 'undefined') {
            field.selectionStart = start;
            field.selectionEnd = end;
            field.focus();
        }
    } else {
        if (field.createTextRange) {
            var selRange = field.createTextRange();
            selRange.collapse(true);
            selRange.moveStart('character', start);
            selRange.moveEnd('character', end);
            selRange.select();
            field.focus();
        } else if (field.setSelectionRange) {
            field.focus();
            field.setSelectionRange(start, end);
        } else if (typeof field.selectionStart != 'undefined') {
            field.selectionStart = start;
            field.selectionEnd = end;
            field.focus();
        }
    }
};

//Substituir o char
function setCharAt(str, index, chr) {
    if (index > str.length - 1) return str;
    return str.substr(0, index) + chr + str.substr(index + 1);
};

//Recolocar a máscara
function putMaskAgain(field) {
    var natural = field.value.replace(/[/]/g, "");
    while (natural.length < 10) {
        natural += " ";
    }
    field.value = (natural.substring(0, 2) + "/" + natural.substring(2, 4) + "/" + natural.substring(4, 8));

    for (var i = 0; i <= 10; i++) {
        if (isNaN(field.value.charAt(i)) && (field.value.charAt(i) != "/") && (i != 2 || i != 5)) {
            field.value = setCharAt(field.value, i, " ");
        } else if ((i != 2 && i != 5) && (field.value.charAt(i) == "/")) {
            field.value = setCharAt(field.value, i, " ");
        } else if ((i == 2 || i == 5) && (field.value.charAt(i) != "/")) {
            field.value = setCharAt(field.value, i, "/");
        }
        createSelection(field, i, i);
    }
    createSelection(field, field.value.indexOf(" "), field.value.indexOf(" "));
    return;
};

function putTheRangeOnTheStart(field) {
    var start = field.selectionStart;
    var end = field.selectionEnd;
    if (start != end) {
        return false;
    }
    if (field.value.trim().length == 10) {
        return true;
    }
    createSelection(field, field.value.indexOf(" "), field.value.indexOf(" "));
};
body {
    margin: 0;
    padding: 0;
    background-color: #EDEEF2;
}
.header {
    padding-top: 20px;
    background-color: #fff;
    height: 250px;
    margin: 0px;
}
.box {
    background-color: #323A45;
    width: 400px;
    height: 350px;
    font-size: 20px;
    font-family: sans-serif;
    text-align: center;
    box-shadow: 0px 0px 10px #888;
    border-radius: 5px;
}
.box p {
    color: #fff;
    font-weight: 700;
}
.box input {
    margin-top: 10px;
    background-color: #eaeaea;
    padding: 10px;
    border-style: none;
    font-size: 20px;
    border-radius: 3px;
    width: 90%;
}
.conteudo {
    width: 100vw;
    height: 100vh;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
}
.linha {
    background: #529FD3;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    padding: 0.5px;
}
input[type=text]::-ms-clear {
    display: none;
    width: 0;
    height: 0;
}
<html>
	<head>
	<title>Mascaras</title>
        <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="css/estilo.css">
        <script language="JavaScript" src="script.js"></script>
	</head>
    
	<body>
        <div class="conteudo">
            <div class="box">
                <p>MÁSCARA DINÂMICA</p>
                <div class="header">  
                     <input type="text" id="input" onclick="putTheRangeOnTheStart(this)" onkeydown="return beforeDate(this,event)" onkeyup="return afterDate(this,event)" name= "teste" maxlength="10" value = "  /  /    ">                   
                </div>
            </div>
        </div>
	</body>
    
</html>

  • I’m still analyzing the code, but I think it would be a good idea to separate each task using comments, as it’s great.

  • Yes, even tbm to facilitate reading and understanding of it...

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.