Regulation specifying a cap of 100.00 on decimal numbers entered into a text input field (Regex)

I have created a directive that restricts text input to only decimal numbers in the text field.

Below is the code for the directive:

 import { HostListener, Directive, ElementRef } from '@angular/core';

@Directive({
    exportAs: 'decimal-number-directive',
    selector: 'decimal-number-directive, [decimal-number-directive]',
})
export class DecimalNumberDirective {
    private regex: RegExp = new RegExp(/^\d*\.?\d{0,2}$/g);
    private specialKeys: string[] = ['Backspace', 'Tab', 'End', 'Home'];
    constructor(private el: ElementRef) {}
    @HostListener('keydown', ['$event'])
    onKeyDown(event: KeyboardEvent): void {
        if (this.specialKeys.indexOf(event.key) !== -1) {
            return;
        }

        const current: string = this.el.nativeElement.value;
        const next: string = current.concat(event.key);
        if (next && !String(next).match(this.regex)) {
            event.preventDefault();
        }
    }
}

Here is an example of its usage:

<div class="col-2 pr-0">
                        <label>{{ l('Percent') }}</label>
                        <input
                            class="form-control"
                            type="text"
                            decimal-number-directive
                            name="percent"
                            [(ngModel)]="inquiryItemToAdd.percent"
                            maxlength="64"
                            (ngModelChange)="setTotalPrice()"
                            [readOnly]="!inquiryItemToAdd.servicePriceId || !servicePrice.isPriceCalculated"
                        />
                    </div>

However, I am facing a challenge where I can still input values like 155.00 or 155.56. I aim to limit it to 100.00 as I am using this for writing percents.

I attempted to use the following regex

private regex: RegExp = new RegExp(/^(\d{1,2}(\.\d{1,2})?)|(100(\.0{1,2})?)$/g);
, but I am still able to input values exceeding 100 percent.

Any suggestions on how to solve this issue?

Answer №1

Positive numbers should be matched from 0 to 100, including decimal values like 0.0 and 100.00

Regex:

^(\d{1,2}|\d{1,2}\.\d{1,2}|100\.[0]{1,2}|100)$

https://regex101.com/r/S9fbY7/3


Update:

Allow the use of a dot in the input field as it is not valid when entered alone. Only validate on blur if the value ends with a dot.

Ignored Keys:

private specialKeys: string[] = ['Backspace', 'Tab', 'End', 'Home', '.'];

For validation on Blur:

if (val.endsWith('.')) {
  // Option 1: Remove the dot
  this.el.nativeElement.value = val.substring(0, val.length - 1); 

  // Option 2: Add '00' after the dot
  this.el.nativeElement.value = val + '00'; 

  // Option 3: Clear the entire value
  this.el.nativeElement.value = ''; 
}

Final Code:

import { HostListener, Directive, ElementRef } from '@angular/core';

@Directive({
  exportAs: 'decimal-number-directive',
  selector: 'decimal-number-directive, [decimal-number-directive]',
})
export class DecimalNumberDirective {
  private regex: RegExp = new RegExp(/^(\d{1,2}|\d{1,2}\.\d{1,2}|100\.[0]{1,2}|100)$/g);
  private specialKeys: string[] = ['Backspace', 'Tab', 'End', 'Home', '.'];
  constructor(private el: ElementRef) { }
  
  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent): void {
    if (this.specialKeys.indexOf(event.key) !== -1) {
      return;
    }

    const current: string = this.el.nativeElement.value;
    const next: string = current.concat(event.key);
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }

  @HostListener('blur', [])
  onBlur(): void {
    const val = this.el.nativeElement.value;
    if (val.endsWith('.')) {
      this.el.nativeElement.value = val.substring(0, val.length - 1); // Option 1: Remove the dot
      // this.el.nativeElement.value = val + '00'; // Option 2: Add '00' after the dot
      // this.el.nativeElement.value = ''; // Option 3: Clear the entire value
    }
  }
}

Answer №2

Experiment with this regular expression:

^ :- This will verify that the string always begins with 100
[0]{2} :- This ensures that after the decimal point, there are exactly 2 zeros.

private regex: RegExp = /^100\.[0]{2}/gm;

You can see the outcome here.

Answer №3

The solution seems to be this specific pattern: ^(\d{0,2}(.\d{1,2})?|100(.00?)?)$

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble with importing SendInBlue into my NodeJS application?

Currently in the process of updating my Node app to utilize ES6 import modules over requiring files. Encountering difficulties while trying to integrate this change with SendInBlue for email functionality, resulting in the following error message: TypeEr ...

Building a collapsible toggle feature with an SVG icon using HTML and CSS

I am trying to swap a FontAwesome Icon with a Google Materials SVG Icon when a collapsible table button toggle is pressed (changing from a down arrow to an up arrow). I have been struggling to get the Google Material Icons code to work. How can I resolve t ...

Sharing environment variables between a React app and an Express.js server that hosts it as a static site can be achieved by setting

My static site react app is hosted under an express server project in a folder called client/build. The oauth redirect uris point to the express server for token retrieval. The react app redirects users to the oauth endpoint, which is also referenced by th ...

Generating automatic generic types in Typescript without needing to explicitly declare the type

In the scenario where I have an interface containing two functions - one that returns a value, and another that uses the type of that value in the same interface - generics were initially used. However, every time a new object was created, the type had to ...

Place an image at the center with a height set to 100% within a div that has a fixed height and

Apologies for asking about this topic again, but I have been unable to find a solution where the image fills 100% of the height. If you'd like to see the issue in action, here's a link to the jsfiddle: http://jsfiddle.net/BBQvd/3/ I'm just ...

Having trouble interpreting PHP-generated JSON data in JavaScript

I have a PHP script that outputs a JSON string. <?php $arr = array( 'id' => '1', 'myarray' => array( array('a' => 'a1', 'b' => 'b1', 'c' => 'c1', & ...

The $.inArray() function returns a value of false or -1, despite the fact that the variable

My goal is to verify that my currentMedia variable (which exists in the DOM) can be located within my array media, and then return the index i, which should be 0 instead of -1. When I execute console.log(media[0]); and console.log(currentMedia);, the outc ...

How can we handle multiple asynchronous calls within a function?

In the process of developing a dynamic page with heavy AJAX interactions that update values in selectors based on prior selections. Currently, working on implementing a "repopulate" feature to fill in selectors based on previous entries. Whenever Selector ...

What is the best way to access a property within a typescript object?

I'm working with the following code snippet: handleSubmit() { let search = new ProductSearch(); search = this.profileForm.value; console.log(search); console.log(search.code); } When I run the console.log(search) line, it outputs: ...

The object literal can only define properties that are already known, and 'data' is not found in the type 'PromiseLike<T>'

When making a request to a server with my method, the data returned can vary in shape based on the URL. Previously, I would cast the expected interface into the returned object like this: const data = Promise.resolve(makeSignedRequest(requestParamete ...

The URL routing in Vue-router seems to be incorrect as it directs to the wrong page. To fix this issue, make sure to include a '#' before the

Welcome to my website! Check out my home page here: https://i.sstatic.net/znfq0.jpg If you're interested in reading my blog, visit the blog page here: https://i.sstatic.net/oiYSY.png I've built this site using vue3. Here's a snippet of th ...

What could be causing the change event to be triggered in a v-text-field when I press enter, despite not making any changes?

How come the @change event triggers in a v-text-field when I press enter, even if I haven't made any changes? HTML <div id="app"> <v-app> <v-content> <v-container> <v-text-field @change=" ...

Using the typeof operator to test a Typescript array being passed as an object

I have a puzzling query about this particular code snippet. It goes like this: export function parseSomething(someList: string[]): string[] { someList.forEach((someField: string) => { console.log(typeof someField) }) Despite passing a s ...

Issue with scrolling feature in div

I am currently facing an issue with scrolling on my website. Visit this site to see the problem. When scrolling down, it causes the "hidden" part of the site to slide up. I want to achieve a similar sliding effect, but it needs to be smooth. I have attempt ...

How to access the state of an @ngrx/data entity in a reducer function in ngrx 8

I am trying to access the state of a ngrx/data entity within a reducer function. Currently, I am working on implementing a pager (pagination) feature where users can navigate through different pages. However, I am facing a challenge in determining the tot ...

Display the menu and submenus by making a request with $.get()

My menu with submenu is generated in JSON format, but I am facing issues displaying it on an HTML page using the provided code. Can someone please assist me in identifying what mistakes I might be making? let HandleClass = function() { ...

What is causing JS to malfunction and preventing App Scripts from running `doGet()` when using either `e` or `event` as parameters?

Following a Basic Web App video last night, I meticulously followed every step until the very end where things started to go wrong. Today, I decided to start from scratch and recreate it all. Despite weeks of coding practice, I can't seem to figure ou ...

methods to retrieve value from a javascript function

Just a quick inquiry - what's the best way to pass or return a value from a function? Here is my code: function numberOfDivs(){ var numberOfElements = $("#div").children().length; // Counting the number of existing divs return numberOfElements; } ...

Generate a new entry by analyzing components from a separate array in a single line

I have a list of essential items and I aim to generate a record based on the elements within that list. Each item in the required list will correspond to an empty array in the exist record. Essentially, I am looking to condense the following code into one ...

Ways to declare the function prototype using object and key as parameters

I am currently working on defining a utility function that will handle axios errors and store the resulting error message into a specific field of a specified object. The desired syntax for using this function is: axios.get(...).then(...).catch(ParseIntoE ...