Angular 2 CSS Validator

I am working on a new Angular 2 application and one of the inputs allows you to define a CSS color. This is an interesting input to validate.

Valid input includes the standard hex code value (#ff2112), but named colors (rebeccapurple) are also valid.

For the hex code, we can use a standard regular expression to validate directly in-line, but that won’t let us also validate against the CSS names.

RegEx for CSS colors:
/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i

To validate both the hex code and the name we need to use a custom validator.

The basic flow of a validator is to take the input, perform the test(s), and then return the validity.

Create a new file named cssColor.validator.ts and save it within a directory named validators. I like to keep all my custom validators in a validators directory.

We need to import the FormControl module from @angular/forms

import { FormControl } from '@angular/forms';

Next, we need to declare the export function that we can call to validate our input

export function validateCSSColor(c: FormControl) {

Into this function, we will pass in the reference to the form. Now it is a simple matter of performing the tests. We will define the COLOR_REGEXP, then see if the input matches:

let COLOR_REGEXP = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i;
if (COLOR_REGEXP.test(c.value)) {
  return null;
 }

If the input is valid, the validator should just return a null value. Since this is the more probably input type by the user, I opted to test it first.

Next, if the input does not match this regex, we can see if is one of the custom CSS names. The full list of these names can be found here.

let validColors: Array<string> = ["black", "silver", "gray", "white", ...

With our array defined (and properly typed), we test if the input:

if ( validColors.indexOf(c.value.toLowerCase() ) == -1) {
  return { validateCSSColor: { valid: false } };
 } else {
  return null;
 }

Here is where we handle the case where the input matches neither a valid hex code nor a valid CSS name. In this case, we need to return a custom object. This object has one property, which is the name of the validation function (in our case validateCSSColor), and its value also, an object: { valid: false }.

Now our standard Angular validation directives will function, just like the built-in validators. The full code of the validator can be seen here.

With the validator written, we can now reference it within our code. In your component’s .ts file, import the validator:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators, FormBuilder, ReactiveFormsModule } from'@angular/forms';
import { validateCSSColor } from'./validators/cssColor.validator';

@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})

export class AppComponent {
 pwaForm: FormGroup;
 themeColorCtrl: FormControl;
 title = 'Angular 2 Custom Validator Demo';

 constructor(private fb: FormBuilder) {
 this.themeColorCtrl = this.fb.control('', [Validators.required, validateCSSColor]);
 this.pwaForm = this.fb.group({
 themeColor: this.themeColorCtrl,
 });
 }
}

The key addition to this simple component is passing in our custom validator as part of the validator array when we declare the themeColorCtrl.

Let’s set up of HTML file for a simple input for the CSS color, and some feedback. Here is the snippet:

<input type="text" label="Theme Color" formControlName="themeColor" />
<div *ngIf="pwaForm.controls.themeColor.errors">Invalid CSS Color</div>

Now, we have linked our <input> to our component’s FormControl through the formControlName attribute. Then we can test if there is an error by querying ‘pwaForm.controls.themeColor.errors’ and display some feedback to the user.

For a complete example, see the GitHub repo.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s