Password Generator: Why is there no password being generated in the div with id="generated-password"?

71 Views Asked by At

toIncludeCharacters() seems to be working since it returns lower-case letters on upload generatePassword() seems to be returning a blank output

When you click "Generate Password" button it returns three blank outputs

Can I know why this is so?

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Password Generator</title>
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9"
      crossorigin="anonymous"
    />
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <form>
      <h1>Password Generator</h1>
      <div>
      <label for="length">Length of password:</label>
      <input
        type="number"
        id="password-length"
        name="password-length"
        min="8"
        max="20"
        placeholder="8"
      />
    </div>
      <div class="form-check">
        <input
          class="form-check-input"
          type="checkbox"
          value=""
          id="uppercase-condition"
        />
        <label class="form-check-label" for="upper-case-condition">
          Include uppercase letters
        </label>
      </div>
      <div class="form-check">
        <input
          class="form-check-input"
          type="checkbox"
          value=""
          id="lowercase-condition"
          checked
        />
        <label class="form-check-label" for="lowercase-condition">
          Include lowercase letters
        </label>
      </div>
      <div class="form-check">
        <input
          class="form-check-input"
          type="checkbox"
          value=""
          id="symbols-condition"
        />
        <label class="form-check-label" for="symbols-condition">
          Include symbols
        </label>
      </div>
      <div class="form-check">
        <input
          class="form-check-input"
          type="checkbox"
          value=""
          id="numbers-condition"
        />
        <label class="form-check-label" for="numbers-condition">
          Include numbers
        </label>
      </div>
      <button type="button" class="btn btn-primary" id="create-password">Generate Password</button>
      <div id="generated-password">1234</div>
    </form>
    <script
      src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm"
      crossorigin="anonymous"
    ></script>
    <script src="app.js"></script>
  </body>
</html>`
const passwordLengthCondition = document.getElementById("password-length");
const uppercaseCondition = document.getElementById("uppercase-condition");
const lowercaseCondition = document.getElementById("lowercase-condition");
const symbolsCondition = document.getElementById("symbols-condition");
const numbersCondition = document.getElementById("numbers-condition");

const conditionsChecklist = [
  uppercaseCondition,
  lowercaseCondition,
  symbolsCondition,
  numbersCondition,
];

function toIncludeCharacters() {
  const uppercaseLetters = "QWERTYUIOPASDFGHJKLZXCVBNM";
  const lowercaseLetters = "qwertyuiopasdfghjklzxcvbnm";
  const symbols = "!@#$%^&*()_+-={}[]|\\:;\"'<>,.?/~`";
  const numbers = "1234567890";

  const charactersList = [uppercaseLetters, lowercaseLetters, symbols, numbers];

  let includedCharacters = ""; // Reset the characters for each call

  for (let i = 0; i < conditionsChecklist.length; i++) {
    if (conditionsChecklist[i].checked) {
      includedCharacters += charactersList[i];
    }
  }

  console.log(includedCharacters)
  return includedCharacters;
}

function generatePassword(passwordLength) {
  let password = "";
  for (let i = 0; i < passwordLength; i++) {
    password += toIncludeCharacters().charAt(Math.floor(Math.random() * includedCharacters.length));
  }
  console.log(password);
  return password;
}


const generatePasswordButton = document.getElementById("create-password");
generatePasswordButton.addEventListener("click", () => {
  const passwordLength = parseInt(passwordLengthCondition.value); // Convert to number
  document.getElementById("generated-password").textContent = generatePassword(passwordLength);
  console.log(generatePassword(passwordLength)); // Move this line here
});

const checklist = document.getElementsByClassName("form-check-input");
for (let i = 0; i < checklist.length; i++) {
  checklist[i].addEventListener("change", toIncludeCharacters);
}

toIncludeCharacters();
generatePassword();
#generated-password {
  margin: 3%;
  font-weight: bolder;
  font-size: larger;
}


body {
  margin: 5%;
}

form {
  background-color: aliceblue;
  padding: 2%;
}

form div, button {
  margin: 1%;
}

I want to be able to show a custom password given the condition of password length and characters that should be included.

1

There are 1 best solutions below

0
Anonymous On

Solution explanation

In your generatePassword function, it looks like you are getting an error for "includedCharacters" is not defined. This is because you didn't save the returned value of toIncludeCharacters function. The value is only fetched once.

The code can be changed to save the returned value to a variable (let's call it incl_chars) and then we can use that value for the functions.

Updated code

So, your updated function becomes:

function generatePassword(passwordLength) {
  let password = "";
  incl_chars = toIncludeCharacters()
  for (let i = 0; i < passwordLength; i++) {
    password += incl_chars.charAt(Math.floor(Math.random() * incl_chars.length));
  }
  // console.log(password);
  return password;
}

And your updated code becomes:

const passwordLengthCondition = document.getElementById("password-length");
const uppercaseCondition = document.getElementById("uppercase-condition");
const lowercaseCondition = document.getElementById("lowercase-condition");
const symbolsCondition = document.getElementById("symbols-condition");
const numbersCondition = document.getElementById("numbers-condition");

const conditionsChecklist = [
  uppercaseCondition,
  lowercaseCondition,
  symbolsCondition,
  numbersCondition,
];

function toIncludeCharacters() {
  const uppercaseLetters = "QWERTYUIOPASDFGHJKLZXCVBNM";
  const lowercaseLetters = "qwertyuiopasdfghjklzxcvbnm";
  const symbols = "!@#$%^&*()_+-={}[]|\\:;\"'<>,.?/~`";
  const numbers = "1234567890";

  const charactersList = [uppercaseLetters, lowercaseLetters, symbols, numbers];

  let includedCharacters = ""; // Reset the characters for each call

  for (let i = 0; i < conditionsChecklist.length; i++) {
    if (conditionsChecklist[i].checked) {
      includedCharacters += charactersList[i];
    }
  }

  // console.log(includedCharacters)
  return includedCharacters;
}

function generatePassword(passwordLength) {
  let password = "";
  incl_chars = toIncludeCharacters()
  for (let i = 0; i < passwordLength; i++) {
    password += incl_chars.charAt(Math.floor(Math.random() * incl_chars.length));
  }
  // console.log(password);
  return password;
}


const generatePasswordButton = document.getElementById("create-password");
generatePasswordButton.addEventListener("click", () => {
  const passwordLength = parseInt(passwordLengthCondition.value); // Convert to number
  document.getElementById("generated-password").textContent = generatePassword(passwordLength);
  // console.log(generatePassword(passwordLength)); // Move this line here
});

const checklist = document.getElementsByClassName("form-check-input");
for (let i = 0; i < checklist.length; i++) {
  checklist[i].addEventListener("change", toIncludeCharacters);
}

/*
toIncludeCharacters();
generatePassword();
*/
#generated-password {
  margin: 3%;
  font-weight: bolder;
  font-size: larger;
}

body {
  margin: 5%;
}

form {
  background-color: aliceblue;
  padding: 2%;
}

form div,
button {
  margin: 1%;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Password Generator</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous" />
  <link rel="stylesheet" href="style.css" />
</head>

<body>
  <form>
    <h1>Password Generator</h1>
    <div>
      <label for="length">Length of password:</label>
      <input type="number" id="password-length" name="password-length" min="8" max="20" placeholder="8" />
    </div>
    <div class="form-check">
      <input class="form-check-input" type="checkbox" value="" id="uppercase-condition" />
      <label class="form-check-label" for="upper-case-condition">
          Include uppercase letters
        </label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="checkbox" value="" id="lowercase-condition" checked />
      <label class="form-check-label" for="lowercase-condition">
          Include lowercase letters
        </label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="checkbox" value="" id="symbols-condition" />
      <label class="form-check-label" for="symbols-condition">
          Include symbols
        </label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="checkbox" value="" id="numbers-condition" />
      <label class="form-check-label" for="numbers-condition">
          Include numbers
        </label>
    </div>
    <button type="button" class="btn btn-primary" id="create-password">Generate Password</button>
    <div id="generated-password">1234</div>
  </form>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script>
  <script src="app.js"></script>
</body>

</html>`

Suggestion(s)

I would also suggest adding a check to see if the user has entered any value or not in the length box, for your purpose.