Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions OTP Input Field/demo1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- [Medium Blog Link](https://sqkhor.medium.com/create-an-otp-input-with-javascript-c0c9f7c610fe)
64 changes: 64 additions & 0 deletions OTP Input Field/demo1/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OTP Input Field - Using JS</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="otp-input">
<input
type="number"
step="1"
min="0"
max="9"
autocomplete="no"
pattern="\d*"
/>
<input
type="number"
step="1"
min="0"
max="9"
autocomplete="no"
pattern="\d*"
/>
<input
type="number"
step="1"
min="0"
max="9"
autocomplete="no"
pattern="\d*"
/>
<input
type="number"
step="1"
min="0"
max="9"
autocomplete="no"
pattern="\d*"
/>
<input
type="number"
step="1"
min="0"
max="9"
autocomplete="no"
pattern="\d*"
/>
<input
type="number"
step="1"
min="0"
max="9"
autocomplete="no"
pattern="\d*"
/>
</div>
<input type="hidden" name="otp" />

<script src="script.js"></script>
</body>
</html>
100 changes: 100 additions & 0 deletions OTP Input Field/demo1/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
function updateInput() {
let inputValue = Array.from(inputs).reduce(function (otp, input) {
otp += (input.value.length) ? input.value : ' ';
return otp;
}, "");
document.querySelector("input[name=otp]").value = inputValue;
}

window.onload = () => {
const inputs = document.querySelectorAll("#otp-input input");

for (let i = 0; i < inputs.length; i++) {
const input = inputs[i];

input.addEventListener("input", function () {
// handling normal input
if (input.value.length == 1 && i + 1 < inputs.length) {
inputs[i + 1].focus();
}

// if a value is pasted, put each character to each of the next input
if (input.value.length > 1) {
// sanities input
if (isNaN(input.value)) {
input.value = "";
updateInput();
return;
}

// split characters to array
const chars = input.value.split('');

for (let pos = 0; pos < chars.length; pos++) {
// if length exceeded the number of inputs, stop
if (pos + i >= inputs.length) break;

// paste value
let targetInput = inputs[pos + i];
targetInput.value = chars[pos];
}

// focus the input next to the last pasted character
let focus_index = Math.min(inputs.length - 1, i + chars.length);
inputs[focus_index].focus();
}
updateInput();
});

input.addEventListener("keydown", function (e) {
// backspace button
if (e.keyCode == 8 && input.value == '' && i != 0) {
// shift next values towards the left
for (let pos = i; pos < inputs.length - 1; pos++) {
inputs[pos].value = inputs[pos + 1].value;
}

// clear previous box and focus on it
inputs[i - 1].value = '';
inputs[i - 1].focus();
updateInput();
return;
}

// delete button
if (e.keyCode == 46 && i != inputs.length - 1) {
// shift next values towards the left
for (let pos = i; pos < inputs.length - 1; pos++) {
inputs[pos].value = inputs[pos + 1].value;
}

// clear the last box
inputs[inputs.length - 1].value = '';
input.select();
e.preventDefault();
updateInput();
return;
}

// left button
if (e.keyCode == 37) {
if (i > 0) {
e.preventDefault();
inputs[i - 1].focus();
inputs[i - 1].select();
}
return;
}

// right button
if (e.keyCode == 39) {
if (i + 1 < inputs.length) {
e.preventDefault();
inputs[i + 1].focus();
inputs[i + 1].select();
}
return;
}
});
}
};
29 changes: 29 additions & 0 deletions OTP Input Field/demo1/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
* {
margin: 0;
padding: 0;
box-size: border-box;
}

#otp-input {
display: flex;
gap: 0.5em;
}

#otp-input input {
width: 2em;
padding: 0.5em 0;
font-family: monospace;
font-size: 1em;
text-align: center;
}

/* hide spinner */
#otp-input input::-webkit-outer-spin-button,
#otp-input input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}

#otp-input input[type="number"] {
-moz-appearance: textfield; /* Firefox */
}
1 change: 1 addition & 0 deletions OTP Input Field/demo2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- [Blog Link](https://chriscoyier.net/2023/12/04/html-css-for-a-one-time-password-input/)
19 changes: 19 additions & 0 deletions OTP Input Field/demo2/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OTP Input Field - Without using JS</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<input
required
type="text"
autocomplete="one-time-code"
inputmode="numeric"
maxlength="4"
pattern="\d{4}"
/>
</body>
</html>
34 changes: 34 additions & 0 deletions OTP Input Field/demo2/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[autocomplete="one-time-code"] {
--magic-number: 100px;

background-image: linear-gradient(#fff, #fff),
url("https://assets.codepen.io/3/rounded-rectangle.svg");
background-size: var(--magic-number);
background-position-x: right, left;
background-repeat: no-repeat, repeat-x;
border: 0;
height: var(--magic-number);
width: calc(5 * var(--magic-number));
font-size: calc(0.6 * var(--magic-number));
font-family: monospace;
letter-spacing: calc(0.64 * var(--magic-number));
padding-inline-start: calc(0.3 * var(--magic-number));
box-sizing: border-box;
overflow: hidden;
transform: translatex(calc(0.5 * var(--magic-number)));
}
[autocomplete="one-time-code"]:focus {
outline: none;
background-image: linear-gradient(#fff, #fff),
url("https://assets.codepen.io/729148/blue-rounded-rectangle.svg");
background-size: var(--magic-number);
background-position-x: right, left;
background-repeat: no-repeat, repeat-x;
}

body {
height: 100vh;
margin: 0;
display: grid;
place-items: center;
}
44 changes: 44 additions & 0 deletions OTP Input Field/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OTP Input Field</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}

body {
height: 100vh;
padding: 1rem;
display: grid;
gap: 1.2rem;
place-items: center;
background-color: black;
}

a {
color: white;
padding: 1.2rem;
font-size: 1.2rem;
border-radius: 10px;
text-decoration: none;
border: 2px solid gray;
background-color: rgba(123, 255, 0, 0.3);
}

a:hover {
border-color: white;
background-color: rgba(123, 255, 0, 0.6);
}
</style>
</head>

<body></body>
<a href="./demo1/demo.html">Demo 1(Using JS)</a>
<a href="./demo2/demo.html">Demo 2(Without using JS)</a>
</html>
76 changes: 37 additions & 39 deletions Scroll Triggered Animations/index.html
Original file line number Diff line number Diff line change
@@ -1,47 +1,45 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript Experiments</title>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Scroll Triggered Animations</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}

body {
height: 100vh;
padding: 1rem;
display: grid;
gap: 1.2rem;
place-items: center;
background-color: black;
}
body {
height: 100vh;
padding: 1rem;
display: grid;
gap: 1.2rem;
place-items: center;
background-color: black;
}

a {
color: white;
padding: 1.2rem;
font-size: 1.2rem;
border-radius: 10px;
text-decoration: none;
border: 2px solid gray;
background-color: rgba(123, 255, 0, 0.3);
}
a {
color: white;
padding: 1.2rem;
font-size: 1.2rem;
border-radius: 10px;
text-decoration: none;
border: 2px solid gray;
background-color: rgba(123, 255, 0, 0.3);
}

a:hover {
border-color: white;
background-color: rgba(123, 255, 0, 0.6);
}
a:hover {
border-color: white;
background-color: rgba(123, 255, 0, 0.6);
}
</style>
</head>
</head>

<body>
</body>
<a href="./demo1/demo.html">Demo 1</a>
<a href="./demo2/demo.html">Demo 2</a>
<a href="./demo3/demo.html">Demo 3</a>
</html>
<body></body>
<a href="./demo1/demo.html">Demo 1</a>
<a href="./demo2/demo.html">Demo 2</a>
<a href="./demo3/demo.html">Demo 3</a>
</html>
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,6 @@
<a href="./Custom Dropdown/demo.html">Custom Dropdown</a>
<a href="./Markdown to HTML/demo.html">Markdown to HTML</a>
<a href="./Audio Visualizer/demo.html">Audio Visualizer</a>
<a href="./OTP Input Field/index.html">OTP Input Field</a>
</body>
</html>