Monday, 19 June, 2017 UTC


Summary

Recently I released some content around form validation within a NativeScript application that uses Angular. This is great as you can use it to check your form for errors based on any number of criteria. However, what if you wanted to guide your users through a form process rather than validating the data? An example might be when it comes to account registration and password creation. To prevent users from using weak passwords, it might be helpful to add a strength meter within the form that changes as data is entered.
To be clear, this can be considered a type of form validation, but we're going to take a different approach. We're going to see how to monitor an input field in NativeScript, run the data through a regular expression tester, and update the CSS on a strength meter depending on the results of the regular expression test.
You can download a zip containing the finished project here.
Creating a Fresh NativeScript with Angular Project
This project is going to be rather simple, both in design and in the logic. This is because the regular expressions are going to take care of all of the heavy lifting.
In the above animated image you can see a simple form with the strength meter. There are four different strength indicators, or in other words, four different possible colors depending on what was entered.
Using the NativeScript CLI, execute the following command:
tns create pw-strength-project --ng
The --ng tag in the above command indicates that we are going to be building an Angular project rather than a core project. No additional plugins or libraries are required to be successful in this project.
Adding the Strength Test and Application Logic with Regular Expressions
If you've been keeping up with my tutorials, you'll recall that back in 2015 I wrote a tutorial called "Use RegEx to Test Password Strength in JavaScript". That tutorial focused on JavaScript and AngularJS rather than Angular with NativeScript. However, some of the concepts will still hold true.
Open the project's app/app.component.ts file and include the following TypeScript code:
import { Component } from "@angular/core";

@Component({
    selector: "ns-app",
    templateUrl: "app.component.html",
})
export class AppComponent {

    public password: string;
    public passwordStrength: string;

    public constructor() {
        this.passwordStrength = "pw-none";
    }

    public strength(password: string) {
        let strongRegex = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})");
        let mediumRegex = new RegExp("^(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})");
        if(strongRegex.test(password)) {
            this.passwordStrength = "pw-strong";
        } else if(mediumRegex.test(password)) {
            this.passwordStrength = "pw-medium";
        } else if(password != "") {
            this.passwordStrength = "pw-weak";
        } else {
            this.passwordStrength = "pw-none";
        }
    }

}
We need to break down what is happening above because it can be a little confusing for someone new to regular expressions or even TypeScript.
Essentially we have a password variable that will be bound to our input field and a passwordStrength variable that will hold CSS information with regards to how the strength meter should look. When the input field is empty, the CSS class name should be pw-none which we'll create shortly.
This is where things get interesting:
public strength(password: string) {
    let strongRegex = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})");
    let mediumRegex = new RegExp("^(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})");
    if(strongRegex.test(password)) {
        this.passwordStrength = "pw-strong";
    } else if(mediumRegex.test(password)) {
        this.passwordStrength = "pw-medium";
    } else if(password != "") {
        this.passwordStrength = "pw-weak";
    } else {
        this.passwordStrength = "pw-none";
    }
}
In the above strength method you'll notice two long and scary regular expressions. Let's break down what one of them means:
// The string must start with the rules that follow
^

// The string must contain at least one lowercase character
(?=.*[a-z])

// The string must contain at least one uppercase character
(?=.*[A-Z])

// The string must contain at least one numeric character
(?=.*[0-9])

// The string must contain at least one special character, some of which are escaped to prevent regex errors
(?=.*[!@#\$%\^&\*])

// The string must be at least eight characters long
(?=.{8,})
The above rules represent what we have in the regular expression for evaluating a strong password. The medium password formula isn't really different, with the exception that we now have an or operator. We're saying that we want at least two of the conditions to be valid from the strong password formula.
The rest of the strength method just tests the regular expressions and chooses a CSS class name that we should use. Let's configure the CSS and UI in the next step.
Building the UI and Designing the CSS
With the regular expression logic in place, we can focus on the visual magic. Let's first start with the CSS that will power the strength meter.
Open the project's app/app.css file and include the following:
@import 'nativescript-theme-core/css/core.light.css';

.pw {
    border-width: 1;
    border-color: #000000;
    padding: 5;
    margin: 5;
}

.pw-none { }

.pw-weak {
    background-color: red;
}

.pw-medium {
    background-color: yellow;
}

.pw-strong {
    background-color: green;
}
The CSS is very basic and is more heavily based around meter colors or spacing. The real magic is in the markup that connects to the TypeScript logic.
Open the project's app/app.component.html file and include the following markup:
<ActionBar title="{N} Password Strength"></ActionBar>
<StackLayout class="form">
    <StackLayout class="input-field">
        <Label text="Password" class="label font-weight-bold m-b-5"></Label>
        <TextField [(ngModel)]="password" (ngModelChange)="strength($event)" class="input input-border"></TextField>
        <GridLayout rows="auto" columns="*, *, *">
            <StackLayout row="0" col="0" class="pw {{ passwordStrength }}"></StackLayout>
            <StackLayout row="0" col="1" class="pw {{ passwordStrength }}"></StackLayout>
            <StackLayout row="0" col="2" class="pw {{ passwordStrength }}"></StackLayout>
        </GridLayout>
        <StackLayout class="hr-light"></StackLayout>
    </StackLayout>
</StackLayout>
Beyond the basic NativeScript component layout design, we have two core components to pay attention to here. Take note of the TextField and the three StackLayout components with dynamic class information.
The TextField is bound to our password variable that was created in the TypeScript file. There is also a change event that checks our password strength at every character keystroke.
Depending on how the strength method responds, we have the passwordStrength variable within our three StackLayout components that make up the strength meter. This will allow the meter to change colors as we enter data into the input field.
Conclusion
You just saw how to use regular expressions to manage a password strength meter within your NativeScript Angular mobile application. This is similar to what we saw in previous articles on the subject of form validation with Angular.
There are many ways to solve a problem when it comes to programming and this is just another one of those ways.
The post Test Password Strength Using Regular Expressions in a NativeScript Mobile Application appeared first on Telerik Developer Network.