Creating a sign up form with an automatic password generator in javascript
Tags: html, javascript, webdev, showdev
Published: 2022-02-13 00:10:14

Can I learn kung fu without sparring? Are you learning javascript as I am? If you are great! You see, this is the first project I am single-handedly doing since I started learning javascript. I first wrote a password generator in <a href='https://github.com/Babi-B/password-generator/tree/main/Java'>Java</a> then thought; "Well, since I'm learning js..."

I tried to think of a structure I wanted the login form to follow (even though it was _just_ a signup page) but while working I had to redesign my plan several times. I learned a lot from that.


---

> _Talk is cheap. Show me the code..._

### <span id="ref">The Password Complexity Rules</span>

These are just some criteria I wanted the password to validate:

<ol><li>
The password must be of at least 8 characters
</li>
<li>
The password must contain characters that fall within these 
categories:  
<ul><li>
Must contain uppercase letters(A through Z)</li>
<li>
Must contain lowercase letters(a through z)</li>
<li>
Must contain non-alphanumeric characters</li>
<li>
Must contain Arabic numerals(0 through 9)</li>
</ul>
</li>
<li>
The password must **not** contain the user's name (neither first nor last name)
</li>


### The Design

Ok now, let me work you through the implementation of my thought pattern.

First, I created a form with takes in the user's last name, first name, and password(which could be generated or customized)

**Web view**


![web view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jn16pmldzifckmmnxrm.jpg)

**Mobile view**


![mobile view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y8ege8yse7taztag6nd1.jpg)

The logic for password generation and validation can be broken down into a few steps.

- First comes the password generation function
The password is generated from letters(upper and lower cases), numbers (0-9), and special characters. 

```
/* To Generate the password*/
function generatePassword() {
  let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  let symbols = "%!@#$^&*-+=|\\(){}:\"';,?";
  let password = "";

  for (let i = 0; i < 4; i++) {
    let randomNumber = Math.floor(Math.random() * 10);
    let lowerCaseLetter = alphabet.charAt(Math.random() * 26).toLowerCase();
    let upperCaseLetter = alphabet.charAt(Math.random() * 26).toUpperCase();
    let specialChar = symbols.charAt(Math.random() * symbols.length);

    password += randomNumber + lowerCaseLetter + upperCaseLetter + specialChar;
  }
  return shuffle(password);
}
```
- The shuffle() function is used to shuffle the string after the password is generated. Unlike Java, I could not just call an inbuilt function to shuffle the string. This is a custom-built function.

The aim of this is to minimize predictability

```
/* To shuffle the password string*/
function shuffle(str) {
  let arr = str.split("");
  let n = arr.length;

  for (let i = 0; i < n; i++) {
    let j = Math.floor(Math.random() * n);

    let temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
  }
  return arr.join("");
}
```
- Then there's the validation function to ensure that the password contains neither the user's first nor last name, and also to ensure that the password is well-formed with letters(upper and lowercases), numbers, and special characters.

Since the user can enter a customized password, this function is important to ensure that it meets the password <a href="#ref">complexity rules</a> already listed.

```
/* To Validate the password*/
function validatePassword(password, fname, lname) {
  if (password.includes(fname) || password.includes(lname)) {
    formAlert.style.display = "block";
    formAlert.innerHTML = "Password must not include first or last name";
    return false;
  } else if (
    !/\d/.test(password) ||
    !/[a-z]/.test(password) ||
    !/[A-Z]/.test(password) ||
    !/[%!@#$^&*-+=|\\(){}:\"';,?]/.test(password)
  ) {
    formAlert.style.display = "block";
    formAlert.innerHTML = "Password must be a mix of letters, numbers, and special symbols";
    return false;
  } else return true;
}
```
Is there a shorter way to do the RegExp comparison in this validation method? Please comment below or better contribute <a href="https://github.com/Babi-B/password-generator/tree/main/JavaScript">here</a>.

- Other aspects of the validation are handled in the HTML like:
<ul>
<li>The `minlength` of the password field is 8</li>
<li>All input fields are `required` so no input is null</li> 
<li>The type of the email field is `email` so a valid input is given</li>


**Bonus**
I made a checkbox to toggle this visibility of the password.


### The Results

- Password with user's name

![error image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jesgli0vbaf6st887w2k.jpg)

- Malformed password

![error image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zc14kltouetttjkgj8r.jpg)

- Form filled with valid inputs

![valid form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bg5kwz4n9kr5vy7zgsxg.jpg)

![sucess](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qhxsiceevorpgeb4ii1e.jpg)

Please feel free to try out the form in <a href="https://codepen.io/babi-b/full/WNXjoBW">here</a>

The implementation of the code can be found in <a href="https://codepen.io/babi-b/pen/WNXjoBW">codepen.io</a> and codebase in my <a href="https://github.com/Babi-B/password-generator">repository</a>

I am open to any _constructive_ additions you may have. 

Happy Coding! 🌱



                                                    Babi 💞