טפסים מבוססי תבנית

סוגי טפסים

טפסים משמשים לקליטת מידע מהמשתמש ולחיבור של מידע ל-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>

צעדי עבודה:

  1. מגדירים את הטופס #loginForm="ngForm".
  2. מגדירים טריגר לפעולת ה-submit של הטופס: (ngSubmit)="loginUser(loginForm.value)"
  3. מחברים את השדות בטופס לערכים שלהם על ידי 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()