How do I create Form Wizard ng2-admin?
It'll take a bit of setup, but In the Theme's component folder, I created a folder called "baWizzard", which has the following folder structure:
Here is how you put them all together:
import { Component, OnInit, Output, EventEmitter, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
import { baWizzardStepComponent } from './baWizzardStep.component';
@Component({
selector: 'baWizzard',
styleUrls: ['./baWizzard.scss'],
templateUrl: './baWizzard.html'
})
export class baWizzardComponent implements OnInit, AfterContentInit {
@ContentChildren(baWizzardStepComponent) wizardSteps: QueryList<baWizzardStepComponent>;
private _steps: Array<baWizzardStepComponent> = [];
private _isCompleted: boolean = false;
@Output() onStepChanged: EventEmitter<baWizzardStepComponent> = new EventEmitter<baWizzardStepComponent>();
constructor() { }
ngOnInit() {
}
ngAfterContentInit() {
this.wizardSteps.forEach(step => this._steps.push(step));
this._steps[0].isActive = true;
}
private get steps(): Array<baWizzardStepComponent> {
return this._steps;
}
private get isCompleted(): boolean {
return this._isCompleted;
}
private get activeStep(): baWizzardStepComponent {
return this._steps.find(step => step.isActive);
}
private set activeStep(step: baWizzardStepComponent) {
if (step !== this.activeStep && !step.isDisabled) {
this.activeStep.isActive = false;
step.isActive = true;
this.onStepChanged.emit(step);
}
}
private get activeStepIndex(): number {
return this._steps.indexOf(this.activeStep);
}
private get hasNextStep(): boolean {
return this.activeStepIndex < this._steps.length - 1;
}
private get hasPrevStep(): boolean {
return this.activeStepIndex > 0;
}
goToStep(step: baWizzardStepComponent) {
this.activeStep = step;
}
next() {
if (this.hasNextStep) {
let nextStep: baWizzardStepComponent = this._steps[this.activeStepIndex + 1];
this.activeStep.onNext.emit();
nextStep.isDisabled = false;
this.activeStep = nextStep;
}
}
previous() {
if (this.hasPrevStep) {
let prevStep: baWizzardStepComponent = this._steps[this.activeStepIndex - 1];
this.activeStep.onPrev.emit();
prevStep.isDisabled = false;
this.activeStep = prevStep;
}
}
complete() {
this._isCompleted = true;
}
}
<div class="row">
<ul class="nav nav-justified">
<li class="nav-item col-md-{{12/steps.length}}" *ngFor="let step of steps" [ngClass]="{'active': step.isActive, 'enabled': !step.isDisabled, 'disabled': step.isDisabled}">
<a (click)="goToStep(step)">{{step.title}}</a>
</li>
</ul>
</div>
<div class="card-block">
<ng-content></ng-content><br>
<div class="" [hidden]="isCompleted">
<button type="button" class="btn btn-secondary float-left" style="float:left" (click)="previous()" [hidden]="!hasPrevStep || !activeStep.showPrev">Previous</button>
<button type="button" class="btn btn-secondary float-right" style="float:right" (click)="next()" [disabled]="!activeStep.isValid" [hidden]="!hasNextStep || !activeStep.showNext">Next</button>
<button type="button" class="btn btn-secondary float-right" style="float:right" (click)="complete()" [disabled]="!activeStep.isValid" [hidden]="hasNextStep" [routerLink]="['/pages/control-center']" >Done</button>
</div>
</div>
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'baWizzardStep',
templateUrl: './baWizzardStep.html'
})
export class baWizzardStepComponent implements OnInit {
@Input() title: string;
@Input() isValid: boolean = true;
@Input() showNext: boolean = true;
@Input() showPrev: boolean = true;
@Output() onNext: EventEmitter<any> = new EventEmitter();
@Output() onPrev: EventEmitter<any> = new EventEmitter();
@Output() onComplete: EventEmitter<any> = new EventEmitter();
private _isActive: boolean = false;
isDisabled: boolean = true;
constructor() { }
ngOnInit() {
}
@Input('isActive') set isActive(isActive: boolean) {
this._isActive = isActive;
this.isDisabled = false;
}
get isActive(): boolean {
return this._isActive;
}
}
<div [hidden]="!isActive">
<ng-content></ng-content>
</div>
export * from './baWizzard.component';
export * from './baWizzardStep.component'
Then declare baWizzard and baWizzardStep in the module that you want to use it in, and then mark up your HTML correctly like so:
<baWizzard>
<baWizzardStep [title]="'FirstFormStep'">
<!-- Custom Form Shit goes here. -->
</baWizzardStep
</baWizzard>
And repeat the baWizzardStep tags for however many steps you want your wizard to have.
@Bengejd please add code baWizzard.scss
Per requested heres the baWizzard.scss. Edit it as you like, I just made it so that it would be functional for the time being, will probably change the colors a little bit.
.card-block { overflow-y: auto; };
.card-footer { background-color: #fff; border-top: 0 none; };
.nav-item { padding: 1rem 0rem; border-bottom: 0.5rem solid #ccc; };
.active { font-weight: bold; color: black; border-bottom-color: #1976D2 !important; };
.enabled { border-bottom-color: rgb(88, 162, 234); };
.disabled { color: #ccc; };
@Bengejd how to dynamically add steps?
Most helpful comment
It'll take a bit of setup, but In the Theme's component folder, I created a folder called "baWizzard", which has the following folder structure:
/baWizzard/
Here is how you put them all together:
baWizzard.component.ts
baWizzard.html
baWizzardStep.component.ts
baWizzardStep.html
index.ts
Then declare baWizzard and baWizzardStep in the module that you want to use it in, and then mark up your HTML correctly like so:
<baWizzard> <baWizzardStep [title]="'FirstFormStep'"> <!-- Custom Form Shit goes here. --> </baWizzardStep </baWizzard>And repeat the baWizzardStep tags for however many steps you want your wizard to have.