Pinpad
by borisjavier
HTML
<div class="pin-login" id="mainPinLogin" style="display: inline-block">
<input type="password" readonly class="pin-login__text">
<div class="pin-login__numpad">
</div>
</div>
<div style="text-align: center;">
Olvide mi pin
</div>
CSS
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/materialicons/v139/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2');
}
.pin-login {
display: inline-block;
width: 240px;
border-radius: 10px;
padding: 10px;
font-size: 28px;
background: #000000;
border: 1px solid #363b5e;
user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
font-family: sans-serif;
}
.pin-login__text {
margin: 10px auto 10px auto;
padding: 10px;
display: block;
width: 50%;
font-size: 0.5em;
text-align: center;
letter-spacing: 0.2em;
background: rgba(0, 0, 0, 0.75);
color: #ffc300;
border: none;
border-radius: 10px;
outline: none;
cursor: default;
}
.pin-login__text--error {
color: #901818;
background: #000000;
animation-name: loginError;
animation-duration: 0.1s;
animation-iteration-count: 2;
}
@keyframes loginError {
25% {
transform: translateX(-3px);
}
75% {
transform: translateX(3px);
}
}
@-moz-keyframes loginError {
25% {
transform: translateX(-3px);
}
75% {
transform: translateX(3px);
}
}
.pin-login__key {
width: 60px;
height: 60px;
margin: 10px;
background: rgba(255, 195, 0, 0.75);
color: #000000;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
font-weight: bold;
cursor: pointer;
}
.pin-login__key:active {
background: rgba(0, 0, 0, 0.25);
}
.material-icons1 {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-flex;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
}
JavaScript
class PinLogin {
constructor ({el, loginEndpoint, maxNumbers = 6}) {
this.el = {
main: el,
numPad: el.querySelector(".pin-login__numpad"),
textDisplay: el.querySelector(".pin-login__text")
};
this.loginEndpoint = loginEndpoint;
this.maxNumbers = maxNumbers;
this.value = "";
this._generatePad();
}
_generatePad() {
const padLayout = [
"1", "2", "3",
"4", "5", "6",
"7", "8", "9",
"backspace", "0", "done"
];
padLayout.forEach(key => {
const insertBreak = key.search(/[369]/) !== -1;
const keyEl = document.createElement("div");
keyEl.classList.add("pin-login__key");
keyEl.classList.toggle("material-icons1", isNaN(key));
keyEl.textContent = key;
keyEl.addEventListener("click", () => { this._handleKeyPress(key) });
this.el.numPad.appendChild(keyEl);
if (insertBreak) {
this.el.numPad.appendChild(document.createElement("br"));
}
});
}
_handleKeyPress(key) {
switch (key) {
case "backspace":
this.value = this.value.substring(0, this.value.length - 1);
break;
case "done":
this._attemptLogin();
break;
default:
if (this.value.length < this.maxNumbers && !isNaN(key)) {
this.value += key;
} else if (this.value.length < this.maxNumbers && !isNaN(key)) {
this._attemptLogin()
}
break;
}
this._updateValueText();
}
_updateValueText() {
this.el.textDisplay.value = "_".repeat(this.value.length);
this.el.textDisplay.classList.remove("pin-login__text--error");
}
_attemptLogin() {
if (this.value.length > 0) {
...