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);
}
}
.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(() => {
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();
});
});

View File

@ -28,3 +28,51 @@
.mat-form-field-underline {
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 -->
<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
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
@ -25,6 +29,8 @@
<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"
fxFlex="1 0 auto" name="form" [formGroup]="form">
@ -41,16 +47,16 @@
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<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">
Required
First Name is required!
</mat-error>
</mat-form-field>
<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">
Required
Last Name is required!
</mat-error>
</mat-form-field>
@ -59,18 +65,18 @@
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto" fxLayoutWrap>
<mat-form-field fxFlex="100">
<textarea matInput placeholder="Address" formControlName="address">
<textarea matInput placeholder="Address" formControlName="address" required>
1600 Amphitheatre Pkwy
</textarea>
<mat-error *ngIf="formErrors.address.required">
Required
Address is required!
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="100">
<textarea matInput placeholder="Address 2" formControlName="address2"></textarea>
<mat-error *ngIf="formErrors.address2.required">
Required
Address 2 is required!
</mat-error>
</mat-form-field>
@ -79,32 +85,67 @@
<div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
<mat-form-field fxFlex="33">
<input matInput placeholder="City" formControlName="city">
<input matInput placeholder="City" formControlName="city" required>
<mat-error *ngIf="formErrors.city.required">
Required
City is required!
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="34">
<input matInput placeholder="State" formControlName="state">
<input matInput placeholder="State" formControlName="state" required>
<mat-error *ngIf="formErrors.state.required">
Required
State is required!
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="33">
<input matInput #postalCode placeholder="Postal Code" value="94043"
formControlName="postalCode">
formControlName="postalCode" required>
<mat-hint align="end">{{postalCode.value.length}} / 5</mat-hint>
<mat-error *ngIf="formErrors.postalCode.maxlength">
Postal Code needs to be max. {{formErrors.postalCode.maxlength.requiredLength}} characters
</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>
</div>
</form>
<!-- / REACTIVE FORM EXAMPLE -->
<div class="form-errors-model mat-white-bg p-24 mat-elevation-z4">
<div class="h2 mb-24">Reactive Form Errors Model</div>
@ -114,6 +155,313 @@
</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>
<!-- / CONTENT -->

View File

@ -14,5 +14,10 @@
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;
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)
{
// Reactive form errors
this.formErrors = {
company : {},
firstName : {},
lastName : {},
address : {},
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 : {},
state : {},
postalCode: {}
@ -27,6 +77,7 @@ export class FuseFormsComponent implements OnInit
ngOnInit()
{
// Reactive Form
this.form = this.formBuilder.group({
company : [
{
@ -40,12 +91,69 @@ export class FuseFormsComponent implements OnInit
address2 : ['', Validators.required],
city : ['', 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.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()
@ -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!');
}
}