Search code examples
javascriptpasswordsgeneratorpromptconfirm

Random Password Generator Javascript not working


I'm trying to create a random password generator that asks for the user input on size 8-128 characters and then confirms the use of uppercase, lowercase, symbols, and or numbers. I'm trying to get the password to generate and print in the text area and i know i'm missing something but I'm not exactly sure what. I apologize for the rough code. I'm just starting out.

var plength = prompt("How many characters would you like your password to be?")

if (plength < 8 || plength > 128){
    alert("Length must be 8-128 characters")
}

if (plength >= 8 && plength <= 128){
var cuppercase = confirm("Would you like to use uppercase letters?")
var clowercase = confirm("Would you like to use lowercase letters?")
var cnumbers = confirm("would you like to use numbers?")
var csymbols = confirm("would you like to use special characters?")
}    

if (cuppercase != true && clowercase != true && cnumbers != true && csymbols != true){
    alert("You must select at least one character type!")
}

//DOM elements
const resultEl = document.getElementById('password');




document.getElementById('generate').addEventListener('click', () => {	
	const hasLower = clowercase.true;
	const hasUpper = cuppercase.true;
	const hasNumber = cnumbers.true;
	const hasSymbol = csymbols.true;
	resultEl.innerText = generatePassword(hasLower, hasUpper, hasNumber, hasSymbol, length);
});






const randomFunc = {
	lower: getRandomLower,
	upper: getRandomUpper,
	number: getRandomNumber,
	symbol: getRandomSymbol
}

document.getElementById('clipboard').addEventListener('click', () => {
	const textarea = document.createElement('textarea');
	const password = resultEl.innerText;
	
	if(!password) { return; }
	
	textarea.value = password;
	document.body.appendChild(textarea);
	textarea.select();
	document.execCommand('copy');
	textarea.remove();
	alert('Password copied to clipboard');
});


function generatePassword(lower, upper, number, symbol, length) {
	let generatedPassword = '';
    const typesCount = lower + upper + number + symbol;
	const typesArr = [{lower}, {upper}, {number}, {symbol}].filter(item => Object.values(item)[0]);

 	// create a loop
     for(let i=0; i<length; i+=typesCount) {
		typesArr.forEach(type => {
			const funcName = Object.keys(type)[0];
			generatedPassword += randomFunc[funcName]();
		});
	}
	
	const finalPassword = generatedPassword.slice(0, length);
	
	return finalPassword;
}

// Generator functions

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(Math.random() * 10) + 48);
}

function getRandomSymbol() {
	const symbols = '!@#$%^&*(){}[]=<>/,.'
	return symbols[Math.floor(Math.random() * symbols.length)];
}
        <header>
          <h1 class="text-center" style= "margin-top: 20px;">Password Generator</h1>
        </header>
        
        <div class="card shadow-sm p-3 mb-5 bg-white rounded" style="max-width: 60%; margin: 40px auto;">
                <div class="card-body">
                  <h2 class="card-title">Generate a Password</h2>
                  <textarea 
                  style= "width: 100%; text-align:center; resize:none; border: dashed 2px lightgrey; margin:30px auto; padding: 10px auto; min-height: 100px;" 
    
                  readonly
                  id="password"
                  placeholder="Your Secure Password"
                  aria-label="Generated Password"
                ></textarea>
               
        <button type="button" class="btn btn-danger" id= "generate" style= "float:left; border-radius:40px; padding-right: 30px; padding-left: 30px;">Generate Password</button>
        <button type="button" class="btn btn-light" id= "clipboard" style= "float:right;  border-radius:40px; padding-right: 30px; padding-left: 30px; background-color: silver; color:white">Copy to clipboard</button>
    </div>
    </div>


Solution

  • UPDATE:

    I've been referring similar questions to this question, so I figured I'd write some cleaner code for them to see here:

    var length = Number(prompt("How many characters would you like your password to be?"));
    while (isNaN(length) || length < 8 || length > 128) length = Number(prompt("Length must be 8-128 characters. How many characters would you like your password to be?"));
    
    var uppers = confirm("Would you like to use uppercase letters?");
    var lowers = confirm("Would you like to use lowercase letters?");
    var numbers = confirm("Would you like to use numbers?");
    var symbols = confirm("Would you like to use special characters?");
    
    while (!uppers && !lowers && !numbers && !symbols) {
      alert("You must select at least one character type!");
      uppers = confirm("Would you like to use uppercase letters?");
      lowers = confirm("Would you like to use lowercase letters?");
      numbers = confirm("Would you like to use numbers?");
      symbols = confirm("Would you like to use special characters?");
    }
    
    window.addEventListener('load', function() {
      generateNewPassword();
    });
    
    function generateNewPassword() {
      var password = "";
    
      var allowed = {};
      if (uppers) password += rando(allowed.uppers = "QWERTYUIOPASDFGHJKLZXCVBNM");
      if (lowers) password += rando(allowed.lowers = "qwertyuiopasdfghjklzxcvbnm");
      if (numbers) password += rando(allowed.numbers = "1234567890");
      if (symbols) password += rando(allowed.symbols = "!@#$%^&*(){}[]=<>/,.");
    
      for (var i = password.length; i < length; i++) password += rando(rando(allowed).value);
    
      document.getElementById("password").value = randoSequence(password).join("");
    }
    <script src="https://randojs.com/1.0.0.js"></script>
    <input type="text" id="password"/>
    <button onclick="generateNewPassword();">Generate new password</button>

    I used randojs.com to make the randomness simple and easy to read, just like I did in my original answer to this question. Visit the site if you need an explanation on that. Just add this:

    <script src="https://randojs.com/1.0.0.js"></script>
    

    in your head tag to be able to use randojs functions.


    OLD ANSWER:

    You were missing some semicolons. You should wait until the page loads to access elements by wrapping in:

    window.addEventListener('load', function (){
    
    });
    

    You should grab a textarea's value, not its innerText. I also added loops for the prompts/confirms at the beginning to force the user to try again until they give valid input. Other than that, I just cleaned the formatting up a bit. I used randojs.com to make the randomness easier to read. Visit the site if you need an explanation on that. I just added this:

    <script src="https://randojs.com/1.0.0.js"></script>
    

    in your head tag to be able to use randojs functions. Let me know if you have any questions.

    window.addEventListener('load', function() {
      var plength = prompt("How many characters would you like your password to be?");
    
      while (plength < 8 || plength > 128) {
        plength = prompt("Length must be 8-128 characters. How many characters would you like your password to be?");
      }
    
      var cuppercase = confirm("Would you like to use uppercase letters?");
      var clowercase = confirm("Would you like to use lowercase letters?");
      var cnumbers = confirm("would you like to use numbers?");
      var csymbols = confirm("would you like to use special characters?");
    
      while (!(cuppercase || clowercase || cnumbers || csymbols)) {
        alert("You must select at least one character type!");
    
        cuppercase = confirm("Would you like to use uppercase letters?");
        clowercase = confirm("Would you like to use lowercase letters?");
        cnumbers = confirm("would you like to use numbers?");
        csymbols = confirm("would you like to use special characters?");
      }
    
      //DOM elements
      const resultEl = document.getElementById('password');
    
      document.getElementById('generate').addEventListener('click', () => {
        resultEl.value = generatePassword(clowercase, cuppercase, cnumbers, csymbols, plength);
      });
    
      document.getElementById('clipboard').addEventListener('click', () => {
        const textarea = document.createElement('textarea');
        const password = resultEl.value;
    
        if (!password) {
          return;
        }
    
        textarea.value = password;
        document.body.appendChild(textarea);
        textarea.select();
        document.execCommand('copy');
        textarea.remove();
        alert('Password copied to clipboard');
      });
    });
    
    
    const randomFunc = {
      lower: getRandomLower,
      upper: getRandomUpper,
      number: getRandomNumber,
      symbol: getRandomSymbol
    };
    
    function generatePassword(lower, upper, number, symbol, length) {
      let generatedPassword = '';
      const typesCount = lower + upper + number + symbol;
      const typesArr = [{
        lower
      }, {
        upper
      }, {
        number
      }, {
        symbol
      }].filter(item => Object.values(item)[0]);
    
      // create a loop
      for (let i = 0; i < length; i += typesCount) {
        typesArr.forEach(type => {
          const funcName = Object.keys(type)[0];
          generatedPassword += randomFunc[funcName]();
        });
      }
    
      const finalPassword = generatedPassword.slice(0, length);
    
      return finalPassword;
    }
    
    // Generator functions
    function getRandomLower() {
      return rando("qwertyuiopasdfghjklzxcvbnm")
    }
    
    function getRandomUpper() {
      return rando("QWERTYUIOPASDFGHJKLZXCVBNM");
    }
    
    function getRandomNumber() {
      return rando(9);
    }
    
    function getRandomSymbol() {
      return rando('!@#$%^&*(){}[]=<>/,.');
    }
    <html>
      <head>
        <script src="https://randojs.com/1.0.0.js"></script>
      </head>
      <body>
        <header>
          <h1 class="text-center" style="margin-top: 20px;">Password Generator</h1>
        </header>
        <div class="card shadow-sm p-3 mb-5 bg-white rounded" style="max-width: 60%; margin: 40px auto;">
          <div class="card-body">
            <h2 class="card-title">Generate a Password</h2>
            <textarea style="width: 100%; text-align:center; resize:none; border: dashed 2px lightgrey; margin:30px auto; padding: 10px auto; min-height: 100px;" readonly id="password" placeholder="Your Secure Password" aria-label="Generated Password"></textarea>
            <button type="button" class="btn btn-danger" id="generate" style="float:left; border-radius:40px; padding-right: 30px; padding-left: 30px;">Generate Password</button>
            <button type="button" class="btn btn-light" id="clipboard" style="float:right;  border-radius:40px; padding-right: 30px; padding-left: 30px; background-color: silver; color:white">Copy to clipboard</button>
          </div>
        </div>
      </body>
    </html>