הגענו לסיום הקורס באנגולר טפסים מגיבים! למדנו הרבה דברים מעניינים והנה סיכום:
- מה זה abstract control
- formControl formGroups, formArray
- הגדרת הטופס בצורה בסיסית או שימוש בformbuilder
- תכנון נכון של מבנה הטופס בהתאם לטופס שלכם
- חיבור הטופס לתצוגה
- ולידציות מובנות באנגולר
- ולידציות בהתאמה אישית
- שימוש בולידציות בתצוגה של הטופס
נושאים אלו מקיפים את כל שעליכם לדעת על מנת לייצר טפסים מגיבים באנגולר. כמו כן, אפשר להעמיק יותר וללמוד יותר על טפסים ולייצר דברים מורכבים יותר שלא הצגנו כאן. למשל formArray.
וכן אפשר להעמיק בהבנה של abstractControl ו-ValidatorFn . ובכל זאת אני מאמין שקורס זה מקיף מספיק על מנת לתוכלו להתחיל ולכתוב טפסים בעצמכם.
איך ממשיכים ולומדים עוד על טפסים באנגולר
אז מי שיודע ומכיר ולא צריך את המידע הזה יכול להמשיך הלאה וכן צוות קודקודייל מאחל לו בהצלחה רבה.
מי שעוד לא לגמרי מצליח לבדו וצריך עוד תמיכה, אנחנו נשמח לסייע. רשמו לנו איפה היה לכם קשה ותרצו שנרשום פוסטים נוספים בנושא ונפרט ונרחיב עד שכל אחד ואחת מהקוראים יוכל לקבל מדריך מונגש היטב ויסייע לכם להתקדם ביתר קלות.
בנוסף קבלו את המלצתי ככותב המיני קורס הזה, ובעל נסיון רב עם עבודה בטפסים ואנגולר, תבנו לכם תרגיל עצמי. אתם יכול לשכתב את אותו הטופס שיש בדוגמה שהצגתי פה. או ממש להמציע טופס משלכם.
תעברו על כל השלבים כגון תכנון וולידציות. ותתחילו לכתוב את הHTML ולאחר מכן את אובייקט הטופס. תתחילו עם משהו פשוט מאד, 2 -3 שדות, ושפרו אותו עם הזמן. ככה אתם תקלנו טוב יותר את החומר המוצג פה ותוך כדי יישום הדברים , הבנתכם תהיה חזקה יותר.
בהצלחה ונתראה בקורס הבא 😊🐊
קוד של טופס הדוגמה שלנו בקורס אנגולר זה
להלן כל הקבצים של הטופס דוגמה של הקורס, יש פה קומפוננטה אחת למעשה וקצת טופסות בapp. להלן הקבצים של הקומפוננטה form-example
<form *ngIf="jobRegistrationForm" [formGroup]="jobRegistrationForm" (submit)="submit(jobRegistrationForm)"> <div class="form-group"> <label>שם מלא<span class="red-star">*</span></label> <input formControlName="fullName" type="text" value="" placeholder="הקלדו כאן" /> <span *ngIf="jobRegistrationForm.controls.fullName.invalid && (jobRegistrationForm.controls.fullName.dirty || jobRegistrationForm.controls.fullName.touched)" class="invalid-text"> הזינו שם ושם משפחה</span> </div> <div class="form-group"> <label>מספר טלפון<span class="red-star">*</span></label> <div [formGroup]="jobRegistrationForm.get('phoneForm')" class="inner-group-phone"> <input formControlName="number" type="text" value="" placeholder="הקלדו כאן" /> <div class="prefix-container"> <button (click)="displayPrefixlist()" type="button" class="choose-prefix"></button> <ul *ngIf="showPrefix" class="prefix-list"> <li *ngFor="let prefix of prefixList"><button (click)="choosenPrefix(prefix)" type="button" class="prefix">{{prefix}}</button></li> </ul> <input type="text" formControlName="prefix" [attr.disabled]="true" value="" placeholder="000" /> </div> </div> <span *ngIf="jobRegistrationForm.get('phoneForm').invalid && (jobRegistrationForm.get('phoneForm').controls.number.dirty || jobRegistrationForm.get('phoneForm').controls.number.touched)" class="invalid-text"> יש לשים קידומת ומספר טלפון שלפחות 7 ספרות</span> </div> <div class="form-group"> <label>אימייל<span class="red-star">*</span></label> <div [formGroup]="jobRegistrationForm.get('emailForm')" [ngClass]="{'form-not-valid' : jobRegistrationForm.get('emailForm').hasError('emailsAreSame')}" class="inner-group-email"> <input [ngClass]="{'input-not-valid': jobRegistrationForm.get('emailForm').controls.email.hasError('email')}" formControlName="email" type="email" value="" placeholder="אימייל לראשונה"/> <input [ngClass]="{'input-not-valid': jobRegistrationForm.get('emailForm').controls.reEmail.hasError('email')}" formControlName="reEmail" type="email" value="" placeholder="אימייל בשנית" /> </div> <span *ngIf="jobRegistrationForm.get('emailForm').hasError('emailsAreSame') && (jobRegistrationForm.get('emailForm').controls.email.dirty || jobRegistrationForm.get('emailForm').controls.email.touched)" class="invalid-text"> המיילים אינם זהים</span> </div> <div class="form-group"> <label>סטטוס<span class="red-star">*</span></label> <div (change)="checkJobStatus()" class="radio-group"> <input type="radio" name="jobStatus" formControlName="jobStatus" [value]="true" /> <span class="radio-input-text">עובד</span></div> <div (change)="checkJobStatus()" class="radio-group"> <input type="radio" name="jobStatus" formControlName="jobStatus" [value]="false" /><span class="radio-input-text">לא עובד</span></div> <span *ngIf="jobRegistrationForm.controls.jobStatus.invalid && (jobRegistrationForm.controls.jobStatus.dirty || jobRegistrationForm.controls.jobStatus.touched)" class="invalid-text"> זה לא ולידי</span> </div> <div *ngIf="dontHaveJobYet" class="form-group"> <label>מאיזה יום הפסקת לעבוד<span class="red-star">*</span></label> <input formControlName="lastDayJob" type="date" > </div> <div class="form-group"> <input type="checkbox" formControlName="termsApproved" /> <span>יש לאשר את תנאי השימוש<span class="red-star">*</span></span> </div> <button [disabled]="jobRegistrationForm.invalid" [ngClass]="{'btn-invalid': jobRegistrationForm.invalid}" class="button-action">אני רוצה!</button> </form>
:host{ display: block; } .invalid-text { font-size: 11px; color: red; position: relative; top: -10px; height: 0; display: block; } .input-not-valid { border: 1px solid red !important; } .form-not-valid { margin-bottom: 11px; border-bottom: 2px solid red !important; } .inner-group-email { border-bottom: 2px solid transparent; } form { .form-group{ margin: 20px 0 10px 0; .red-star { color: red; margin-right: 4px; } label { display: block; } input[type=text], input[type=email], input[type=date] { height: 36px; margin: 10px 0; padding: 6px 10px; background-color: #dbdbdb44; border: none; border-radius: 0; display: block; width: 100%; } input[type=radio] { margin: 10px 0; } .radio-group { display: inline-block; margin-left: 14px; .radio-input-text{ display: inline-block; margin-right: 4px; } } .inner-group-phone { display: flex; } .prefix-container { margin-right: 10px; position: relative; .choose-prefix { border: none; position: absolute; top: 10px; right: 0; bottom: 10px; left: 0; width: 100%; background-color: transparent; } ul.prefix-list { position: absolute; background-color: #fff; box-shadow: 0 0 20px rgba(0,0,0,0.1); top: 30px; width: 106px; list-style: none; padding: 10px; li { button { background-color: transparent; border: none; width: 100%; } } } } } button.button-action { background-color: #2fcff4; color: #fff; font-size: 24px; width: 100%; text-align: center; padding: 10px; margin-top: 20px; border: none; &.btn-invalid{ opacity: .4; cursor: not-allowed; } } }
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { customValidatorsForJobForm } from 'src/validators/customValidatorsForJobForm'; @Component({ selector: 'app-form-example', templateUrl: './form-example.component.html', styleUrls: ['./form-example.component.scss'] }) export class FormExampleComponent implements OnInit { public showPrefix : boolean; public prefixList: string[] = ['050','052','053','054','055','056','057']; public dontHaveJobYet: boolean; public jobRegistrationForm : FormGroup; constructor(private fb: FormBuilder) { } ngOnInit(): void { this.jobRegistrationForm = this.fb.group({ fullName: this.fb.control('',[Validators.required , Validators.pattern(/[a-zA-Z]+\s+[a-zA-Z]/)]), phoneForm: this.fb.group({ number: ['',[Validators.required , Validators.pattern('[0-9]{7,20}')]], prefix: ['',Validators.required] }), emailForm : this.fb.group({ email: ['',[Validators.required, Validators.email]], reEmail: ['',[Validators.required, Validators.email]] },{validators: [customValidatorsForJobForm.emailVerified()]}), jobStatus: ['',Validators.required], termsApproved : ['',Validators.required] }); } displayPrefixlist(): void { this.showPrefix = !this.showPrefix; } choosenPrefix(choosen: string): void { this.showPrefix = false; this.jobRegistrationForm.get('phoneForm').get('prefix').setValue(choosen); } checkJobStatus(): void{ this.dontHaveJobYet = !this.jobRegistrationForm.controls.jobStatus.value; if (this.dontHaveJobYet){ this.jobRegistrationForm.addControl('lastDayJob', this.fb.control('', [Validators.required])); }else { this.jobRegistrationForm.removeControl('lastDayJob'); } } submit(form: any) { console.log(form.value); } }
להלן הקבצים של app (קובץ הTS של app ללא שינוי)
<div class="form-container"> <div class="header-form"> <h2>הירשם עכשיו!</h2> <span>תניני קוד שמחפשים עבודה</span> </div> <app-form-example></app-form-example> </div>
:host { display: block; } .form-container { background-color: #fff; border-radius: 10px; box-shadow: 1px 2px 20px rgba(0,0,0,0.1); width: 100%; max-width: 500px; margin: 50px auto; padding: 50px 100px; h2{ margin-bottom: 0; } span{ padding-bottom: 10px; display: block; border-bottom: 1px solid #e3e3e3; } }