How to display currency input in Angular 2

Is there a way to dynamically format input as USD currency while typing? The input should have 2 decimal places and populate from right to left. For example, if I type 54.60 it should display as $0.05 -> $0.54 -> $5.46 -> $54.60. I found this PLUNKER that achieves this using AngularJS, but I'm looking for a solution in a different framework. This is what my directive currently looks like:

import {Directive, Output, EventEmitter} from '@angular/core';
import {NgControl} from '@angular/forms';

@Directive({
  selector: '[formControlName][currency]',
  host: {
    '(ngModelChange)': 'onInputChange($event)',
    '(keydown.backspace)':'onInputChange($event.target.value, true)'
  }
})
export class CurrencyMask {
  constructor(public model: NgControl) {}

  @Output() rawChange:EventEmitter<string> = new EventEmitter<string>();

  onInputChange(event: any, backspace: any) {
    // remove all mask characters (keep only numeric)
    var newVal = event.replace(/\D/g, '');
    var rawValue = newVal;
    var str = (newVal=='0'?'0.0':newVal).split('.');
    str[1] = str[1] || '0';
    newVal= str[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') + '.' + (str[1].length==1?str[1]+'0':str[1]);

    // set the new value
    this.model.valueAccessor.writeValue(newVal);
    this.rawChange.emit(rawValue)
  }
}

And here is how it's being used in HTML:

<input  name="cost" placeholder="cost" class="form-control"  type="text" currency formControlName="cost" (rawChange)="rawCurrency=$event">

Update:

This is the final implementation that worked for me:

onInputChange(event: any, backspace: any) {
    var newVal = (parseInt(event.replace(/[^0-9]/g, ''))/100).toLocaleString('en-US', { minimumFractionDigits: 2 });
    var rawValue = newVal;

    if(backspace) {
      newVal = newVal.substring(0, newVal.length - 1);
    }

    if(newVal.length == 0) {
      newVal = '';
    }
    else  {
      newVal = newVal;
    }
    // set the new value
    this.model.valueAccessor.writeValue(newVal);
    this.rawChange.emit(rawValue)
  }

Answer №1

When the input changes, implement the following code snippet:

// Eliminate dots and commas, for example: 123,456.78 -> 12345678
var strVal = myVal.replace(/\.,/g,'');
// Convert string to integer
var intVal = parseInt(strVal); 
// Divide by 100 to get 0.05 when pressing 5 
var decVal = intVal / 100;
// Format value to en-US locale
var newVal = decVal.toLocaleString('en-US', { minimumFractionDigits: 2 });

// Alternatively, you can do it in a single line:
var newVal = (parseInt(myVal.replace(/\.,/g, '')) / 100).toLocaleString('en-US', { minimumFractionDigits: 2 });

Or,

Utilize the currency pipe to format to USD by simplifying it to:

var newVal = (parseInt(myVal.replace(/\.,/g, '')) / 100)

I hope this explanation helps.

Answer №2

One of the helpful features in Angular is its formatCurrency method.

Check it out here

In my code, I have implemented this method as follows:

Using a formControl named demand

formatMoney(value: string) {
    this.demand.setValue(
        this.formatMoneyBase(value)
    );
}

formatMoneyBase(value: string = ''): string {
    return value.length ? formatCurrency(parseFloat(value.replace(/\D/g, '')), 'en', '$').replace('$', '') : '';
}

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

Tips on ensuring Angular calls you back once the view is ready

My issue arises when I update a dropdown list on one of my pages and need to trigger a refresh method on this dropdown upon updating the items. Unfortunately, I am unsure how to capture an event for this specific scenario. It seems like enlisting Angular ...

What is the best way to modify the state of a particular element in an array when using useState in React?

In my Next.js application, I am using a useState hook to manage state. Here is how my initial state looks like: const [sampleData, setSampleData] = useState({ value1: '', value2: '', value3: [] }); To update the state ...

Issue encountered while trying to run `npm install` on an angular-cli

I recently moved my angular-cli project with node modules to a new directory. Upon running npm install, I encountered the following warnings: npm WARN deprecated <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e2838c85978e8 ...

Updating to a newer version of jQuery causes issues with pop-out submenus

Looking for a way to create a menu with pop-out submenus? Here's an example using jQuery: <script type="text/javascript"> $(document).ready(function() { var hoverAttributes = { speed: 10, delay: 1 ...

HTML forms default values preset

I need help with pre-setting the values of a dropdown menu and text box in an HTML form for my iPhone app. When the user taps a button, it opens a webview and I want to preset the dropdown menu and text field. Can someone guide me on how to achieve this? ...

Is it possible for TypeScript to manage a dynamic return type that is not determined by a function parameter?

I am facing a challenge with dynamic type checking using a param type and seeking help to solve it. Even though it might be a difficult task, any assistance would be greatly appreciated! Consider the following code: class DefaultClass { defaultProp: n ...

Angular 10 does not fulfill promises as expected

In the Angular 10 project I'm working on, I encountered an issue while trying to call an API request asynchronously using promises. The code I wrote didn't seem to execute the API call as expected and kept exiting at the first line without progre ...

Ways to display a popup when hovering over a marker in ngx-mapbox-gl

I have a current implementation that displays markers and popups on click of markers. We now need to update it to show popups on hover instead. Here is the structure of my template: <mgl-map #map1 [style]="'mapbox://styles/mapbox/streets ...

What is the best way to integrate my custom JavaScript code into my WordPress theme, specifically Understrap?

I am looking to enhance my website with a sticky navbar positioned directly under the header, and I want it to stick to the top of the page as users scroll down. Additionally, I want the header to disappear smoothly as the user scrolls towards the navbar. ...

Tips for adjusting column positions in a table while maintaining a fixed header and utilizing both horizontal and vertical scrolling

Is there a way to display a table that scrolls both horizontally and vertically, with the header moving horizontally but not vertically while the body moves in both directions? I have been able to shift the position of the columns, however, I am struggling ...

Module or its corresponding type declarations not found in the specified location.ts(2307)

After creating my own npm package at https://www.npmjs.com/package/leon-theme?activeTab=code, I proceeded to set up a basic create-react-app project at https://github.com/leongaban/test-project. In the src/index.tsx file of my react app, I attempted to im ...

Combining vueJS and webpack to bring in fonts, CSS styles, and node_modules into your project

I've recently started working with Vue.js and Webpack, and I'm facing some challenges regarding the correct way to import and reference fonts, CSS, and node_modules in my project. My project structure looks like this, as set up by vue-cli: buil ...

The jQuery included does not function properly in production mode and results in an error stating that it is not a function

After placing the jquery.placeholder.js file in the assets/javascripts folder, I successfully applied the function in my coffeescript file and it worked perfectly. $(document).ready -> $('input, textarea').placeholder(); However, when swit ...

Debate surrounding the use of .next() in conjunction with takeUntil

Recently, I've observed a change in behavior after updating my rxjs version. It seems that the .next() method this.ngUnsubscribe$.next(); is no longer functioning as it used to: export class TakeUntilComponent implements OnDestroy { // Our magical o ...

I keep running into an issue whenever I attempt to import material ui icons and core - a frustrating error message pops up stating that the module cannot be found

[I keep encountering this error message when attempting to utilize @material-ui/core and icons] `import React from "react"; import "./Sidebar.CSS"; import SearchIcon from "@material-ui/icons/Search"; const Sidebar = () => { return ( <> ...

Fresh ajax requests are not clearing the current data displayed in the JSP table

My ajax function retrieves data from a servlet and displays it in the page successfully. However, each time a new ajax call is made, the form appends the new data to the existing results instead of replacing them. I need to reset the current values stored ...

Issue: Unable to assign type 'FormDataEntryValue' to type 'string'. Type 'File' cannot be assigned to type 'string'

After retrieving data from the formData, I need to pass it to a function for sending an email. Error: The error message states that 'FormDataEntryValue' is not compatible with type 'string | null'.ts(2322) definitions.ts(119, 3): The e ...

Disabling pointer-events on material-ui textField input is ineffective

I have a material-ui textField input and I want to prevent the user from entering text by setting the css to pointer-events: none. However, this method does not work as expected. While I am aware that I can use the disabled={true} flag to disable the inpu ...

How to Round Decimals in DataTables

I am encountering an issue with my data table's footer, which is supposed to display the sum of each column. However, while the values within the table are rounded to two decimal places, the values in the footer do not always adhere to this formatting ...

Confusion surrounding asynchronous functions in Node.js

When handling routes or endpoints with multiple operations, I often encounter scenarios where I need to perform additional actions. For instance, when deleting an item, it's necessary to also remove the related file from S3 along with deleting the col ...