Form Stepper examples

+ Simplified the mat-select style
+ Further simplified the mat-select in dashboard widgets
This commit is contained in:
Sercan Yemen 2017-11-30 15:37:32 +03:00
parent 0d8fe0be72
commit a65f61cce4
6 changed files with 555 additions and 15 deletions

View File

@ -62,4 +62,23 @@ fuse-widget {
transform: rotateY(360deg); transform: rotateY(360deg);
} }
} }
.mat-form-field {
&.mat-form-field-type-mat-select {
.mat-input-wrapper {
padding: 16px 0;
.mat-input-infix {
border: none;
padding: 0;
}
}
.mat-input-underline {
display: none;
}
}
}
} }

View File

@ -27,7 +27,9 @@ export class FuseWidgetComponent implements OnInit, AfterContentInit
setTimeout(() => { setTimeout(() => {
this.toggleButtons.forEach(flipButton => { this.toggleButtons.forEach(flipButton => {
this.renderer.listen(flipButton.el.nativeElement, 'click', () => { this.renderer.listen(flipButton.el.nativeElement, 'click', (event) => {
event.preventDefault();
event.stopPropagation();
this.toggle(); this.toggle();
}); });
}); });

View File

@ -28,3 +28,51 @@
.mat-form-field-underline { .mat-form-field-underline {
background-color: rgba(0, 0, 0, 0.12); background-color: rgba(0, 0, 0, 0.12);
} }
// Fix: "Some idiots using table-cell and inline-table in mat-select"
.mat-form-field {
&.mat-form-field-type-mat-select {
.mat-input-infix {
display: inline-flex;
width: auto;
.mat-select-trigger {
display: inline-flex;
align-items: center;
width: 100%;
.mat-select-value {
display: flex;
max-width: none;
margin-right: 8px;
}
.mat-select-arrow-wrapper {
display: inline-flex;
}
}
}
}
}
// Fix: "Stepper icons are broken due to Fuse's icon helpers"
mat-horizontal-stepper,
mat-vertical-stepper {
mat-step-header {
mat-icon {
height: 16px !important;
width: 16px !important;
min-width: 0 !important;
min-height: 0 !important;
color: rgba(255, 255, 255, 0.87) !important;
}
}
}
mat-vertical-stepper {
padding: 16px 0;
}

View File

@ -16,7 +16,11 @@
<!-- CONTENT --> <!-- CONTENT -->
<div class="content p-24"> <div class="content p-24">
<p class="mb-32"> <div class="h1">
Reactive Forms
</div>
<p class="pt-16 pb-32">
Angular reactive forms facilitate a reactive style of programming that favors explicit management of the Angular reactive forms facilitate a reactive style of programming that favors explicit management of the
data flowing between a non-UI data model (typically retrieved from a server) and a UI-oriented form model data flowing between a non-UI data model (typically retrieved from a server) and a UI-oriented form model
that retains the states and values of the HTML controls on screen. Reactive forms offer the ease of using that retains the states and values of the HTML controls on screen. Reactive forms offer the ease of using
@ -25,6 +29,8 @@
<div fxLayout="column" fxLayoutAlign="start start" fxLayout.gt-md="row"> <div fxLayout="column" fxLayoutAlign="start start" fxLayout.gt-md="row">
<!-- REACTIVE FORM EXAMPLE -->
<form class="mat-white-bg mat-elevation-z4 p-24 mr-24 mb-24" fxLayout="column" fxLayoutAlign="start" <form class="mat-white-bg mat-elevation-z4 p-24 mr-24 mb-24" fxLayout="column" fxLayoutAlign="start"
fxFlex="1 0 auto" name="form" [formGroup]="form"> fxFlex="1 0 auto" name="form" [formGroup]="form">
@ -41,16 +47,16 @@
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto"> <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field fxFlex="50"> <mat-form-field fxFlex="50">
<input matInput placeholder="First name" formControlName="firstName"> <input matInput placeholder="First name" formControlName="firstName" required>
<mat-error *ngIf="formErrors.firstName.required"> <mat-error *ngIf="formErrors.firstName.required">
Required First Name is required!
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="50"> <mat-form-field fxFlex="50">
<input matInput placeholder="Last name" formControlName="lastName"> <input matInput placeholder="Last name" formControlName="lastName" required>
<mat-error *ngIf="formErrors.lastName.required"> <mat-error *ngIf="formErrors.lastName.required">
Required Last Name is required!
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
@ -59,18 +65,18 @@
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto" fxLayoutWrap> <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto" fxLayoutWrap>
<mat-form-field fxFlex="100"> <mat-form-field fxFlex="100">
<textarea matInput placeholder="Address" formControlName="address"> <textarea matInput placeholder="Address" formControlName="address" required>
1600 Amphitheatre Pkwy 1600 Amphitheatre Pkwy
</textarea> </textarea>
<mat-error *ngIf="formErrors.address.required"> <mat-error *ngIf="formErrors.address.required">
Required Address is required!
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="100"> <mat-form-field fxFlex="100">
<textarea matInput placeholder="Address 2" formControlName="address2"></textarea> <textarea matInput placeholder="Address 2" formControlName="address2"></textarea>
<mat-error *ngIf="formErrors.address2.required"> <mat-error *ngIf="formErrors.address2.required">
Required Address 2 is required!
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
@ -79,32 +85,67 @@
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto"> <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field fxFlex="33"> <mat-form-field fxFlex="33">
<input matInput placeholder="City" formControlName="city"> <input matInput placeholder="City" formControlName="city" required>
<mat-error *ngIf="formErrors.city.required"> <mat-error *ngIf="formErrors.city.required">
Required City is required!
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="34"> <mat-form-field fxFlex="34">
<input matInput placeholder="State" formControlName="state"> <input matInput placeholder="State" formControlName="state" required>
<mat-error *ngIf="formErrors.state.required"> <mat-error *ngIf="formErrors.state.required">
Required State is required!
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="33"> <mat-form-field fxFlex="33">
<input matInput #postalCode placeholder="Postal Code" value="94043" <input matInput #postalCode placeholder="Postal Code" value="94043"
formControlName="postalCode"> formControlName="postalCode" required>
<mat-hint align="end">{{postalCode.value.length}} / 5</mat-hint> <mat-hint align="end">{{postalCode.value.length}} / 5</mat-hint>
<mat-error *ngIf="formErrors.postalCode.maxlength"> <mat-error *ngIf="formErrors.postalCode.maxlength">
Postal Code needs to be max. {{formErrors.postalCode.maxlength.requiredLength}} characters Postal Code needs to be max. {{formErrors.postalCode.maxlength.requiredLength}} characters
</mat-error> </mat-error>
<mat-error *ngIf="formErrors.postalCode.required">
Postal Code is required!
</mat-error>
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field fxFlex="100">
<mat-select placeholder="Country" formControlName="country" required>
<mat-option [value]="'United States of America'">
United States of America
</mat-option>
<mat-option [value]="'United Kingdom'">
United Kingdom
</mat-option>
<mat-option [value]="'Russia'">
Russia
</mat-option>
<mat-option [value]="'China'">
China
</mat-option>
<mat-option [value]="'Japan'">
Japan
</mat-option>
<mat-option [value]="'Turkey'">
Turkey
</mat-option>
</mat-select>
<mat-error *ngIf="formErrors.country.required">
Country is required!
</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>
</form> </form>
<!-- / REACTIVE FORM EXAMPLE -->
<div class="form-errors-model mat-white-bg p-24 mat-elevation-z4"> <div class="form-errors-model mat-white-bg p-24 mat-elevation-z4">
<div class="h2 mb-24">Reactive Form Errors Model</div> <div class="h2 mb-24">Reactive Form Errors Model</div>
@ -114,6 +155,313 @@
</div> </div>
<div class="h1 pt-32">
Horizontal Stepper
</div>
<p class="pb-32">
Angular Material's stepper provides a wizard-like workflow by dividing content into logical steps.
<code>mat-horizontal-stepper</code> selector can be used to create a horizontal stepper.
</p>
<div class="horizontal-stepper-wrapper">
<!-- HORIZONTAL STEPPER EXAMPLE -->
<mat-horizontal-stepper class="mat-elevation-z4" [linear]="true">
<mat-step [stepControl]="horizontalStepperStep1">
<form [formGroup]="horizontalStepperStep1">
<ng-template matStepLabel>Fill out your name</ng-template>
<div>
<mat-form-field fxFlex="50">
<input matInput placeholder="First name" formControlName="firstName" required>
<mat-error *ngIf="horizontalStepperStep1Errors.firstName.required">
First Name is required!
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="50">
<input matInput placeholder="Last name" formControlName="lastName" required>
<mat-error *ngIf="formErrors.lastName.required">
Last Name is required!
</mat-error>
</mat-form-field>
</div>
<div class="pt-24" fxLayout="row" fxLayoutAlign="center center">
<button mat-raised-button matStepperNext type="button" color="accent">
Next
</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="horizontalStepperStep2">
<form [formGroup]="horizontalStepperStep2">
<ng-template matStepLabel>Fill out your address</ng-template>
<div>
<mat-form-field fxFlex="100">
<textarea matInput placeholder="Address" formControlName="address" required>
1600 Amphitheatre Pkwy
</textarea>
<mat-error *ngIf="horizontalStepperStep2Errors.address.required">
Address is required!
</mat-error>
</mat-form-field>
</div>
<div class="pt-24" fxLayout="row" fxLayoutAlign="center center">
<button class="mr-8" mat-raised-button matStepperPrevious type="button" color="accent">
Previous
</button>
<button mat-raised-button matStepperNext type="button" color="accent">
Next
</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="horizontalStepperStep3">
<form [formGroup]="horizontalStepperStep3">
<ng-template matStepLabel>Fill out your address</ng-template>
<div>
<mat-form-field fxFlex="33">
<input matInput placeholder="City" formControlName="city" required>
<mat-error *ngIf="horizontalStepperStep3Errors.city.required">
City is required!
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="34">
<input matInput placeholder="State" formControlName="state" required>
<mat-error *ngIf="horizontalStepperStep3Errors.state.required">
State is required!
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="33">
<input matInput #postalCode placeholder="Postal Code" formControlName="postalCode"
required>
<mat-hint align="end">{{postalCode.value.length}} / 5</mat-hint>
<mat-error *ngIf="horizontalStepperStep3Errors.postalCode.maxlength">
Postal Code needs to be max.
{{horizontalStepperStep3Errors.postalCode.maxlength.requiredLength}} characters
</mat-error>
<mat-error *ngIf="horizontalStepperStep3Errors.postalCode.required">
Postal Code is required!
</mat-error>
</mat-form-field>
</div>
<div class="pt-24" fxLayout="row" fxLayoutAlign="center center">
<button class="mr-8" mat-raised-button matStepperPrevious type="button" color="accent">
Previous
</button>
<button mat-raised-button matStepperNext type="button" color="accent">
Next
</button>
</div>
</form>
</mat-step>
<mat-step>
<ng-template matStepLabel>Done</ng-template>
<div class="h2 m-16" fxLayout="row" fxLayoutAlign="center center">
Thank your for filling out our form.
</div>
<div class="pt-24" fxLayout="row" fxLayoutAlign="center center">
<button class="mr-8" mat-raised-button matStepperPrevious type="button" color="accent">
Previous
</button>
<button mat-raised-button type="button" color="accent" (click)="finishHorizontalStepper()">
Finish
</button>
</div>
</mat-step>
</mat-horizontal-stepper>
<!-- / HORIZONTAL STEPPER EXAMPLE -->
</div>
<div class="h1 pt-48">
Vertical Stepper
</div>
<p class="pb-32">
Angular Material's stepper provides a wizard-like workflow by dividing content into logical steps.
<code>mat-vertical-stepper</code> can be used to create a vertical stepper.
</p>
<div class="vertical-stepper-wrapper">
<!-- VERTICAL STEPPER EXAMPLE -->
<mat-vertical-stepper class="mat-elevation-z4" [linear]="true">
<mat-step [stepControl]="verticalStepperStep1">
<form [formGroup]="verticalStepperStep1">
<ng-template matStepLabel>Fill out your name</ng-template>
<div>
<mat-form-field fxFlex="50">
<input matInput placeholder="First name" formControlName="firstName" required>
<mat-error *ngIf="verticalStepperStep1Errors.firstName.required">
First Name is required!
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="50">
<input matInput placeholder="Last name" formControlName="lastName" required>
<mat-error *ngIf="formErrors.lastName.required">
Last Name is required!
</mat-error>
</mat-form-field>
</div>
<div class="pt-24" fxLayout="row" fxLayoutAlign="center center">
<button mat-raised-button matStepperNext type="button" color="accent">
Next
</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="verticalStepperStep2">
<form [formGroup]="verticalStepperStep2">
<ng-template matStepLabel>Fill out your address</ng-template>
<div>
<mat-form-field fxFlex="100">
<textarea matInput placeholder="Address" formControlName="address" required>
1600 Amphitheatre Pkwy
</textarea>
<mat-error *ngIf="verticalStepperStep2Errors.address.required">
Address is required!
</mat-error>
</mat-form-field>
</div>
<div class="pt-24" fxLayout="row" fxLayoutAlign="center center">
<button class="mr-8" mat-raised-button matStepperPrevious type="button" color="accent">
Previous
</button>
<button mat-raised-button matStepperNext type="button" color="accent">
Next
</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="verticalStepperStep3">
<form [formGroup]="verticalStepperStep3">
<ng-template matStepLabel>Fill out your address</ng-template>
<div>
<mat-form-field fxFlex="33">
<input matInput placeholder="City" formControlName="city" required>
<mat-error *ngIf="verticalStepperStep3Errors.city.required">
City is required!
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="34">
<input matInput placeholder="State" formControlName="state" required>
<mat-error *ngIf="verticalStepperStep3Errors.state.required">
State is required!
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="33">
<input matInput #postalCode placeholder="Postal Code" formControlName="postalCode"
required>
<mat-hint align="end">{{postalCode.value.length}} / 5</mat-hint>
<mat-error *ngIf="verticalStepperStep3Errors.postalCode.maxlength">
Postal Code needs to be max.
{{verticalStepperStep3Errors.postalCode.maxlength.requiredLength}} characters
</mat-error>
<mat-error *ngIf="verticalStepperStep3Errors.postalCode.required">
Postal Code is required!
</mat-error>
</mat-form-field>
</div>
<div class="pt-24" fxLayout="row" fxLayoutAlign="center center">
<button class="mr-8" mat-raised-button matStepperPrevious type="button" color="accent">
Previous
</button>
<button mat-raised-button matStepperNext type="button" color="accent">
Next
</button>
</div>
</form>
</mat-step>
<mat-step>
<ng-template matStepLabel>Done</ng-template>
<div class="h2 m-16" fxLayout="row" fxLayoutAlign="center center">
Thank your for filling out our form.
</div>
<div class="pt-24" fxLayout="row" fxLayoutAlign="center center">
<button class="mr-8" mat-raised-button matStepperPrevious type="button" color="accent">
Previous
</button>
<button mat-raised-button type="button" color="accent" (click)="finishVerticalStepper()">
Finish
</button>
</div>
</mat-step>
</mat-vertical-stepper>
<!-- / VERTICAL STEPPER EXAMPLE -->
</div>
</div> </div>
<!-- / CONTENT --> <!-- / CONTENT -->

View File

@ -14,5 +14,10 @@
background: none !important; background: none !important;
} }
} }
.horizontal-stepper-wrapper,
.vertical-stepper-wrapper {
max-width: 800px;
}
} }
} }

View File

@ -11,14 +11,64 @@ export class FuseFormsComponent implements OnInit
form: FormGroup; form: FormGroup;
formErrors: any; formErrors: any;
// Horizontal Stepper
horizontalStepperStep1: FormGroup;
horizontalStepperStep2: FormGroup;
horizontalStepperStep3: FormGroup;
horizontalStepperStep1Errors: any;
horizontalStepperStep2Errors: any;
horizontalStepperStep3Errors: any;
// Vertical Stepper
verticalStepperStep1: FormGroup;
verticalStepperStep2: FormGroup;
verticalStepperStep3: FormGroup;
verticalStepperStep1Errors: any;
verticalStepperStep2Errors: any;
verticalStepperStep3Errors: any;
constructor(private formBuilder: FormBuilder) constructor(private formBuilder: FormBuilder)
{ {
// Reactive form errors
this.formErrors = { this.formErrors = {
company : {}, company : {},
firstName : {}, firstName : {},
lastName : {}, lastName : {},
address : {}, address : {},
address2 : {}, address2 : {},
city : {},
state : {},
postalCode: {},
country : {}
};
// Horizontal Stepper form error
this.horizontalStepperStep1Errors = {
firstName: {},
lastName : {}
};
this.horizontalStepperStep2Errors = {
address: {}
};
this.horizontalStepperStep3Errors = {
city : {},
state : {},
postalCode: {}
};
// Vertical Stepper form error
this.verticalStepperStep1Errors = {
firstName: {},
lastName : {}
};
this.verticalStepperStep2Errors = {
address: {}
};
this.verticalStepperStep3Errors = {
city : {}, city : {},
state : {}, state : {},
postalCode: {} postalCode: {}
@ -27,6 +77,7 @@ export class FuseFormsComponent implements OnInit
ngOnInit() ngOnInit()
{ {
// Reactive Form
this.form = this.formBuilder.group({ this.form = this.formBuilder.group({
company : [ company : [
{ {
@ -40,12 +91,69 @@ export class FuseFormsComponent implements OnInit
address2 : ['', Validators.required], address2 : ['', Validators.required],
city : ['', Validators.required], city : ['', Validators.required],
state : ['', Validators.required], state : ['', Validators.required],
postalCode: ['', [Validators.required, Validators.maxLength(5)]] postalCode: ['', [Validators.required, Validators.maxLength(5)]],
country : ['', Validators.required]
}); });
this.form.valueChanges.subscribe(() => { this.form.valueChanges.subscribe(() => {
this.onFormValuesChanged(); this.onFormValuesChanged();
}); });
// Horizontal Stepper form steps
this.horizontalStepperStep1 = this.formBuilder.group({
firstName: ['', Validators.required],
lastName : ['', Validators.required]
});
this.horizontalStepperStep2 = this.formBuilder.group({
address: ['', Validators.required]
});
this.horizontalStepperStep3 = this.formBuilder.group({
city : ['', Validators.required],
state : ['', Validators.required],
postalCode: ['', [Validators.required, Validators.maxLength(5)]]
});
this.horizontalStepperStep1.valueChanges.subscribe(() => {
this.onFormValuesChanged();
});
this.horizontalStepperStep2.valueChanges.subscribe(() => {
this.onFormValuesChanged();
});
this.horizontalStepperStep3.valueChanges.subscribe(() => {
this.onFormValuesChanged();
});
// Vertical Stepper form stepper
this.verticalStepperStep1 = this.formBuilder.group({
firstName: ['', Validators.required],
lastName : ['', Validators.required]
});
this.verticalStepperStep2 = this.formBuilder.group({
address: ['', Validators.required]
});
this.verticalStepperStep3 = this.formBuilder.group({
city : ['', Validators.required],
state : ['', Validators.required],
postalCode: ['', [Validators.required, Validators.maxLength(5)]]
});
this.verticalStepperStep1.valueChanges.subscribe(() => {
this.onFormValuesChanged();
});
this.verticalStepperStep2.valueChanges.subscribe(() => {
this.onFormValuesChanged();
});
this.verticalStepperStep3.valueChanges.subscribe(() => {
this.onFormValuesChanged();
});
} }
onFormValuesChanged() onFormValuesChanged()
@ -69,4 +177,14 @@ export class FuseFormsComponent implements OnInit
} }
} }
} }
finishHorizontalStepper()
{
alert('You have finished the horizontal stepper!');
}
finishVerticalStepper()
{
alert('You have finished the vertical stepper!');
}
} }