סוגי טפסים
טפסים משמשים לקליטת מידע מהמשתמש ולחיבור של מידע ל-DB.
Template driven forms
בטפסים מבוססי תבנית רוב העבודה מתבצעת בקובץ ה-html. מתאים לטפסים יחסית קצרים בלי לוגיקה מורכבת.
Reactive form
רוב העבודה מתבצעת ב-class כמו ולידציה, איתור שגיאות וכו'
כשאנחנו מושכים מידע מ-DB רצף העבודה יהיה:
Template -> Class -> Service -> Database.
Template driven form
כדי להשתמש בטפסים צריך להתקין את FormsModule ב-app module.
simple-form.html
<div class="container">
<h1 class="mb-4">Login to the site</h1>
<form #loginForm="ngForm" (ngSubmit)="loginUser(loginForm.value)">
<input type="text" name="name" placeholder="Enter name" ngModel />
<br /><br />
<input
type="password"
name="password"
placeholder="Enter password"
ngModel
/>
<br /><br />
<button>Login</button>
</form>
</div>
צעדי עבודה:
- מגדירים את הטופס #loginForm="ngForm".
- מגדירים טריגר לפעולת ה-submit של הטופס: (ngSubmit)="loginUser(loginForm.value)"
- מחברים את השדות בטופס לערכים שלהם על ידי ngModel.
simple-form.ts
export class SimpleFormComponent {
loginUser(form: NgForm) {
console.log(form);
}
}
ולידציות לטופס
אפשר לסמן שדה כנדרש ולתת לו id כדי שיציג את הודעות השגיאה.
simple-form.html
<div class="container">
<h1 class="mb-4">Login to the site</h1>
<form #loginForm="ngForm" (ngSubmit)="loginUser(loginForm.value)">
<input
type="text"
required
#name="ngModel"
name="name"
placeholder="Enter name"
ngModel
/>
<span *ngIf="name.invalid && name.touched">Please enter a valid input</span>
<br /><br />
<input
type="password"
name="password"
placeholder="Enter password"
ngModel
/>
<br /><br />
<button [disabled]="loginForm.invalid">Login</button>
</form>
</div>
אפשר גם להפוך את הכפתור ללא זמין עד שהקלט של המשתמש תקין.
אפשר להוסיף תנאים נוספים לולידציה של השדה.
simple-form.html
<input
type="text"
required
minlength="2"
pattern="[a-zA-Z]+$"
#name="ngModel"
name="name"
placeholder="Enter name"
ngModel
/>
דרך נוספת לקבל את ערכי הטופס היא:
simple-form.html
<form #loginForm="ngForm" (ngSubmit)="onSubmit()">
simple-form.ts
@ViewChild ('loginForm') form: NgForm;
onSubmit(){
console.log(this.form);
}
Template forms validations
ולידציה required – שדה נדרש. ולידציה email – שדה אימייל.
חסימת הכפתור עד שהטופס תקין:
simple-form.html
<button [disabled]="loginForm.invalid">Login</button>
שינוי העיצוב כשהשדה אינו תקין:
simple-form.css
input.ng-invalid.ng-touched{
border: 1px solid red;
}
הגדרת שדה ברירת מחדל לשדה רדיו:
simple-form.html
<select … [ngModel]="defaultCountry">
simple-form.ts
defaultCountry = "Israel";
Form group
אפשר לחבר ביחד כמה שדות תחת כותרת אחת.
אנחנו צריכים ליצור div ולשים בתוכו את השדות שאנחנו רוצים לאגד ביחד. אפשר לייצר גם ולידציה משותפת לכל הקבוצה.
simple-form.html
<div ngModelGroup="personalDetails" #personalDetails="ngModelGroup">
...
</div>
<span *ngIf="PersonalDetail.invalid">Some error message</span>
Form Radio field
simple-form.ts
defauldGender="Male";
gender = [
{id: "1", value: 'Male'},
{id: "2", value: Female'}
];
simple-form.html
<label for="gender">Gender:</label>
<span *ngFor="let gen of gender">
<input type="radio" id={{gen.id}} value={{gen.value}} name="gender ngModel [ngModel]="defaultGender">
<label for={{gen.value}}>{{gen.value}}</label>
</span>
עדכון ערך השדות
אם יש כפתור ואנחנו רוצים לעדכן את השדות אחרי שמתבצעת פעולה הלחיצה על הכפתור.
comp.html
<button (click)="setDefaltValues()">Set default values</botton>
comp.ts
@ViewChild('formName') form NgForm;
setDefaultValue(){
this.form.value.personalDetails.firstName = "John";
}
במקרה הזה יתבצע שינוי בערך, אבל אנחנו לא נראה אותו בטופס. כדי לראות את השינוי נשתמש בפונקציה setValue:
comp.ts
@ViewChild('formName') form NgForm;
setDefaultValue(){
this.form.setValue({
country: ' ',
personalDetails: {
firstName = "John"
}
})
}
המבנה של setValue חייב להתאים למבנה השדות בטופס ומשתמשים בו כשרוצים לעדכן את כל השדות בטופס.
אם רוצים לעדכן ערך מסויים משתמשים בפונקציה patchValue.
comp.ts
@ViewChild('formName') form NgForm;
setDefaultValue(){
this.form.form.patchValue({
country: ' ',
personalDetails: {
firstName = "John"
}
})
}
קריאת נתוני הטופס
אם רוצים לאחזר את המידע מהטופס:
1. ב-class ניצור משתנה שיחזיק את הערך:
firstName: string;
2. נכתוב פונקציה שמופעלת כשיש טריגר של שינוי בערך השדה:
onSomeFunction(){
this.firstName = this.form.value.personalDetails.firstName; }
3. נציג את הערכים בקובץ ה-html:
<p>First name: {{ firastName }} </p>
4. בטופס נשתמש בבינדינג דו צדדי:
<input name="firstName" ngModel #fname="ngModel">
אפשר לאפס טופס על ידי שימוש בפונקציה:
this.form.reset()