Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if string contains only digits and dots (.)

I need to use a fields as a String and I want that the user should be able to add only digits and dots. and I am looking on the net and is hard to find something, can anyone give me a hand I would really appreciate that. Thanks in advance !!

like image 890
Ilia Tapia Avatar asked Jan 25 '23 21:01

Ilia Tapia


2 Answers

I can suggest you to use regex to validate the string. The below regex will allow only digits and .

/[^.0-9]+/g

I you want to validate only digits, then you can use below expression.

/[^0-9]+/g

Feel free to ask queries...

like image 88
Venkata Sai Katepalli Avatar answered Jan 28 '23 11:01

Venkata Sai Katepalli


Note: All the solutions which simply use patterns, still allow the user to type restricted symbols, and then mark them as invalid.

If you'd like to prevent typing invalid characters, then you can use the solution below.

It's a component that doesn't even allow to type any other character than digits and dots,
and always makes sure that the input is a number before inserting the character into the input.

Also, it doesn't allow to type invalid numbers like "45..3" "3.4..4" using those characters.
Bonus Feature 1: It works fine with mobile (since doesn't look for Keydown/Keyup events).
Bonus Feature 2: It doesn't allow to copy paste invalid text as well.

import { Component, Input, forwardRef } from '@angular/core';

import {
  NG_VALUE_ACCESSOR,
  NG_VALIDATORS,
  Validator,
  FormControl,
  ValidationErrors,
  ControlValueAccessor
} from '@angular/forms';

@Component({
  selector: 'numeric-input',
  template: '<input type="text" inputmode="numeric" [placeholder]="placeHolderText" [ngModel]="inputValue" (input)="onInputChange($event)">',
  providers: [
  {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => NumericInputComponent),
    multi: true
  },
  {
    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => NumericInputComponent),
    multi: true
  }]
})
export class NumericInputComponent implements ControlValueAccessor, Validator {
  @Input() public placeHolderText = '';
  @Input() public isRequired = false;

  public inputValue: string;

  public onInputChange(event: any): void {
    const newValue = event.target.value;
    if (!this.isValidInput(newValue)) {
      // Invalid input detected. Resetting to previous value
      event.target.value = this.inputValue;
    } else if (newValue !== this.inputValue) {
      // New valid input detected.
      this.inputValue = newValue;
      this.propagateChange(this.inputValue);
    }
  }

  //#region Custom validation

  // Note: Used the mechanism described in the link below
  // https://medium.com/@tarik.nzl/angular-2-custom-form-control-with-validation-json-input-2b4cf9bc2d73

  // Called for setting the initial value
  public writeValue(value: string): void {
    if (this.isValidInput(value) && this.inputValue !== value) {
      this.inputValue = value;
    }
  }

  // Validates the form, returns null when valid else the validation object
  public validate(formControl: FormControl): ValidationErrors {
    return (this.isRequired && !this.inputValue) ? { required: true } : null;
  }

  // Registers function that will be fired when changes are made.
  public registerOnChange(callbackFunction: (newValue: string) => void): void {
    this.propagateChange = callbackFunction;
  }

  // Non-implemented method which are required by the validator interface
  public registerOnTouched(callbackFunction: () => void): void { }

  // The method set in registerOnChange to emit changes back to the form
  private propagateChange = (newValue: string) => { };

  private isValidInput(value: string): boolean {
    // Note: ParseInt is not recommended as it will convert "222aa" -> "222" and assume as valid
    return !isNaN(Number(value));
  }

  //#endregion Custom validation
}

Usage:

<numeric-input [(ngModel)]="ModelNameHere">
</numeric-input>

Note: You might consider moving out the html template of the component outside the component.ts file to separate html file and use templateUrl instead (like it's done in the samples below).

Here is a quick code sample and demo on stackblitz just in case it's needed.
And here is a sample for angular material.

like image 25
Just Shadow Avatar answered Jan 28 '23 11:01

Just Shadow