Creating A Password Generator Using Javascript

Creating A Password Generator Using Javascript

Creating A Password Generator Using Javascript

Nowadays we all need security, No not that security which has bouncers and guards I’m talking about Virtual Security like social media account , google account etc. For that they use password which is known to the user and it hidden as (*). But now their are some constraint for the password like there should be a fix range of characters there must but uppercase, lowercase letters some symbols etc.

But nowadays how a user will remember this thing because user will only set the password which he can memorize faster. So for that we have a project idea to share, On that note I Welcome you all to Codewithrandom with a new blog in which we’ll create a password generator and understand front-end development tools.

I hope you have got an idea about the project

HTML Code for Password Generator

<div class="container">
    <h2 class="title">Password Generator</h2>
    <div class="result">
        <div class="result__title field-title">Generated Password</div>
        <div class="result__info right">click to copy</div>
        <div class="result__info left">copied</div>
        <div class="result__viewbox" id="result">CLICK GENERATE</div>
        <button id="copy-btn" style="--x: 0; --y: 0"><i class="far fa-copy"></i></button>
    </div>
    <div class="length range__slider" data-min="4" data-max="32">
        <div class="length__title field-title" data-length='0'>length:</div>
        <input id="slider" type="range" min="4" max="32" value="16" />
    </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>

In this HTML Code we have defined the structure of the password generator which the slider to set a range of characters then we have a clipboard which will help the user to copy the generated password and then a button which will provide a generated password. Now lets style the page using CSS.

CSS Code for Password Generator

* {
    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";
    h2.title {
        font-size: 1.75rem;
        margin: 10px -5px;
        margin-bottom: 30px;
        color: #fff;
    }
}

$field-color: rgba(255, 255, 255, 0.08);
$field-height: 65px;
$field-border-radius: 8px;

.result {
    position: relative;
    width: 100%;
    height: 65px;
    overflow: hidden;
    &__info {
        &.right {
            right: 8px;
        }
        &.left {
            left: 8px;
        }
        position: absolute;
        bottom: 4px;
        color: #fff;
        font-size: 0.8rem;
        transition: all 150ms ease-in-out;
        transform: translateY(200%);
        opacity: 0;
    }
    &__viewbox {
        width: 100%;
        height: 100%;
        background: $field-color;
        border-radius: $field-border-radius;
        color: #fff;
        text-align: center;
        line-height: 65px;
    }
    #copy-btn {
        position: absolute;
        top: var(--y);
        left: var(--x);
        width: 38px;
        height: 38px;
        background: #fff;
        border-radius: 50%;
        opacity: 0;
        transform: translate(-50%, -50%) scale(0);
        transition: all 350ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
        cursor: pointer;
        z-index: 2;
        &:active {
            box-shadow: 0 0 0 200px rgba(255, 255, 255, 0.08);
        }
    }
    &:hover {
        #copy-btn {
            opacity: 1;
            transform: translate(-50%, -50%) scale(1.35);
        }
    }
}
.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(#{$field-height} - 10px);
display: flex;
justify-content: center;
align-items: center;
background: $field-color;
border-radius: $field-border-radius;
margin: 30px 0;

&::before,
&::after {
    position: absolute;
    color: #fff;
    font-size: 0.9rem;
    font-weight: bold;
}
&::before {
    content: attr(data-min);
    left: 10px;
}
&::after {
    content: attr(data-max);
    right: 10px;
}
.length__title::after {
    content: attr(data-length);
    position: absolute;
    right: -16px;
    font-variant-numeric: tabular-nums;
    color: #fff;
}
}

$range-handle-color: rgb(255, 255, 255) !default;
$range-handle-color-hover: rgb(212, 212, 212) !default;
$range-handle-size: 20px !default;

$range-track-color: rgba(255, 255, 255, 0.314) !default;
$range-track-height: 2px !default;

$range-label-width: 60px !default;

#slider {
    -webkit-appearance: none;
    width: calc(100% - (#{$range-label-width + 10px}));
    height: $range-track-height;
    border-radius: 5px;
    background: $range-track-color;
    outline: none;
    padding: 0;
    margin: 0;
    cursor: pointer;

    // Range Handle
    &::-webkit-slider-thumb {
        -webkit-appearance: none;
        width: $range-handle-size;
        height: $range-handle-size;
        border-radius: 50%;
        background: $range-handle-color;
        cursor: pointer;
        transition: all 0.15s ease-in-out;
        &:hover {
            background: $range-handle-color-hover;
            transform: scale(1.2);
        }
    }
    &::-moz-range-thumb {
        width: $range-handle-size;
        height: $range-handle-size;
        border: 0;
        border-radius: 50%;
        background: $range-handle-color;
        cursor: pointer;
        transition: background 0.15s ease-in-out;
        &:hover {
            background: $range-handle-color-hover;
        }
    }
}

.settings {
    position: relative;
    height: auto;
    widows: 100%;
    display: flex;
    flex-direction: column;

    .setting {
        position: relative;
        width: 100%;
        height: calc(#{$field-height} - 10px);
    background: $field-color;
    border-radius: $field-border-radius;
    display: flex;
    align-items: center;
    padding: 10px 25px;
    color: #fff;
    margin-bottom: 8px;
    input {
        opacity: 0;
        position: absolute;
        + label {
            user-select: none;
            &::before,
            &::after {
                content: "";
                position: absolute;
                transition: 150ms cubic-bezier(0.24, 0, 0.5, 1);
                transform: translateY(-50%);
                top: 50%;
                right: 10px;
                cursor: pointer;
            }
            &::before {
                height: 30px;
                width: 50px;
                border-radius: 30px;
                background: rgba(214, 214, 214, 0.434);
            }
            &::after {
                height: 24px;
                width: 24px;
                border-radius: 60px;
                right: 32px;
                background: #fff;
            }
        }
        &:checked {
            & + label:before {
                background: #5d68e2;
                transition: all 150ms cubic-bezier(0, 0, 0, 0.1);
            }
            & + label:after {
                right: 14px;
            }
        }
        &:focus {
            + label:before {
                box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.75);
            }
        }
        &:disabled{
            + label{
                &:before, &:after{ cursor: not-allowed }
                &:before{ background: #4f4f6a }
                &:after{ background: #909090 }
            }
        }
    }
}
}

.btn.generate {
    user-select: none;
    position: relative;
    width: 100%;
    height: 50px;
    margin: 10px 0;
    border-radius: $field-border-radius;
    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;
    &: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 .56s;
}
@keyframes octocat-wave{
    0%, 100%{
        transform:rotate(0);
    }
    20%, 60%{
        transform:rotate(-20deg);
    }
    40%, 80%{
        transform:rotate(10deg);
    }
}

In this CSS code we have styled the page given the color to the page and set the alignment for the defined tags in the HTML code and set the padding and margin for the respective element so that every thing doesn’t get messy and every thing is aligned properly. Lets code the JavaScript part which has all the main function and which is the important part of this project.

JavaScript Code in Password Generator

console.clear();
const sliderProps = {
    fill: "#0B1EDF",
    background: "rgba(255, 255, 255, 0.214)",
};
const slider = document.querySelector(".range__slider");
const sliderValue = document.querySelector(".length__title");
slider.querySelector("input").addEventListener("input", event => {
    sliderValue.setAttribute("data-length", event.target.value);
    applyFill(event.target);
});
applyFill(slider.querySelector("input"));
function applyFill(slider) {
    const percentage = (100 * (slider.value - slider.min)) / (slider.max - slider.min);
    const bg = `linear-gradient(90deg, ${sliderProps.fill} ${percentage}%, ${sliderProps.background} ${percentage +
            0.1}%)`;
    slider.style.background = bg;
    sliderValue.setAttribute("data-length", slider.value);
}
const randomFunc = {
    lower: getRandomLower,
    upper: getRandomUpper,
    number: getRandomNumber,
    symbol: getRandomSymbol,
};
function secureMathRandom() {
    return window.crypto.getRandomValues(new Uint32Array(1))[0] / (Math.pow(2, 32) - 1);
}
function getRandomLower() {
    return String.fromCharCode(Math.floor(Math.random() * 26) + 97);
}
function getRandomUpper() {
    return String.fromCharCode(Math.floor(Math.random() * 26) + 65);
}
function getRandomNumber() {
    return String.fromCharCode(Math.floor(secureMathRandom() * 10) + 48);
}
function getRandomSymbol() {
    const symbols = '~!@#$%^&*()_+{}":?><;.,';
    return symbols[Math.floor(Math.random() * symbols.length)];
}
const resultEl = document.getElementById("result");
const lengthEl = document.getElementById("slider");
const uppercaseEl = document.getElementById("uppercase");
const lowercaseEl = document.getElementById("lowercase");
const numberEl = document.getElementById("number");
const symbolEl = document.getElementById("symbol");
const generateBtn = document.getElementById("generate");
const copyBtn = document.getElementById("copy-btn");
const resultContainer = document.querySelector(".result");
const copyInfo = document.querySelector(".result__info.right");
const copiedInfo = document.querySelector(".result__info.left");
let generatedPassword = false;
let resultContainerBound = {
    left: resultContainer.getBoundingClientRect().left,
    top: resultContainer.getBoundingClientRect().top,
};
resultContainer.addEventListener("mousemove", e => {
    resultContainerBound = {
        left: resultContainer.getBoundingClientRect().left,
        top: resultContainer.getBoundingClientRect().top,
    };
    if(generatedPassword){
        copyBtn.style.opacity = '1';
        copyBtn.style.pointerEvents = 'all';
        copyBtn.style.setProperty("--x", `${e.x - resultContainerBound.left}px`);
        copyBtn.style.setProperty("--y", `${e.y - resultContainerBound.top}px`);
    }else{
        copyBtn.style.opacity = '0';
        copyBtn.style.pointerEvents = 'none';
    }
});
window.addEventListener("resize", e => {
    resultContainerBound = {
        left: resultContainer.getBoundingClientRect().left,
        top: resultContainer.getBoundingClientRect().top,
    };
});

copyBtn.addEventListener("click", () => {
    const textarea = document.createElement("textarea");
    const password = resultEl.innerText;
    if (!password || password == "CLICK GENERATE") {
        return;
    }
    textarea.value = password;
    document.body.appendChild(textarea);
    textarea.select();
    document.execCommand("copy");
    textarea.remove();

    copyInfo.style.transform = "translateY(200%)";
    copyInfo.style.opacity = "0";
    copiedInfo.style.transform = "translateY(0%)";
    copiedInfo.style.opacity = "0.75";
});

generateBtn.addEventListener("click", () => {
    const length = +lengthEl.value;
    const hasLower = lowercaseEl.checked;
    const hasUpper = uppercaseEl.checked;
    const hasNumber = numberEl.checked;
    const hasSymbol = symbolEl.checked;
    generatedPassword = true;
    resultEl.innerText = generatePassword(length, hasLower, hasUpper, hasNumber, hasSymbol);
    copyInfo.style.transform = "translateY(0%)";
    copyInfo.style.opacity = "0.75";
    copiedInfo.style.transform = "translateY(200%)";
    copiedInfo.style.opacity = "0";
});

function generatePassword(length, lower, upper, number, symbol) {
    let generatedPassword = "";
    const typesCount = lower + upper + number + symbol;
    const typesArr = [{ lower }, { upper }, { number }, { symbol }].filter(item => Object.values(item)[0]);
    if (typesCount === 0) {
        return "";
    }
    for (let i = 0; i < length; i++) {
        typesArr.forEach(type => {
            const funcName = Object.keys(type)[0];
            generatedPassword += randomFunc[funcName]();
        });
    }
    return generatedPassword.slice(0, length)
                                    .split('').sort(() => Math.random() - 0.5)
                                    .join('');
}

function disableOnlyCheckbox(){
    let totalChecked = [uppercaseEl, lowercaseEl, numberEl, symbolEl].filter(el => el.checked)
    totalChecked.forEach(el => {
        if(totalChecked.length == 1){
            el.disabled = true;
        }else{
            el.disabled = false;
        }
    })
}

[uppercaseEl, lowercaseEl, numberEl, symbolEl].forEach(el => {
    el.addEventListener('click', () => {
        disableOnlyCheckbox()
    })
})

In this code we have clear console and then added the logical how the things will work and combine and the user a password according to its need. we have defined all the characters, upper case, lower case, symbols etc. And set the parameter when the user will demand according to its need now let us see the final output of the project.

Final Output

We have Successfully created our Password Generator using HTML5, CSS3 & JS | Password Generator Code in JavaScript. You can use this project for your personal needs and the respective lines of code are given with the code pen link mentioned above.

If you find out this Blog helpful, then make sure to search code with random on google for Front End Projects with Source codes and make sure to Follow the Code with Random Instagram page.

Written By – Harsh Sawant

Code By – @harshh9



Leave a Reply