Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": ["src/favicon.ico", "src/assets"],
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss",
"./node_modules/quill/dist/quill.core.css",
"./node_modules/quill/dist/quill.bubble.css",
"./node_modules/quill/dist/quill.snow.css"
],
"scripts": ["node_modules/quill/dist/quill.min.js"],
"scripts": [
"node_modules/quill/dist/quill.min.js"
],
"aot": true
},
"configurations": {
Expand Down Expand Up @@ -87,16 +92,26 @@
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": ["src/styles.scss"],
"styles": [
"src/styles.scss"
],
"scripts": [],
"assets": ["src/favicon.ico", "src/assets"]
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"],
"exclude": ["**/node_modules/**"]
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
Expand All @@ -122,7 +137,9 @@
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": ["**/node_modules/**"]
"exclude": [
"**/node_modules/**"
]
}
}
}
Expand Down Expand Up @@ -156,12 +173,17 @@
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": ["projects/simplified-ui/tsconfig.lib.json", "projects/simplified-ui/tsconfig.spec.json"],
"exclude": ["**/node_modules/**"]
"tsConfig": [
"projects/simplified-ui/tsconfig.lib.json",
"projects/simplified-ui/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "simplified-ui-library"
"defaultProject": "simplified-ui-library",
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<input matInput [placeholder]="placeholder" type="text" [formControl]="currencyValue" required="required" />
<input matInput [placeholder]="placeholder" type="text" [formControl]="currencyValue" [required]="required" />

Original file line number Diff line number Diff line change
@@ -1,73 +1,83 @@
import {
Component,
OnDestroy,
ViewChild,
DoCheck,
ElementRef,
Inject,
Input,
LOCALE_ID,
OnDestroy,
OnInit,
Optional,
Self,
OnInit,
Inject,
LOCALE_ID,
DoCheck
ViewChild
} from '@angular/core';
import { Subject } from 'rxjs';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { FocusMonitor } from '@angular/cdk/a11y';
import { debounceTime } from 'rxjs/operators';
import { formatCurrency, getCurrencySymbol } from '@angular/common';
import {
CurrencyPipe,
getLocaleCurrencyCode, getLocaleCurrencySymbol,
getLocaleNumberFormat, getLocaleNumberSymbol,
NumberFormatStyle, NumberSymbol,
registerLocaleData
} from '@angular/common';
import { MatFormFieldControl } from '@angular/material/form-field';
import { ControlValueAccessor, FormControl, NgControl, Validators } from '@angular/forms';
import { symbolFormatEnum } from '../pipes/sa-value-formatter.pipe';
import { ControlValueAccessor, FormControl, NgControl } from '@angular/forms';

/*
// Register the locale data in the module/component class where this component will be used.
import localeEs from '@angular/common/locales/es';
registerLocaleData(localeEs);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can register locale in the app only

*/

@Component({
selector: 'sa-currency-input',
templateUrl: './sa-currency-input.component.html',
styleUrls: ['./sa-currency-input.component.scss'],
providers: [{ provide: MatFormFieldControl, useExisting: SaCurrencyInputComponent }]
providers: [
CurrencyPipe,
{ provide: MatFormFieldControl, useExisting: SaCurrencyInputComponent },
]
})
export class SaCurrencyInputComponent
implements ControlValueAccessor, MatFormFieldControl<any>, OnInit, OnDestroy, DoCheck {
export class SaCurrencyInputComponent implements ControlValueAccessor, MatFormFieldControl<any>, OnInit, OnDestroy, DoCheck {
@ViewChild('input') inputRef: ElementRef;

@Input() allowNegative: boolean = true;

static nextId = 0;

private decimalSeparator: string;
private groupSeparator: string;

public currencyValue = new FormControl();
stateChanges = new Subject<void>();
private _value: any;
private viewValue: string;
focused = false;
errorState = false;
controlType = 'currency-input';
id = `currency-input-${SaCurrencyInputComponent.nextId++}`;
describedBy = '';
onChange = (_: any) => {};
onTouched = () => {};
private _empty = true;
private symbol: string;
private _disabled = false;
private _placeholder: string;

constructor(
private _focusMonitor: FocusMonitor,
private _elementRef: ElementRef<HTMLElement>,
@Optional() @Self() public ngControl: NgControl,
@Inject(LOCALE_ID) private locale: string
) {
this.decimalSeparator = '.';
this.symbol = getCurrencySymbol('USD', symbolFormatEnum.narrow);
onChange = (_: any) => {};
onTouched = () => {};

constructor(private _focusMonitor: FocusMonitor, private _elementRef: ElementRef<HTMLElement>, @Optional() @Self() public ngControl: NgControl, @Inject(LOCALE_ID) private locale: string,private currencyPipe: CurrencyPipe) {

this.groupSeparator = getLocaleNumberSymbol(this.locale, NumberSymbol.CurrencyGroup);
this.decimalSeparator = getLocaleNumberSymbol(this.locale, NumberSymbol.CurrencyDecimal);

_focusMonitor.monitor(_elementRef, true).subscribe((origin) => {
if (this.focused && !origin) {
if (this.viewValue) {
if (this.parse(this.viewValue))
this.currencyValue.patchValue(formatCurrency(parseFloat(this.parse(this.viewValue)), 'en-US', this.symbol));
else this.currencyValue.patchValue('');

if(this.currencyValue.value != null) {
if (origin) {
this.currencyValue.setValue(this.parse(this.currencyValue.value));
}
this.onTouched();
} else {
if (this._value) {
this.currencyValue.patchValue(this.parse(this._value));
else {
this.currencyValue.setValue(currencyPipe.transform(this.parse(this.currencyValue.value), getLocaleCurrencyCode(this.locale)));
}
}
this.focused = !!origin;
Expand All @@ -79,13 +89,6 @@ export class SaCurrencyInputComponent
}
}

ngOnInit() {
this.currencyValue.valueChanges.pipe(debounceTime(200)).subscribe((num) => {
this.viewValue = num;
this.value = this.parse(num);
});
}

ngDoCheck(): void {
if (this.ngControl) {
this.errorState = this.ngControl.invalid && this.ngControl.touched;
Expand All @@ -98,12 +101,21 @@ export class SaCurrencyInputComponent
this._focusMonitor.stopMonitoring(this._elementRef);
}

ngOnInit() {
this.currencyValue.valueChanges.pipe(debounceTime(200)).subscribe((num) => {
this.value = this.parse(num);
});
}

get empty() {
return this._empty;
}

get shouldLabelFloat() {
return this.focused || !this.empty;
if (!this.focused) {
return this.currencyValue.value !== null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use this.empty instead of checking null?

}
return true;
}

@Input()
Expand All @@ -119,10 +131,12 @@ export class SaCurrencyInputComponent
get required(): boolean {
return this._required;
}

set required(value: boolean) {
this._required = coerceBooleanProperty(value);
this.stateChanges.next();
}

private _required = false;

@Input()
Expand All @@ -142,11 +156,7 @@ export class SaCurrencyInputComponent

set value(val: string | null) {
this._value = val;
if (this._value != null && this._value !== '') {
this._empty = false;
} else {
this._empty = true;
}
this._empty = !(this._value != null && this._value !== '');
this.onChange(this._value);
this.stateChanges.next();
}
Expand All @@ -160,7 +170,7 @@ export class SaCurrencyInputComponent
writeValue(val: string | null): void {
if (val != null) {
this._empty = false;
this.currencyValue.patchValue(formatCurrency(parseFloat(val), 'en-US', this.symbol));
this.currencyValue.setValue(this.currencyPipe.transform(this.parse(val),getLocaleCurrencyCode(this.locale)))
}
this.value = val;
}
Expand All @@ -182,10 +192,12 @@ export class SaCurrencyInputComponent
}

parse(value: string) {
let [integer, fraction = ''] = (value.toString() || '').split(this.decimalSeparator);
const temp = value.toString().replace(getLocaleCurrencySymbol(this.locale), '');
let [integer, fraction = ''] = (temp.toString() || '').split(this.decimalSeparator);
integer = integer.replace(new RegExp(/[^\d\.]/, 'g'), '');
integer = integer.replace(this.groupSeparator, '');
fraction = parseInt(fraction, 10) > 0 && 2 > 0 ? this.decimalSeparator + (fraction + '000000').substring(0, 2) : '';
if (this.allowNegative && (value.toString() || '').startsWith('-')) {
if (this.allowNegative && (temp.toString() || '').startsWith('-')) {
return (-1 * parseFloat(integer + fraction)).toString();
} else {
return integer + fraction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
HostBinding,
ViewChild,
Output,
EventEmitter
EventEmitter, LOCALE_ID, Inject
} from '@angular/core';
import { ControlValueAccessor, NgControl, FormControl } from '@angular/forms';
import { MatFormFieldControl } from '@angular/material/form-field';
Expand All @@ -20,6 +20,7 @@ import { DatePickerConfig, DatePickerType } from '../models/DatePickerConfigMode
import * as moment_ from 'moment-timezone';
const moment = moment_;
import { MOMENT_FORMATS } from '../pipes/sa-date-time.pipe';
import { DateTimeAdapter } from '@danielmoncada/angular-datetime-picker';

@Component({
selector: 'sa-date-picker',
Expand Down Expand Up @@ -149,8 +150,11 @@ export class SaDatePickerComponent
constructor(
@Optional() @Self() public ngControl: NgControl,
private fm: FocusMonitor,
private elRef: ElementRef<HTMLElement>
private elRef: ElementRef<HTMLElement>,
@Inject(LOCALE_ID) private locale: string, /// Getting LOCALE_ID of our app. (manually set to 'en-IN' in app.module for testing)
dateTimeAdapter: DateTimeAdapter<any> /// Injecting DateTimeAdapter to change date time picker's locale
) {
dateTimeAdapter.setLocale(this.locale); // Setting our app's LOCALE_ID as date time picker's locale.
if (this.ngControl != null) {
// Setting the value accessor directly (instead of using
// the providers) to avoid running into a circular import.
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ <h3> Button Component </h3>
<h3> Currency Inpput Component </h3>
<mat-form-field>
<mat-label>Currency</mat-label>
<sa-currency-input></sa-currency-input>
<sa-currency-input [formControl]='formControl'></sa-currency-input>
</mat-form-field>

<h3> Filter Component </h3>
Expand Down
2 changes: 2 additions & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export class AppComponent implements OnInit {

dateFormats = DateFormats;

formControl: FormControl = new FormControl(1234);

date = moment.tz(moment(), moment.tz.guess()); //current timezone
date1 = moment.tz(moment(), 'America/Toronto'); //string timezone
date2 = moment.tz(); //UTC timezone
Expand Down