Search code examples
angulartypescriptangular2-material

Handling dollars in Angular 2 Material Slider


I have a form in my Angular 2 Material application with, among other things, a price field modeled as a slider with a maximum, minimum, and step:

  <md-input type="range"
      [min]="minimumPrice"
      [max]="maximumPrice"
      [step]="priceTick"
      class="slider">

Prices are modeled in cents (i.e. with no fractions), but the front-end should display prices in dollars, e.g., a price of 12345 cents with a maximum of 50000 cents, a minimum of 0 cents, and a step of 5 cents looks like this now:

                12345
       0 |---------*---------------| 50000

              in steps of 5

but it should be displayed in terms of dollars:

                $123.45
   $0.00 |---------*---------------| $500.00

              in steps of $0.05

The form and slider work when displayed cents, but how can I get the slider to behave and display correctly with values in dollars?

The back-end price model is a long which is sent to the front-end as a long value (i.e., with no fractions) but I'm willing to change what I send to the front-end to simplify handling, if need be. So, the general question is: what's the simplest way to get md-input to display dollars correctly, and behave correctly?


Solution

  • Without being entirely familiar with Angular2 Material I would venture using the CurrencyPipe combined with a template variable for the slider if you're eschewing model binding:

    <md-input type="range" name="slider"
      [min]="minimumPrice"
      [max]="maximumPrice"
      [step]="priceTick"
      #slider
      class="slider" [placeholder]="slider.value | customCurrency">
        <span md-prefix>{{slider.min | customCurrency}}</span>
        <span md-suffix>{{slider.max | customCurrency}}</span>
    </md-input>
    

    The layout is probably incorrect but that is the gist of it, and you can muck around with this Plunker http://plnkr.co/edit/Fj3hDJmwRD4SvzlKu6R6?p=preview

    Here's a very simple custom extension of the CurrencyPipe to remove the /100 and set formatting:

    custom-currency.pipe.ts

    import {Pipe, PipeTransform} from '@angular/core';
    import {CurrencyPipe} from '@angular/common';
    
    @Pipe({
        name: "customCurrency"
    })
    export class CustomCurrencyPipe implements PipeTransform {
    
        constructor(private currencyPipe: CurrencyPipe) {}
    
        transform(value: any): string {
          return this.currencyPipe.transform(value / 100, 'USD', true);
        }
    }
    

    module.ts

    import {CustomCurrencyPipe} from "[location]/custom-currency.pipe";
    import {CurrencyPipe} from "@angular/common";
    
    @NgModule({<...>, declarations: [<...>, CustomCurrencyPipe], providers: [<...>, CurrencyPipe]})