How to display Date in Html using angular? - html

I have two datepickeres in my HTML file using bootstrap and I am trying to display a simple message from this (first selected date) to this (second selected date).
The typescript class is:
export class Datepicker {
date: any;
}
And the HTML is:
<div class="form-group">
<label for="hireDate">Hire Date:</label>
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<input class="form-control" name="hireDate" id="hireDate" placeholder="yyyy-mm-dd"
[(ngModel)]="datePicker.date" ngbDatepicker #d="ngbDatepicker">
<div class="input-group-append">
<button class="btn btn-outline-secondary" (click)="d.toggle()" type="button">
<img src="/assets/calendar-icon.svg" style="width: 1.2rem; height: 1rem; cursor: pointer;"/>
</button>
</div>
</div>
</div>
</form>
</div>
<div>{{datePicker.date}} </div>
But it gives me Object as a result and not the selected date.
Any help?

You can use Angular DatePipe to convert the date into the format that you wish to display.
<div> {{datePicker.date | date : 'yyyy-MM-dd'}} </div>
DEMO
EDIT : To convert the date object ({ "year": 2018, "month": 8, "day": 7 }) returned by ngBootstrap to yyyy-MM-dd format, you can do the transformation inside the setter method of datePicker.date property as follows :
module.ts
providers : [DatePipe]
service.ts
export class Datepicker {
_date: string;
constructor(private datePipe: DatePipe) {}
set date(value) {
let date = new Date(value.year, value.month, value.year);
this._date= this.datePipe.transform(date, 'yyyy-MM-dd');
}
get date() {
return this._date
}
}

ng-bootstrap datepicker selection gives you an object like this
Model: {
"year": 2018,
"month": 8,
"day": 9
}
You can write initialize a date object from selected model like this:
<div> {{ new Date(datePicker.date.year, (datePicker.date.month - 1), datePicker.date.day) | date : 'yyyy-MM-dd'}} </div>
https://ng-bootstrap.github.io/#/components/datepicker/examples#popup

Related

How to pass value from one component to another? (Angular)

I just recently started learning Angular and I have a question. I want to implement a search method to search for a product on my site, I made search.pipe.ts, which works, but the input for input is in the header.component.ts component, and the products array is in the car-list.component.ts component.
car-list.component.html
<div *ngFor="let car of cars | paginate: { itemsPerPage: pageNumber, currentPage: currentPg} | **search:searchStr**" class="col-md-3">
<div class="product box">
<img src="{{'data:image/jpg;base64,' + car.image }}" alt="">
<h3>{{ car.name }}</h3>
<div class="price">{{ car.price | currency:'USD' }}</div>
<button class="btn btn-primary btn-sm">Add to cart</button> <!--(click)="addToCart(tempProduct)"-->
</div>
<br>
</div>
header.component.html
<form class="d-flex me-5">
<input type="text" class="form-control me-2" placeholder="Search cars...">
</form>
header.component.ts
export class HeaderComponent implements OnInit {
searchStr: string = '';
constructor() {
}
ngOnInit(): void {
}
}
search.pipe.ts
#Pipe({
name: 'search'
})
export class SearchPipe implements PipeTransform {
transform(cars: any[], value: any) {
return cars.filter(car => {
return car.name.includes(value);
})
}
}
I want the input values ​​from the header component to be passed to the car-list component so that I can find the product I need.
In this case you can use a shared service where you can pass data from your header component and load that data in your products component.
For further reference - Angular 4 pass data between 2 not related components
use #Input and #Output decorators to communicate between components

How to validate dynamic form in angular

Below is my code. According to the loop count, fName will increase. currently I am using ng-bootstrap-form-validation for validation. The issue if I validate using formControlName that's not working it's duplicating if one field(fName) is correct all the fields become correct.
Below is my HTML code,
<form [formGroup]="formGroup" (validSubmit)="onSubmit()">
<div class="results-traveler" *ngFor="let item of createLoopRange(selectedDataDetails[0].Adult); let ii= index;">
<div class="row">
<div class="col-12 heading" *ngIf="ii == 0 else travelCount">Traveller {{ii}}</div>
<div class="col-6 M-full-div">
<label>First Name</label>
<div class="inputContainer form-group">
<input class="InputField form-control" type="text" placeholder="Type Here" formControlName="fName" id="fName_{{i}}" />
</div>
</div>
</div>
</div>
<a class="SearchBtn" type="submit">CONTINUE</a>
</form>
Below is the typescript code I am using,
ngOnInit(): void {
this.bookingDetailsValidate();
}
bookingDetailsValidate() {
this.formGroup = new FormGroup({
fName: new FormControl('', [
Validators.required,
Validators.pattern(/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)
])
});
}
onSubmit() {
console.log(this.formGroup);
}
Can anyone please guide me on how to do this. Thanks.
for fName use FormArray then add FormControl to FormArray and you can validate FormArray and every FormControl inside FormArray
example:
this.formGroup = new FormGroup({
fName: new FormArray([], [
Validators.required
])
});
...
const arrayOfNameControl = this.formGroup.get('fName') as FormArray
arrayOfNameControl.insert(0, new FormControl('',[
Validators.required,
Validators.pattern(/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)
]));
You need form array here. Please refer the link.
Angular form array

Get a value from a HTML form in a Angular 2 ag-grid

I have a form that appears in a modal in my HTML file and i would like to add the values i get form the form in a ag-grid array, and i have no idea how to do this.
This is my file.html
<template #addTrainContent let-c="close" let-d="dismiss">
<div class="modal-header">
<h4 class="modal-title">Ajouter un train</h4>
<button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<input type="radio" name="choiceDirection" /> Gauche
<input type="radio" name="choiceDirection" /> Droite
<input type="number" placeholder="Numéro de matériel" value="nMateriel"/>
<select>
<option>1</option>
<option>52</option>
<option>38</option>
</select>
<input type="checkbox" checked /> Créer dans l'ATS
</div>
<div class="modal-footer">
<button class="btn btn-lg btn-primary" (click)="c(createTrain())">Ajouter le train</button>
<button type="button" class="btn btn-secondary" (click)="c('Close click')">Annuler</button>
</div>
</template>
And i was adding a train with value i chose instead of the ones from the form, like that in my file.ts
createNewTrain() {
var newTrain = {
nMateriel: 97,
nRame: 42,
position: 'TB__BLOC_13',
direction: 'droite',
etat: 'mouvement',
vitesse: '24 km/h'
};
return newTrain;
}
createTrain() {
var newItem = this.createNewTrain();
this.gridOptions.api.addItems( [newItem] );
this.rowCount++;
}
How can i get the value from my form and put it in my ag-grid array?
Thank you for your help
Let's step through this example. Here is the initial setup:
//our root app component
import {Component, Directive, ElementRef} from 'angular2/core'
#Component({
selector: 'my-app',
directives: [],
providers: [],
template: `
<div>
<h2>Hello {{name}}</h2>
<label>Name</label>
<select [(ngModel)]="name" name="Select name" class="ui fluid search selection dropdown">
<option *ngFor="#n of names" [attr.value]="n">{{n}}</option>
</select>
<br>
<button (click)="print()">print</button>
</div>
`,
directives: []
})
export class App {
// name: string = "Jane";
names: string[] = ["John", "Paul", "George", "Ringo"]
print = () => console.log(this.name)
constructor() {
setTimeout(() => {
jQuery('.ui.dropdown').dropdown();
}, 1000);)
}
}
NOTE: MODEL refers to variables in the class App, CONTROLLER refers to functions in the class App, and VIEW refers to the HTML template.
The variable that is of most interest to us is name. Notice that it is currently commented out in the MODEL. However, I have a CONTROLLER that is able to print this.name. What is happening is that Angular notices that it is bound in the VIEW and so it decides to create it for us.
In the <h2> it is a one-way binding, meaning that it takes the value of what is in the MODEL. So if something were to change the value of name in the MODEL, Angular would update the VIEW with the new value.
In the Select there is a two-way binding, meaning that if the value of name in the VIEW gets updated, Angular will notify the MODEL that name is now a new value; Also, if something in the MODEL were to change name then the VIEW would get updated.
For example when you change the select to "Ringo", the MODEL gets updated, then the MODEL updates the VIEW so that the title reads "Hello Ringo"
Now if you uncomment name: string = "Jane", then you are basically setting a default value for name. You might also notice that the title will then read "Hello Jane" but the select remains blank. That is because "Jane" isn't one of the options in the select.
What this means for you:
In your VIEW bind each of your inputs to variables with [(ngModel)] for example:
<input [(ngModel)]="materiel" type="number" placeholder="Numéro de matériel" value="nMateriel"/>
Then in your CONTROLLER for creating a new train you will be able to use that variable as a reference:
createNewTrain() {
var newTrain = {
nMateriel: this.materiel,
nRame: 42,
position: 'TB__BLOC_13',
direction: 'droite',
etat: 'mouvement',
vitesse: '24 km/h'
};
return newTrain;
}
Nothing else is really needed, however I would strongly suggest to add some defaults into your TS file/MODEL for readability's sake and so that each of these variables will have a value:
// somewhere in your TS
materiel: number = 97
I solved my problem by doing this in my file.ts :
(I only changed it for nMateriel for the example)
createNewTrain() {
var newTrain = {
nMateriel: (<HTMLInputElement>document.getElementById("nMateriel")).value,
nRame: 42,
position: 'TB__BLOC_13',
direction: 'droite',
etat: 'mouvement',
vitesse: '24 km/h'
};
return newTrain;
}

How do I get the count of the selected checkboxes and display the count in Angular 2?

I need help displaying the count of a list of checkboxes into the value of a dropdown box. Where do I need to get my count from? The checkboxes are being passed dynamically as an array.
Here is my current code.
DropDownBox Component
<div ngbDropdown class="d-inline-block" [autoClose]="false">
<button class="btn btn-outline-primary" id="dropdownMenu1" ngbDropdownToggle{{title}}`(need to display the count here)`
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu1">
<input type="text" placeholder="{{searchPlaceholder}}" class="searchBox" />
<div *ngFor="let data of datas">
<cst-checkbox [checkBoxValue] = "data" [ngModel]="data.selected"></cst-checkbox>
</div>
</div>
</div>
Checkbox component
<div class="checkbox">
<input type="checkbox" value="{{checkBoxValue}}" />
<label>{{checkBoxValue}}</label>
</div>
The checkbox component is <cst-checkbox> in the dropdown component.
You can create your Custom Pipe to get selected values only, by filtering them up
#Pipe({
name: 'getSelcted',
pure: false
})
#Injectable()
export class GetSelectedPipe implements PipeTransform {
transform(items: any[]): any {
// take out only selected values
return items.filter(item => item.selected === true);
}
}
Usage
{{(datas: getSelcted)?.length || 0}}
Note: Make sure GetSelectedPipe has been injected in declarations of AppModule's #NgModule declartions array.

Angular2 - How to use one way databinding to bind to JSON attribute

I try to use Angular2's one way databinding to bind an input field value to a JSON property.
The JSON object looks like this:
[
{
"name": "my name",
"list": [
{
"date": "0101970",
"list": [
{
"timespan": "6-7",
"entries": [
{
"name": ""
},
{
"name": ""
},
{
"name": ""
}
]
}
]
}
]
}
]
I want to bind the value to a specific name attribute of entries.
This is how I try to do the on way binding:
<div class="col-md-4" *ngFor="#category of categories">
<div>
<div class="col-md-12">
<h1>{{category.name}}</h1>
</div>
</div>
<div *ngFor="#listentry of category.list">
<div class="row">
<div class="col-md-12">
<h2>{{listentry.date}}</h2>
</div>
</div>
<div class="row" *ngFor="#shift of listentry.list">
<div class="row">
{{shift.timespan}}
</div>
<div class="row" *ngFor="#entry of shift.entries">
<div class="col-md-10">
<input type="text" class="form-control" (ngModel)="entry.name">
</div>
</div>
</div>
</div>
</div>
This is my Component:
export class InputComponent {
public categories:Category[];
constructor(private _dataService:DataService) {
// ... fetch data from the service here
}
}
As I understand the databinding in Angular2 (ngModel)="attribute" binds from the view to the model and [ngModel]="attribute" binds the other way around.
So, what is wrong with my <input type="text" class="form-control" (ngModel)="entry.name"> then?
I could use two way databinding instead of course, but I have some other constraints (disabling form elements) which just apply after a button was pressed and not on the user input.
With
<input type="text" class="form-control" [ngModel]="entry.name">
you bind the JSON value to the input.
(ngModelChange)="model=$event" updates the model when an `ngModelChange` event is emitted.
[(ngModel)]="model" binds two-way
where ngModel is a directive with an
#Input() ngModel; // for the [ngModel]="..." bindign
#Output() ngModelChange = EventEmitter(); // for the (ngModelChange)="..." binding
together they support the shorthand form
[(ngModel)]="model"