How to set two decimal places of input fields? - html

I'm working with Angular2 and TypeScript. I have input fields values set in .ts file. When I run my application it displays them as whole numbers and I will like to display them as two decimals for example 8.00 instead of just 8.
Here is part of my .ts file:
ngOnInit() {
if (!this.phast.operatingCosts) {
let defaultCosts: OperatingCosts = {
fuelCost: 8.00,
steamCost: 10.00,
electricityCost: .080
}
this.phast.operatingCosts = defaultCosts;
this.startSavePolling();
}
}
I'm using ngModel. Here is one input field .html:
<div class="input-group">
<input name="electricityCost" type="number" step="any" class="form-control" id="electricityCost" (input)="startSavePolling()"
[(ngModel)]="phast.operatingCosts.electricityCost">
<span class="units input-group-addon">$/kWh</span>
</div>

You can use a custom filter like
function decimalValue($filter) {
return (input, size) => {
return $filter('number')(input, size)
};
}

Related

Angular input's ngModel and Value don't work together

I have a problem with the form in angular. My goal is to make a form that is filled with default values ​​that can be changed. After validating the form, it sends the data to the MySQL database.
This is component.html code:
<form #adopt="ngForm" (ngSubmit)="success()">
<label for="email">Email:</label>
<input type="email" name="email" [(ngModel)]="adoptions.email" #email="ngModel">
<label for="animal">Twój wybór to:</label>
<input type="text" name="animal" [(ngModel)]="adoptions.animal" #email="ngModel">
<button [disabled]="adopt.form.invalid" type="submit">Adoptuj</button>
<button (click)="getAnimal('')" class="disable">Odznacz swój wybór</button>
</form>
This is typeScript code:
export class AdoptpageComponent implements OnInit {
adoptions = new Adoptions();
sessionValue
animal
value
msg='';
constructor(private userService: UserService, private shared: SharedService, private _service
: AdoptService, private _router : Router) {
}
ngOnInit(): void {
this.getUsers();
this.sessionValue = sessionStorage.getItem('email');
}
getAnimal(arg) {
this.animal = arg;
}
success() {
this._service.create(this.adoptions).subscribe(
data => {
console.log("dziala");
this._router.navigate(['/adopt'])
},
error => {
console.log("nie dziala");
this.msg = error.error;
}
)
}
}
The code I posted above works, but only when I enter the value into the form from the keyboard. I want the value from sessionValue to be retrieved automatically in the first form and animal in the second. I managed to achieve it when instead of ngModel I entered:
<input type="email" name="email" [value]="sessionValue" #email="ngModel">
But then the form does not work (it does not send data to the database). Unfortunately, when both are used, [value] = "sessionValue" does not work
<input type="email" name="email" [value]="sessionValue" [(ngModel)]="adoptions.email" #email="ngModel">
do you have an idea what to do to be able to submit the form with the default value?
first: you are binding adoptions.email and adoptions.animal to ngModel, but they are empty(or even worse - null or undefined) when ngOnInit is fired, that is why your inputs are empty. They get value once you introduce text in inputs, that is why you are able to successfully execute this._service.create
second: you are causing a value binding conflict. The source of ngModel is different from the source of value. Once ngOnInit is fired value tries to load the value of sessionValue in input and ngModel tries to load nothing, as its source is empty
There is no need to use value if you have ngModel. You just have to set up start point value for its source variable. like below example
ngOnInit(): void {
adoptions.email = somehowGetEmail()
adoptions.animal= somehowGetAnimal()
}
And that's all you have to do, if you insist on using ngModels.
But in general this looks like a lot of unnccessary bindings. Since these are a form inputs you should be using form's preimplemented features for value bindings. Check docs for angular FormBuilder, formControl

Iterate over array of objects and display key and value for each object in ngFor in Angular 12

In an Angular 12 app the data returned from an API is
data = {
"options":[
{
"Yes": 1
},
{
"No": 0
}
]
}
My requirement is to iterate over this array and display radio buttons dynamically in the html as shown below.
<div *ngFor="let option of data.options;">
<input type="radio" class="form-control" name="rdgroup" value="{{option.key}}">
<label>{{option.value}}</label>
</div>
I want display labels for radio buttons to be 'Yes' and 'No' and their values should be 1 and 0 respectively. Currently nothing is displayed. How do I fix it?
You will need to modify you data in order to render radio buttons.
Check this stackblitz: https://stackblitz.com/edit/angular-material-with-angular-sidenav-spz9oq?file=app/app.component.html
Use the below method on your component:
options = this.data.options.map( (op) => {
const key = Object.keys(op)[0];
return {
"value" : Object.keys(op)[0],
"key": op[key]
}
});
and in template
<div *ngFor="let option of options;">
<input type="radio" class="form-control" name="rdgroup" value="{{option.key}}">
<label>{{option.value}}</label>
</div>
You can try in this way, It may help you to get expected output!
edit your component.ts file, and add below defined method.
getEntrires(object: any) {
return Object.entries(object);
}
this method will return you Object entry with it's KEY & VALUE in Array
For Example:
let output = getEntrires({"Yes": 1});
console.log(output) // [Array[2]] => it will be two dimensional array
Now in your html you can consume this in this way
<div *ngFor="let option of data.options;">
<input type="radio" class="form-control" name="rdgroup" value="{{getEntrires(option)[0][1]}}">
<label>{{getEntrires(option)[0][0]}}</label>
</div>

Angular change displayed value

I have an input that retrieve a numeric value. I would like to change the display on the html side, basically if the variable equals to let s say 7 the value displayed becomes 'abcdefg' instead of 7. On the contrary if I type abcdefg I would like for the form to understand that the value that should be stored is 7 and not the string. Is there a way to do that only on the HTML side ?
<div class="col-6">
<mat-form-field>
<input matInput placeholder="Cardinality Max" required #asbiepCardinalityMax
(change)="changeMax(asbiepCardinalityMax.value)"
(focus)="focusInMax(asbiepCardinalityMax.value)"
[(ngModel)]="asAsbiepDetail().cardinalityMax"
(ngModelChange)="onChange()"
[disabled]="!isEditable() || !asAsbiepDetail().used"
(keypress)="numberOnly($event)">
</mat-form-field>
</div>
You want to separate out the logic for controller to view binding and view to controller. You want to add separate functions for updating and reading. You can either add an event handler to set the value onChange and remove the () from the ngModel (removing the view -> controller updating), or use typescript getters and setters to bind to one value, with different logic.
Option 1:
HTML:
<div class="col-6">
<mat-form-field>
<input matInput placeholder="Cardinality Max" required #asbiepCardinalityMax
(change)="changeMax(asbiepCardinalityMax.value)"
(focus)="focusInMax(asbiepCardinalityMax.value)"
[ngModel]="fieldValue()"
(ngModelChange)="onChange()"
(change)="setFieldValue($event)"
[disabled]="!isEditable() || !asAsbiepDetail().used"
(keypress)="numberOnly($event)">
</mat-form-field>
</div>
Controller:
#Component({})
export class Controller {
realValue: number = 7;
setFieldValue($event) {
let newValue = $event.target.value;
//Code here to turn newValue into something correct for real value
if (newValue == 'abcdefg') {
realValue = 7;
}
}
fieldValue(): string {
if (realValue === 7) {
return 'abcdefg';
}
};
}
Option 2:
HTML:
<div class="col-6">
<mat-form-field>
<input matInput placeholder="Cardinality Max" required #asbiepCardinalityMax
(change)="changeMax(asbiepCardinalityMax.value)"
(focus)="focusInMax(asbiepCardinalityMax.value)"
[(ngModel)]="fieldValue"
(ngModelChange)="onChange()"
[disabled]="!isEditable() || !asAsbiepDetail().used"
(keypress)="numberOnly($event)">
</mat-form-field>
</div>
Controller:
#Component({})
export class Controller {
realValue: number = 7;
set FieldValue(newValue): void {
//Code here to turn newValue into something correct for real value
if (newValue == 'abcdefg') {
realValue = 7;
}
}
get fieldValue(): string {
if (realValue === 7) {
return 'abcdefg';
}
};
}
And then you use realValue where you want.
The advantage of the first is you can pick what event you want to fire the function that sets the value on the controller - you might want change, keyup, keydown, blur - you can have any of the classic javascript events. The second approach requires onChange.

Reactive form angular using FormArrayName

In my form I need to add phones, I have seen that in the database you are saving a string array with the phone numbers that I added, but the moment the value returned from the database is set to the form, only the first array value is shown .
I would like to display all array values that contain number of phones in string format.
component.html:
<div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start">
<div formArrayName="phones" fxFlex="30">
<div *ngFor="let phone of phones.controls; index as i">
<mat-form-field>
<input matInput [formControlName]="i" placeholder="Phone Number">
</mat-form-field>
</div>
</div>
<div fxFlex="30">
<button mat-raised-button class="blue" (click)="addPhone()">Add</button>
</div>
</div>
component.ts:
this.myForm = this._formBuilder.group({
phones: new FormArray([new FormControl('')]),
});
this.values$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((values) => {
// values = {phones: ['999999', '88888', '77777']}
if (values) {
this.myForm.patchValue(values, { emitEvent: false });
}
});
get phones(): FormArray { return this.myForm.get('phones') as FormArray; }
addPhone(): void { this.phones.push(new FormControl('')); }
Even returning more than one value inside the array only displays the first array value on my form, what am I doing wrong?
patchValue won't create any form controls for you, so when you call patchValue it only sets the value for the first form control in your form array, because you only created one.
You have to call addPhone for each phone number or create form inside the describe when you already know how many form controls there should be, but you still need to create as many form controls as number of elements in your array.
this.myForm = this._formBuilder.group({
phones: new FormArray(),
});
this.values$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((values) => {
if (values && values.phones) {
phones.forEach(phone => this.addPhone(phone));
}
});
get phones(): FormArray { return this.myForm.get('phones') as FormArray; }
addPhone(phone = ''): void { this.phones.push(new FormControl(phone)); }

show json value in a label in angular 6

In Angular 6 I click on a date time picker and set a label to the selected value.
At the moment it is showing as { "_value": "2018-09-14T09:30:00.000Z" }
How can I show only the value, 2018-09-14T09:30:00.000Z?
Here is the html
<dl-date-time-picker minuteStep="15" (change)="myDateChanged($event)"></dl-date-time-picker>
<label class="text-secondary">{{ myDate | json }}</label>
and the called code
myDateChanged(val: string) {
this.myDate = JSON.stringify(val);
}
Change the function to
myDateChanged(val: any) {
this.myDate = val._value;
}
And remove the json pipe from the html and you should be good
access the myDate._value property
<label class="text-secondary">{{ myDate._value }}</label>