Hey everyone, In this article, we will build our own Password Generator using pure Javascript.
This app will generate a secure random password for us.
In this article we will talk about app's funtionality mostly about Javascript & html
This is the link of our Random Password generator https://rkhan76.github.io/Random-Password-Generator-js/
Source code is given below
Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Link css -->
<link rel="stylesheet" href="style.css" />
<title>
Random Password Generator
</title>
</head>
<body>
<div class="container">
<h2 class="title">Password Generator</h2>
<div class="result">
<div class="result__viewbox" id="result">CLICK GENERATE</div>
</div>
<div class="length range__slider" data-min="4" data-max="32">
<div class="length__title field-title" data-length="8">length:</div>
<input id="slider" type="range" min="4" max="32" value="8" />
</div>
<div class="settings">
<span class="settings__title field-title">settings</span>
<div class="setting">
<input type="checkbox" id="uppercase" checked />
<label for="uppercase">Include Uppercase</label>
</div>
<div class="setting">
<input type="checkbox" id="lowercase" checked />
<label for="lowercase">Include Lowercase</label>
</div>
<div class="setting">
<input type="checkbox" id="number" checked />
<label for="number">Include Numbers</label>
</div>
<div class="setting">
<input type="checkbox" id="symbol" />
<label for="symbol">Include Symbols</label>
</div>
</div>
<button class="btn generate" id="generate">Generate Password</button>
</div>
<script src="script.js"></script>
</body>
</html>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100%;
height: 100vh;
background-image: linear-gradient(to top, #209cff 100%, #68e0cf 200%);
display: flex;
justify-content: center;
align-items: center;
}
button {
border: 0;
outline: 0;
}
.container {
margin: 40px 0;
width: 400px;
height: 600px;
padding: 10px 25px;
background: #0a0e31;
border-radius: 10px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.45), 0 4px 8px rgba(0, 0, 0, 0.35), 0 8px 12px rgba(0, 0, 0, 0.15);
font-family: "Montserrat";
}
.container h2.title {
font-size: 1.75rem;
margin: 10px -5px;
margin-bottom: 30px;
color: #fff;
}
.result {
position: relative;
width: 100%;
height: 65px;
overflow: hidden;
cursor: pointer;
}
.result__info {
position: absolute;
bottom: 4px;
color: #fff;
font-size: 0.8rem;
transition: all 150ms ease-in-out;
transform: translateY(200%);
opacity: 0;
}
.result__viewbox {
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.08);
border-radius: 8px;
color: #fff;
text-align: center;
line-height: 65px;
}
.field-title {
position: absolute;
top: -10px;
left: 8px;
transform: translateY(-50%);
font-weight: 800;
color: rgba(255, 255, 255, 0.5);
text-transform: uppercase;
font-size: 0.65rem;
pointer-events: none;
user-select: none;
}
.options {
width: 100%;
height: auto;
margin: 50px 0;
}
.range__slider {
position: relative;
width: 100%;
height: calc(65px - 10px);
display: flex;
justify-content: center;
align-items: center;
background: rgba(255, 255, 255, 0.08);
border-radius: 8px;
margin: 30px 0;
}
.range__slider::before, .range__slider::after {
position: absolute;
color: #fff;
font-size: 0.9rem;
font-weight: bold;
}
.range__slider::before {
content: attr(data-min);
left: 10px;
}
.range__slider::after {
content: attr(data-max);
right: 10px;
}
.range__slider .length__title::after {
content: attr(data-length);
position: absolute;
right: -16px;
font-variant-numeric: tabular-nums;
color: #fff;
}
#slider {
-webkit-appearance: none;
width: calc(100% - (70px));
height: 2px;
border-radius: 5px;
background: rgba(255, 255, 255, 0.314);
outline: none;
padding: 0;
margin: 0;
cursor: pointer;
}
#slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: rgb(255, 255, 255);
cursor: pointer;
transition: all 0.15s ease-in-out;
}
#slider::-webkit-slider-thumb:hover {
background: rgb(212, 212, 212);
transform: scale(1.2);
}
#slider::-moz-range-thumb {
width: 20px;
height: 20px;
border: 0;
border-radius: 50%;
background: rgb(255, 255, 255);
cursor: pointer;
transition: background 0.15s ease-in-out;
}
#slider::-moz-range-thumb:hover {
background: rgb(212, 212, 212);
}
.settings {
position: relative;
height: auto;
widows: 100%;
display: flex;
flex-direction: column;
}
.settings .setting {
position: relative;
width: 100%;
height: calc(65px - 10px);
background: rgba(255, 255, 255, 0.08);
border-radius: 8px;
display: flex;
align-items: center;
padding: 10px 25px;
color: #fff;
margin-bottom: 8px;
}
.settings .setting input {
opacity: 0;
position: absolute;
}
.settings .setting input + label {
user-select: none;
}
.settings .setting input + label::before, .settings .setting input + label::after {
content: "";
position: absolute;
transition: 150ms cubic-bezier(0.24, 0, 0.5, 1);
transform: translateY(-50%);
top: 50%;
right: 10px;
cursor: pointer;
}
.settings .setting input + label::before {
height: 30px;
width: 50px;
border-radius: 30px;
background: rgba(214, 214, 214, 0.434);
}
.settings .setting input + label::after {
height: 24px;
width: 24px;
border-radius: 60px;
right: 32px;
background: #fff;
}
.settings .setting input:checked + label:before {
background: #5d68e2;
transition: all 150ms cubic-bezier(0, 0, 0, 0.1);
}
.settings .setting input:checked + label:after {
right: 14px;
}
.settings .setting input:focus + label:before {
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.75);
}
.settings .setting input:disabled + label:before, .settings .setting input:disabled + label:after {
cursor: not-allowed;
}
.settings .setting input:disabled + label:before {
background: #4f4f6a;
}
.settings .setting input:disabled + label:after {
background: #909090;
}
.btn.generate {
user-select: none;
position: relative;
width: 100%;
height: 50px;
margin: 10px 0;
border-radius: 8px;
color: #fff;
border: none;
background-image: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
letter-spacing: 1px;
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
transition: all 150ms ease;
}
.btn.generate:active {
transform: translateY(-3%);
box-shadow: 0 4px 8px rgba(255, 255, 255, 0.08);
}
.support {
position: fixed;
right: 10px;
bottom: 10px;
padding: 10px;
display: flex;
}
a {
margin: 0 20px;
color: #fff;
font-size: 2rem;
transition: all 400ms ease;
}
a:hover {
color: #222;
}
.github-corner svg {
position: absolute;
right: 0;
top: 0;
mix-blend-mode: darken;
color: #eeeeee;
fill: #353535;
clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.github-corner:hover .octo-arm {
animation: octocat-wave 0.56s;
}
@keyframes octocat-wave {
0%, 100% {
transform: rotate(0);
}
20%, 60% {
transform: rotate(-20deg);
}
40%, 80% {
transform: rotate(10deg);
}
}
Javascript
const slider = document.getElementById('slider')
const lengthTitle = document.querySelector('.length__title')
const uppercaseCheckbox = document.getElementById('uppercase')
const lowercaseCheckbox = document.getElementById('lowercase')
const numberCheckbox = document.getElementById('number')
const symbolCheckbox = document.getElementById('symbol')
const showResult = document.getElementById('result')
const generate = document.getElementById('generate')
const copyfunction = document.getElementById('result')
const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const lowercase = 'abcdefghijklmnopqrstuvwxyz'
const specialSymbol = "!@#$%^&*()_-+={}[]|:;'<>,.?/"
const number = '0123456789'
let stringToChoosePass = uppercase + lowercase + number
let Password = ''
let length = parseInt(slider.value)
// handle slider to adjust lenght of password
slider.addEventListener('input', function () {
lengthTitle.setAttribute('data-length', slider.value)
length = parseInt(slider.value)
})
// handle the selection part to what include in our password
uppercaseCheckbox.addEventListener('input', () => {
if (uppercaseCheckbox.checked === false) {
stringToChoosePass = stringToChoosePass.replace(uppercase, '')
} else {
stringToChoosePass += uppercase
}
})
lowercaseCheckbox.addEventListener('input', () => {
if (lowercaseCheckbox.checked === false) {
stringToChoosePass = stringToChoosePass.replace(lowercase, '')
} else {
stringToChoosePass += lowercase
}
})
numberCheckbox.addEventListener('input', () => {
if (numberCheckbox.checked === false) {
stringToChoosePass = stringToChoosePass.replace(number, '')
} else {
stringToChoosePass += number
}
})
symbolCheckbox.addEventListener('input', () => {
if (symbolCheckbox.checked === true) {
stringToChoosePass += specialSymbol
} else {
stringToChoosePass = stringToChoosePass.replace(specialSymbol, '')
}
})
// handle generate operation of password and Show it on screnn
generate.addEventListener('click', () => {
if (Password != '') return
for (let i = 0; i < length; i++) {
Password += stringToChoosePass.charAt(
Math.floor(Math.random() * stringToChoosePass.length)
)
}
showResult.innerText = Password
})
// handle copy funtion
copyfunction.addEventListener('mouseover', () => {
if (!Password) {
showResult.innerText = 'CLICK GENERATE'
} else {
showResult.innerText = 'Click to Copy'
}
})
copyfunction.addEventListener('mouseout', function () {
if (!Password) {
showResult.innerText = 'CLICK GENERATE'
} else {
showResult.innerText = Password
}
})
showResult.addEventListener('click', () => {
if(Password == "") return
navigator.clipboard.writeText(Password)
alert('copied')
})
In this article we will talk about each part seperatly
Step -1 (slider funtionality)
<div class="length range__slider" data-min="4" data-max="32">
<div class="length__title field-title" data-length="8">length:</div>
<input id="slider" type="range" min="4" max="32" value="8" />
</div>
- It will use to set the length of the Password generated by the user
data-min="4"
anddata-max="32"
:- These data attributes set the minimum and maximum values for a range which will show on the slider box
data-length="8"
:- It is like a tag on a label inside a box, indicating the starting value or length, set to 8.
type="range"
specifies that it's a slider.min="4"
andmax="32"
set the minimum and maximum values for the slider.value="8"
sets the initial value of the slider to 8.
// handle slider to adjust lenght of password
const slider = document.getElementById('slider')
const lengthTitle = document.querySelector('.length__title')
slider.addEventListener('input', function () {
lengthTitle.setAttribute('data-length', slider.value)
length = parseInt(slider.value)
})
const slider = document.getElementById('slider')
:- This line finds and grabs the HTML element with the id "slider" and stores it in a variable called
slider
.
- This line finds and grabs the HTML element with the id "slider" and stores it in a variable called
const lengthTitle = document.querySelector('.length__title')
:- This line finds and grabs the HTML element with the class "length__title" and stores it in a variable called
lengthTitle
.
- This line finds and grabs the HTML element with the class "length__title" and stores it in a variable called
slider.addEventListener('input', function () {...})
:This sets up an event listener that waits for the user to move the slider knob.
When the slider is moved, the function inside the curly braces will run.
lengthTitle.setAttribute('data-length', slider.value)
:This updates the data-length attribute of the label inside the box with the current value of the slider.
It's like changing the number on the "Length" label as you move the slider.
length = parseInt(slider.value)
:This converts the slider's current value to an integer and stores it in a variable called
length
.We will use this 'length' variable later.
Step-2 ( what we include in our password )
<div class="settings">
<span class="settings__title field-title">settings</span>
<div class="setting">
<input type="checkbox" id="uppercase" checked />
<label for="uppercase">Include Uppercase</label>
</div>
<div class="setting">
<input type="checkbox" id="lowercase" checked />
<label for="lowercase">Include Lowercase</label>
</div>
<div class="setting">
<input type="checkbox" id="number" checked />
<label for="number">Include Numbers</label>
</div>
<div class="setting">
<input type="checkbox" id="symbol" />
<label for="symbol">Include Symbols</label>
</div>
</div>
type="checkbox"
:- This attribute indicates that the input element is a checkbox.
checked
:The
checked
attribute is a boolean attribute.When present, it means that the checkbox is initially selected (ticked).
So, when the page loads, the "Include Uppercase" checkbox is already ticked.
// handle the selection area of for the password
const uppercaseCheckbox = document.getElementById('uppercase')
const lowercaseCheckbox = document.getElementById('lowercase')
const numberCheckbox = document.getElementById('number')
const symbolCheckbox = document.getElementById('symbol')
const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const lowercase = 'abcdefghijklmnopqrstuvwxyz'
const specialSymbol = "!@#$%^&*()_-+={}[]|:;'<>,.?/"
const number = '0123456789'
let stringToChoosePass = uppercase + lowercase + number
uppercaseCheckbox.addEventListener('input', () => {
if (uppercaseCheckbox.checked === false) {
stringToChoosePass = stringToChoosePass.replace(uppercase, '')
} else {
stringToChoosePass += uppercase
}
})
lowercaseCheckbox.addEventListener('input', () => {
if (lowercaseCheckbox.checked === false) {
stringToChoosePass = stringToChoosePass.replace(lowercase, '')
} else {
stringToChoosePass += lowercase
}
})
numberCheckbox.addEventListener('input', () => {
if (numberCheckbox.checked === false) {
stringToChoosePass = stringToChoosePass.replace(number, '')
} else {
stringToChoosePass += number
}
})
symbolCheckbox.addEventListener('input', () => {
if (symbolCheckbox.checked === true) {
stringToChoosePass += specialSymbol
} else {
stringToChoosePass = stringToChoosePass.replace(specialSymbol, '')
}
})
uppercaseCheckbox.addEventListener('input', () => {...})
:This line sets up an event listener for the "input" event on the
uppercaseCheckbox
.The "input" event typically fires when the user interacts with the checkbox (e.g., clicks on it).
if (uppercaseCheckbox.checked === false) {...} else {...}
:This is a conditional statement that checks if the checkbox is unchecked.
If the checkbox is unchecked (
uppercaseCheckbox.checked
isfalse
), it enters the block inside the curly braces.If the checkbox is checked, it enters the
else
block.
Checkbox Unchecked:
- If the checkbox is unchecked, It uses the
replace
method to remove theuppercase
characters fromstringToChoosePass
.
- If the checkbox is unchecked, It uses the
Checkbox Checked:
- If the checkbox is checked, It appends (adds) the
uppercase
characters tostringToChoosePass
.
- If the checkbox is checked, It appends (adds) the
And it will do same for rest of the code
Step-3 ( Generate Password functionality)
// handle generate operation of password and Show it on screen
const showResult = document.getElementById('result')
const generate = document.getElementById('generate')
generate.addEventListener('click', () => {
if (Password != '') return
for (let i = 0; i < length; i++) {
Password += stringToChoosePass.charAt(
Math.floor(Math.random() * stringToChoosePass.length)
)
}
showResult.innerText = Password
})
generate.addEventListener('click', () => {...})
:This sets up an event listener for the "click" event on the
generate
button.When the button is clicked, the function inside the curly braces will run.
if (Password != '') return
:This checks if the variable
Password
is not an empty string.If
Password
is not empty, the function returns early, indicating that a password has already been generated.
Password Generation Loop:
A
for
loop runs from 0 to the specifiedlength
(the length of the password).In each iteration, a random character from
stringToChoosePass
is chosen and added to thePassword
.
Display Result:
- The generated password is then assigned to the
innerText
property of theshowResult
element.
- The generated password is then assigned to the
Step-4 ( handle Copy password functionality)
// Handle Copy function
const copyfunction = document.getElementById('result')
copyfunction.addEventListener('mouseover', () => {
if (!Password) {
showResult.innerText = 'CLICK GENERATE'
} else {
showResult.innerText = 'Click to Copy'
}
})
copyfunction.addEventListener('mouseout', function () {
if (!Password) {
showResult.innerText = 'CLICK GENERATE'
} else {
showResult.innerText = Password
}
})
showResult.addEventListener('click', () => {
if(Password == "") return
navigator.clipboard.writeText(Password)
alert('copied')
})
Mouseover Event Listener:
copyfunction.addEventListener('mouseover', () => {...})
sets up an event listener for the "mouseover" event on thecopyfunction
element.If there is no generated password (
Password
is falsy), it changes the displayed text to 'CLICK GENERATE'. Otherwise, it changes the text to 'Click to Copy'.
Mouseout Event Listener:
copyfunction.addEventListener('mouseout', function () {...})
sets up an event listener for the "mouseout" event on thecopyfunction
element.If there is no generated password, it shows 'CLICK GENERATE'. Otherwise, it restores the displayed password.
Click Event Listener:
showResult.addEventListener('click', () => {...})
sets up an event listener for the "click" event on theshowResult
element.If there is a generated password, it copies the password to the clipboard using
navigator.clipboard.writeText(Password)
.After copying, it shows an alert saying 'copied'.
Conclusion
In conclusion, this article has guided us in creating a Random Password Generator using HTML, CSS, and JavaScript. We've learned to build an interactive tool for secure password generation, adjust length, and customize character sets. The addition of copy-to-clipboard functionality enhances user convenience. This project not only reinforces fundamental web development concepts but also underscores the significance of strong, unique passwords for improved online security.
Social Links:
Github: https://github.com/Rkhan76
Twitter: https://twitter.com/RakhshanKhan5
Linkedin: https://www.linkedin.com/in/rakhshan-khan-079875221/