blog image

Validation of the html input control in angular for the swiss license plates

87018c00-694b-11e9-8b5f-c34826306d36 

We were having requirement to validate html input in the mobile selfcare app for the swiss car license plates. The requirement was to limit the input only for the allowed characters. First two characters are alphabetical and next one up to 6 are digits. Typical pattern is BE123456. The mobile app is running on angular framework. First thought was using one of the many angular input mask validation libraries such as angular-mask, syncfusion, ngx-currency etc. We may have in the future more specific requirements to enter only 2 alphabetical characters from existing cities etc , we decided not to use library and to implement in the angular the validation our selfs.

The requirement included for every position allow only correct characters , e.g. for the 2 first positions only alphabetical and next only digit. The submit icon should be active only when it is a valid swiss license plate e.g. first two characters alphabetical and at least one number. 

mobileokfz

 The custom validation consist of using regular expression which allows with the or operator entering first, second alphabet and then digist.

 public regexPlateInput = '^[a-zA-Z]$|^[a-zA-Z][a-zA-Z]$|^[a-zA-Z][a-zA-Z][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9][0-9][0-9]$';

 Second regular expression is used to make submit icon visible after the text contains valid swiss car license plate.

 public regexPlateSubmit = '^[a-zA-Z][a-zA-Z][0-9]+$';

The input control was enhanced with events :

  • keypress – to capture and validate the input characters
  • keydown – to validate backspace and delete, which can violate the format for the license plate
  • keyup.enter – to capture enter for validating the submit of the text
  • angular placeholder was entered to give the user an example 

<div id="input-box">
    <!--  [@slide]="slide" (@slide.done)="slideDone($event)" -->
    <label for="input-text"></label>
    <input id="input-text" #entryText autocomplete="off" [(ngModel)]="chatItemDef.value"
           (keyup.enter)="onEnter($event)" (blur)="onFocusChanged($event.type)" (focus)="onFocusChanged($event.type)"
            [placeholder]="isPlate ? placeholder : ''"  (keypress)="validateKeyPress($event)" (keydown)="validateKeyDownPress($event)" (paste)="onPaste($event)" />
   <img id="img-send" src="assets/images/Send.svg" alt="" (click)="onSubmit()" *ngIf="showSubmit">
</div>  

ds 

The script for the control is quite complex, but we have it under control and can in the future react to the requirements.

import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
import {ChatService} from '../chat.service';
import {ChatItemDef, InputPattern} from '../../../core/session.service';
@Component({
    selector: 'ph-chat-entry-text',
    templateUrl: 'chat-entry-text.component.html',
    styleUrls: ['./chat-entry-text.component.scss']
})
export class ChatEntryTextComponent implements OnInit {
    @ViewChild('entryText', {static: true}) entryInput: ElementRef;
    @Input() chatItemDef: ChatItemDef;
    @Output() focusChanged = new EventEmitter<string>();
    public showSubmit=true;
    public placeholder='';
    public isPlate=false;
    public regexPlateInput = '^[a-zA-Z]$|^[a-zA-Z][a-zA-Z]$|^[a-zA-Z][a-zA-Z][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9][0-9]$|^[a-zA-Z][a-zA-Z][0-9][0-9][0-9][0-9][0-9][0-9]$';
    public regexPlateSubmit = '^[a-zA-Z][a-zA-Z][0-9]+$';
    constructor(private chatSvc: ChatService) {
    }
    onEnter(event) {
        if (this.isPlate) {
            if (this.onSubmitPlateValidation (event.target.value)) {
                this.onSubmit();
            }
            else {
                event.preventDefault();
                return false;
            }
        } else this.onSubmit();
    }
    onSubmitPlateValidation(str) {
        let regexSubmit = new RegExp(this.regexPlateSubmit);
        if (regexSubmit.test(str)) {
                 return true;
        } else {
               return false;
        }
    }
    onSubmit() {
        if (this.chatItemDef.value) {    // value must exist
            let value: string = this.chatItemDef.value;
            if (this.chatItemDef.pattern === InputPattern.NUMBERPLATE) {
                value = value.toUpperCase().replace(/s/g, '');
            }
            value = value.trim();
            this.chatSvc.processAnswer(value, value);
            this.chatItemDef.value = '';
            this.chatSvc.currentInputType = null;
        }
    }
    onFocusChanged(type: string) {
        this.focusChanged.emit(type);
    }
    ngOnInit(): void {
        if (!this.chatSvc.isApple()) {
            const endPos = this.chatItemDef.value ? this.chatItemDef.value.length : 0;
            this.entryInput.nativeElement.setSelectionRange(endPos, endPos);    // set caret
            this.entryInput.nativeElement.focus();
        }
        this.chatItemDef.value = '';
        if (this.chatItemDef.pattern === InputPattern.NUMBERPLATE) {
            this.showSubmit=false;
            this.isPlate=true;
            this.placeholder='BE12345';
        }
    }
    validateKeyDownPress (event) {
        if (this.isPlate) {
            if (event.key === 'Backspace') {
                // Execute your logic here.
                let str = event.target.value;
                let pos =event.target.selectionStart;
                str = str.substring(0,pos-1)+str.substring(pos);
                if (this.validateMaskPlate(str)) {
                    return true;
                } else {
                    event.preventDefault();
                    return false;
                }
            } else if (event.key === 'Delete' ) {
                let str = event.target.value;
                let pos =event.target.selectionStart;
                str = str.substring(0,pos)+str.substring(pos+1);
                if (this.validateMaskPlate(str)) {
                    return true;
                } else {
                    event.preventDefault();
                    return false;
                }
            }
        }
    }
    validateKeyPress(event) {
        if (this.isPlate) {
            let str = '';
            str = event.target.value;
            let pos = event.target.selectionStart;
            str = str.substring(0,pos)+String.fromCharCode(!event.charCode ? '' : event.charCode)+str.substring(pos);
            if (this.validateMaskPlate(str)) {
                return true;
            } else {
                event.preventDefault();
                return false;
            }
        }
        return true;
    }
    validateMaskPlate (str) {
            //alert(e.target.selectionStart);
            let regex = new RegExp(this.regexPlateInput);
            let regexSubmit = new RegExp(this.regexPlateSubmit);
            if (regex.test(str)||str.length ===0) {
                if (regexSubmit.test(str)&& str.length>0) {
                    this.showSubmit = true;
                } else {
                    this.showSubmit = false;
                }
                return true;
            } else {
                 return false;
            }
    }
    onPaste(e) {
        e.preventDefault();
        return false;
    }
}

 

Skôr ako začneme: nahliadnite do spracovania vašich osobných údajov

Ak navštívite stránku, ktorá zapisuje cookies, v počítači sa vám vytvorí malý textový súbor, ktorý sa uloží vo vašom prehliadači. Ak rovnakú stránku navštívite nabudúce, pripojíte sa vďaka nemu na web rýchlejšie. Náš web vám ponúkne relevantné informácie a bude sa vám pracovať jednoduchšie.

Súbory cookies používame najmä na anonymnú analýzu návštevnosti a vylepšovanie našich web stránok. Ak si nastavíte blokovanie zápisu cookies do vášho prehliadača, je možné, že web sa spomalí a niektoré jeho časti nemusia fungovať úplne korektne. Viac info k spracúvaniu cookies.