I am trying to separate the code responsible for the form into another component, and make it reusable.
I guess i should use #Input somehow. Then referr it in html. And pass values from it to post method. But how can i do it?
Backend, form and method worked fine when code were in same .ts. Im using Angular11.2.2
Here is my code:
**camel-form.component.ts **
camelForm = this.formBuilder.group({
id: [],
name: [''],
age: [],
guardian: this.formBuilder.group({
id: [],
name: [''],
lastName: [''],
email: ['']
})
});
**camel-form.component.html **
<form [formGroup]="camelForm">
<!-- part for camel-->
<h2 class="ml-3">Camel form</h2>
<div class="form-row ml-3">
<div class="form-group col-md-2">
<label for="id">id </label>
<input class="form-control" id="id" type="number" formControlName="id">
</div>
<div class="form-group col-md-2">
<label for="name">name </label>
<input class="form-control" id="name" type="text" formControlName="name">
</div>
<div class="form-group col-md-2">
<label for="age">age </label>
<input class="form-control" id="age" type="number" formControlName="age">
</div>
</div>
<!-- part for guardian-->
<h2 class="ml-3">Guardian form</h2>
<div class="form-row ml-3" formGroupName="guardian">
<div class="form-group col-md-2">
<label for="id">id </label>
<input class="form-control" id="id" type="number" formControlName="id">
</div>
<div class="form-group col-md-2">
<label for="name">name </label>
<input class="form-control" id="name" type="text" formControlName="name">
</div>
<div class="form-group col-md-2">
<label for="lastName">lastName</label>
<input class="form-control" id="lastName" type="text" formControlName="lastName">
</div>
<div class="form-group col-md-2">
<label for="email">email</label>
<input class="form-control" id="email" type="email" formControlName="email">
</div>
</div>
</form>
**rest.component.ts **
camel: Camel;
postCamel(): void {
this.camel = this.----------.value;
this.apiService.postCamel(this.camel).subscribe();
}
**rest.component.html **
<app-camel-form></app-camel-form>
<button class="btn-danger ml-3" type="submit" (click)="postCamel()">Submit</button>
First, I would move the submit button into the CamelForm component.
Second, to make the form re-usable for editing you'll need to provide an input for the data so it can be bound to the FormGroup instance. Example, omitting the component definition:
#Input()
camel: ICamel;
form: FormGroup;
initForm(camel?: ICamel): void {
this.form = this.formBuilder.group({
id: [camel ? camel.id : null],
name: [camel ? camel.name : null],
age: [],
guardian: this.formBuilder.group({
id: [camel ? camel.gaurdian.id : null],
name: [camel ? camel.gaurdian.name : null],
lastName: [camel ? camel.gaurdian.lastName : null],
email: [camel ? camel.gaurdian.email : null]
});
}
}
Now you can leverage the form in either case by supplying the input, or not:
<app-camel-form [camel]="camel"></app-camel-instance>
Hope that helps you out.
are you sure you want to make a submit button out of the form? if that is false then you can subscribe to submit event and emit it from your component (submit)="postCamel($event)". Otherwise - you want button out of the form I would propose to do like that
<app-camel-form #camelForm [camel]="camelData"></app-camel-form>
<button (click)="postCamel(camelForm.value)"
and in the form
ngOnChanges(changes) { // this method is needed if you want to pass data to the form
if(changes.camel) {
this.camelForm.patchValue(this.camel)
}
}
get value() {// this will make the form value be accessible from outside of form component
return this.camelForm.value;
}
Related
SERVICE.TS
addP(nome: string, cognome: string, anno_n: string): Observable<any> {
return this.http.post<Partecipanti>(this.partecipantiUrl, {
nome: nome,
cognome: cognome,
anno_n: anno_n
}, this.httpOptions).pipe(
tap((newPartecipante: Partecipanti) => this.log(`partecipante aggiunto w/ id=${newPartecipante.id}`)),
catchError(this.handleError<Partecipanti>('addP'))
);
}
COMPONENT.TS
add(nome: string, cognome: string, anno_n: string): void {
this.PartecipantiService.addP(nome, cognome, anno_n).subscribe(res => {
console.log(res);
this.loadUser();
})
}
<form class="row row-cols-lg-auto g-3 align-items-center float-center" (ngSubmit)="add(nome.value, cognome.value, anno_n.value)" (ngSubmit)="loadUser()" style="justify-content: center;">
<div class="col-12">
<label class="visually-hidden" for="inlineFormInputGroupUsername">Nome</label>
<div class="input-group">
<input type="text" class="form-control" id="inlineFormInputGroupUsername" required #nome placeholder="Nome">
</div>
</div>
<div class="col-12">
<label class="visually-hidden" for="inlineFormInputGroupUsername">Cognome</label>
<div class="input-group">
<input type="text" class="form-control" id="inlineFormInputGroupUsername" required #cognome placeholder="Cognome">
</div>
</div>
<div class="col-12">
<label class="visually-hidden" for="inlineFormInputGroupUsername">Data di nascita</label>
<div class="input-group">
<input type="text" class="form-control" id="inlineFormInputGroupUsername" required #anno_n useValueAsDate placeholder="Data di nascita (GG/MM/AAAA)">
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary shadow-lg">Salva</button>
</div>
</form>
How can I take the date value in my function "add"?
In my function add I have 3 field (name, surname and date), when I call my function add on a button I use (ngSubmit)="add(name.value, surname.value, date...?). What I have to use? Value is for string, I can't find something for Date! This part is on component.html Can you explain me how it works? My input is type="date"
I would suggest you use ngForm. This is the easiest for handling this scenario.
See here the Documentation: https://angular.io/api/forms/NgForm
Here is a working example i did: https://stackblitz.com/edit/angular-ivy-pqgewm?devtoolsheight=33&file=src/app/app.component.html
In Essence you want your HTML look like this:
<form #form="ngForm" (ngSubmit)="userService.submitForm(form)">
<div>
<label for="firstName">First Name</label>
<input name="firstName" id="firstName" type="text" ngModel required />
</div>
<div>
<label for="lastName">Last Name</label>
<input name="lastName" id="lastName" ngModel type="text" required />
</div>
<div>
<label for="dateOfBirth">Date of Birth</label>
<input name="dateOfBirth" id="dateOfBirth" ngModel type="date" required />
</div>
<br />
<button type="submit">Submit</button>
</form>
And your Submit function to look like this:
submitForm(form: NgForm) {
if (form.valid) {
const user: User = {
name: form.value['firstName'],
surname: form.value['lastName'],
birth: new Date(form.value['dateOfBirth']),
};
}
}
I would like to add values from the input controls to the applicable divs as displayed in the picture
example.
I followed this Tutorial and I am able to replicate the same controls again and again but not as represented in this picture. This is code, can someone lead me where I went wrong? posted the html and component.ts.
<form [formGroup]="FemaForm" (ngSubmit)="onSubmit()" class="form-horizontal">
<div formArrayName="aliases">
<div *ngFor="let alias of aliases.controls; let i=index">
<label>Cause</label>
<input id="reason" formControlName="cause" type="text" class="form-control"
[formControlName]="i">
<label>Start</label>
<input name="Start" formControlName="Start" type="text"
placeholder="MM/DD/YYYY" [formControlName]="i" />
<label>End</label>
<input name="End" formControlName="End" type="text" placeholder="MM/DD/YYYY" [formControlName]="i" />
<label >FLD</label>
<input id="FLD" formControlName="FLD" type="text" class="form-control"
[formControlName]="i" >
<label>Valid </label>
<input id="Extn" formControlName="Extn" type="text" class="form-control"
[formControlName]="i">
<button (click)="deleteAlias(i)"></button>
</div>
<button (click)="add(i)"> </button>
<button type="submit">Log</button>
</div>
</form>
export class TestComponent {
constructor(private fb: FormBuilder) { }
FemaForm= this.fb.group({
cause: [''],
Start: [''],
End: [''],
FLD: [''],
Extn: [''],
aliases: this.fb.array([
this.fb.control('')
])
});
get aliases() {
return this.FemaForm.get('aliases') as FormArray;
}
add() {
this.aliases.push(this.fb.control(''));
}
deleteAlias(index) {
this.aliases.removeAt(index);
}
}
do someone knows how i can bind the keyup.enter proproty to the tab of the keyboard?
i mean i want that when i enter the value in a first field of my form that i spring in the second field.
Like:
<form>
<label for="xxx">first:
<input type="text" id="first" name="first" (keyup.enter)="enterFirst(firstName)">
</label>
<label for="xxx">second:
<input type="text" id="second" name="second" (keyup.enter)="enterSecond(lastName)">
</label>
.
.
.
<button type="button" class="btn btn-success" (click)="sendNames(xxx)">valid</button>
</form>
So i would to be able to spring on the field second when i give the firstname and click on enter.
Do someone have an idea? thanks in advance
This should work, although it is vanilla JS:
<input type="text" id="first" name="first" onkeyup="if (event.keyCode == '13') {enterFirst(this)}">
(EDITED: Replaced "firstName" with "this")
HTML:
<h1>Here we will try to bind the keyup.enter with Tab</h1>
<div class="container">
<h2>Please enter datas an click on enter</h2>
<form>
<div class="row">
<div class="form-group col">
<label for="fname">Enter your firstname:</label>
<input type="text" class="form-control" placeholder="enter your firstname and click enter"
id="fname" name="fname" onkeyup="if (event.keyCode == '13') {enterFirst(this)}">
</div>
<div class="form-group col">
<label for="lname">Enter your lastname:</label>
<input type="text" class="form-control" placeholder="enter your lastname and click enter"
id="lname" name="lname" onkeyup="if (event.keyCode == '13') {enterLast(this)}">
</div>
</div>
<button type="button" class="btn btn-success" (click)="sendData()">submit</button>
</form>
</div>
Ts:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'angulartest';
public firstname: string;
constructor(){}
ngOninit(){
}
enterFirst(firstname){
console.log(firstname);
}
sendData(){
}
}
I wrote it just to see if i can spring to the field lastname by clicking on enter after the firstname
I have a ngForm for singup page. I have tried passing the data to the .ts file but failed to print them on console.
Here's my code:
<div class="column" style="padding: 7.5%">
<form #instituteForm="ngForm" (ngSubmit)="instituteLogin(instituteForm)">
<div class="form-group">
<label> Full Name </label>
<input
type="text"
ng-maxlength="10"
hint="Full Name"
name="patient"
id="name"
class="form-control"
[(ngModel)]="institute.patient">
<label> Phone Number </label>
<input
type="number"
hint="phone"
name="phoneno"
id="phone"
maxlength="10"
minlength="10"
class="form-control"
[(ngModel)]="institute.phoneno">
<label> Aadhar Number </label>
<input
type="number"
hint="aadhar"
id="aadhar"
name="aadhar"
maxlength="16"
minlength="16"
class="form-control"
[(ngModel)]="institute.aadhar">
<br><br>
</div>
<button id="signup" class="btn btn-primary" type="submit">Signup</button>
</form>
</div>
institute = {
patient: '',
phoneno: '',
aadhar: ''
};
instituteLogin(instForm: NgForm) {
console.log("Entered new patient");
console.log(instForm.value);
}
You have not added the FormsModule in app.module.ts.
import { FormsModule } from '#angular/forms';
#NgModule({
imports: [
// Other imports
FormsModule
]
})
Working demo : https://stackblitz.com/edit/angular-ybbamr
In this case it should be like this:
instituteLogin(): void{
console.log("Entered new patient");
console.log(this.institute);
}
Well, I think you should use FormControlName instead of ngModel.
html:
<div class="column" style="padding: 7.5%" >
<form [formGroup]="institute" #instituteForm (ngSubmit)="instituteLogin()">
<div class="form-group">
<label> Full Name </label>
<input type="text" ng-maxlength="10" hint="Full Name" id="name" class="form-
control" formControlName="patient">
<label> Phone Number </label>
<input type="number" hint="phone" id="phone" maxlength="10" minlength="10"
class="form-control" formControlName="phoneno">
<label> Aadhar Number </label>
<input type="number" hint="aadhar" id="aadhar" maxlength="16" minlength="16"
class="form-control" formControlName="aadhar">
<br><br>
<button id="signup" class="btn btn-primary"
routerLink="../../home/dashboard">Signup</button>
</div> </form>
</div>
ts:
institute:FormGroup;
instituteLogin(){
console.log("Entered new patient");
console.log(this.institute.value);
}
constructor(private formBuilder:FormBuilder) { }
ngOnInit() {
this.institute =this.formBuilder.group( {
patient: new FormControl(),
phoneno:new FormControl(),
aadhar:new FormControl()
});
}
I am trying to create a from validations in such a way that when form is submitted the invalid fields must be highlighted with red color but i am not sure where i am wrong can someone help me
my template,
<form id="login-form" name="login-form" class="nobottommargin" [formGroup]="form" (ngSubmit)="onSubmit(form.value)">
<p *ngIf="activation" class="activation">We have sent an activation link to your email</p>
<div class="form-group col-sm-offset-2">
<label class="radio-inline">
<input type="radio" [formControl]="form.controls['type']" value = 'personal' name="optradio">Personal
</label>
<label class="radio-inline">
<input type="radio" [formControl]="form.controls['type']" value = 'professional' name="optradio">Professional
</label>
</div>
<div class="form-group">
<input type="text" [formControl]="form.controls['firstname']" id="login-form-firstnamee" name="login-form-firstname" value="" placeholder="First Name" class="sm-form-control not-dark formcontrolheight required">
</div>
<div class="clear"></div>
<div class="col-sm-12 labeltopmargin nopadding">
<button class="col-xs-12 button buttonmeroon button-mini nomargin" id="login-form-submit" name="login-form-submit" value="login">Sign Up</button>
</div>
<div class="clear"></div>
</form>
My ts,
export class SignUp {
http: Http;
emailfailure: any;
activation: any;
profilefailure: any;
form:any;
constructor(fbld: FormBuilder, http: Http, public router: Router) {
this.http = http;
this.form = fbld.group({
firstname: ['', Validators.required],
lastname: ['', Validators.required],
profilename: ['', Validators.required],
email: ['', Validators.required],
password: ['', Validators.required],
repeatpassword: ['', Validators.required],
image: [''],
phone: ['', phoneValidator],
type: ['',],
}
You can use .ng-invalid class which is added to your input, when it does not meet Validator requirements.
You can also display some error messages depending on your form state:
<div class="error message" *ngIf="!form.valid">Your message</div>
This is simple form validation in angular 2
<form #heroForm="ngForm">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name"
required
[(ngModel)]="info.name" name="name"
#name="ngModel" >
<span *ngIf="!name.valid && !name.pristine" style="color:red;"> <span>name is Required</span></span>
</div>
<div class="form-group">
<label for="alterEgo">Alter Ego</label>
<input type="text" class="form-control" id="alterEgo"
[(ngModel)]="info.age" name="alterEgo" >
</div>
<button type="button" class="btn btn-default" (click)="enter()">ENTER</button>