connecteev
94
1
Vue

HTML custom sign up form (password) validation

Posted 6 days ago by connecteev

I have no idea where to start here, but I am trying to recreate the HTML form signup / password validation as seen here: https://duefocus.com/sign-up/

I love the UI of the red arrows turning into green checkmarks as the password meets the validation requirements. If someone can help point me to some sample code, that would be appreciated.

I am starting with this code here: https://codepen.io/connecteev/pen/xoBeRR https://codepen.io/rauldronca/pen/OwKMGX

Html:

<div id="app">
    <h2> Password Strength</h2>

    <div class="input_container">
        <ul>
            <li v-bind:class="{ is_valid: contains_eight_characters }">8 Characters</li>
            <li v-bind:class="{ is_valid: contains_number }">Contains Number</li>
            <li v-bind:class="{ is_valid: contains_uppercase }">Contains Uppercase</li>
            <li v-bind:class="{ is_valid: contains_special_character }">Contains Special Character</li>
        </ul>

        <div class="checkmark_container" v-bind:class="{ show_checkmark: valid_password }">     
            <svg width="50%" height="50%" viewBox="0 0 140 100">
                <path class="checkmark" v-bind:class="{ checked: valid_password }" d="M10,50 l25,40 l95,-70" />
            </svg>
        </div>
        
    <input type="password" @input="checkPassword" v-model="password" autocomplete="off" placeholder="Password" />
    </div>
</div>

Css:

/* Basic Config --------- */

html { box-sizing: border-box; }

*, *:before, *:after { box-sizing: inherit; }

html, body {
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
}

body {
    font-family: 'Open Sans', sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #ff6b6b;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h2 {
    text-align: center;
    color: #FFF;
    font-weight: 400;
}

ul {
    padding-left: 20px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

li { 
    margin-bottom: 8px;
    color: #525f7f;
    position: relative;
}

li:before {
  content: "";
    width: 0%; height: 2px;
    background: #2ecc71;
    position: absolute;
    left: 0; top: 50%;
    display: block;
    transition: all .6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

#app { width: 400px; }


/* Password Input --------- */

.input_container {
    position: relative;
    padding: 30px;
    box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
    border-radius: 6px;
    background: #FFF;
}

input[type="password"] {
    line-height: 1.5;
    display: block;
    color: rgba(136, 152, 170, 1);
    font-weight: 300;
    width: 100%;
    height: calc(2.75rem + 2px);
    padding: .625rem .75rem;
    border-radius: .25rem;
    background-color: #fff;
    transition: border-color .4s ease;
    border: 1px solid #cad1d7;
    outline: 0;
}

input[type="password"]:focus {
    border-color: rgba(50, 151, 211, .45);
}


/* Checkmark & Strikethrough --------- */

.is_valid { color: rgba(136, 152, 170, 0.8); }
.is_valid:before { width: 100%; }

.checkmark_container {
    border-radius: 50%;
    position: absolute;
    top: -15px; right: -15px;
    background: #2ecc71;
    width: 50px; height: 50px;
    visibility: hidden;
    opacity: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: opacity .4s ease;
}

.show_checkmark {
  visibility: visible;
  opacity: 1;
}

.checkmark {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: white;
  stroke-width: 15;
  stroke-linecap: round;
  stroke-dasharray: 180;
  stroke-dashoffset: 180;
}

.checked { animation: draw 0.5s ease forwards; }

@keyframes draw {
  to { stroke-dashoffset: 0; }
}

Javascript:


const App = new Vue({
  el: "#app",
  data: {
    password: null,
    password_length: 0,
        contains_eight_characters: false,
    contains_number: false,
    contains_uppercase: false,
        contains_special_character: false,
    valid_password: false
  },
  
  methods: {
    checkPassword() {
      this.password_length = this.password.length;
            const format = /[ [email protected]#$%^&*()_+\-=\[\]{};':"\|,.<>\/?]/;
            
      if (this.password_length > 8) {
        this.contains_eight_characters = true;
      } else {
        this.contains_eight_characters = false;
            }
            
      this.contains_number = /\d/.test(this.password);
      this.contains_uppercase = /[A-Z]/.test(this.password);
            this.contains_special_character = format.test(this.password);
      
      if (this.contains_eight_characters === true &&
                    this.contains_special_character === true &&
                    this.contains_uppercase === true &&
                    this.contains_number === true) {
                        this.valid_password = true;         
      } else {
        this.valid_password = false;
      }
    }
  }
});

Please sign in or create an account to participate in this conversation.