Using separate components in a linear mat-horizontal-stepper

mat-stepper with different components
mat-horizontal-stepper example
mat stepper (selectedindex)
angular material stepper validation
mat stepper (selectionchange)
angular material stepper responsive
can t bind to linear since it isn t a known property of mat-horizontal-stepper
mat-step events

In Angular, is it possible to have a linear stepper where the individual steps are separate components? For example:

<mat-horizontal-stepper [linear]="isLinear">
    <mat-step [stepControl]="firstFormGroup" label="Some Form">
        <first-component></first-component>
    </mat-step>
    <mat-step [stepControl]="secondFormGroup" label="Another Form">
        <second-component></second-component>
    </mat-step>
    <mat-step [stepControl]="thirdFormGroup" label="Review">
        <third-component></third-component>
    </mat-step>
</mat-horizontal-stepper>

When I try this, I receive the following error upon hitting the matStepperNext button:

TypeError: Cannot read property 'invalid' of undefined.


Here is the solution that work for me.

<mat-horizontal-stepper [linear]="true" #stepper>
  <mat-step [stepControl]="selectAdvType">
    <ng-template matStepLabel>
      <div class="text-center">
        <mat-icon>queue_play_next</mat-icon><br /><span>Select Adv Type</span>
      </div>
    </ng-template>
    <app-advertisement-type></app-advertisement-type>
  </mat-step>
  <mat-step [stepControl]="selectAdvType">
    <ng-template matStepLabel>
      <div class="text-center">
        <mat-icon>directions_car</mat-icon><br /><span>Select Car</span>
      </div>
    </ng-template>
    <app-select-car-adv></app-select-car-adv>
  </mat-step>
  <mat-step>
    <ng-template matStepLabel>
      <div class="text-center">
        <mat-icon>description</mat-icon><br /><span>Select Features</span>
      </div>
    </ng-template>
    <div>
      <button mat-button matStepperPrevious>Back</button>
      <button mat-button (click)="stepper.reset()">Reset</button>
    </div>
  </mat-step>
</mat-horizontal-stepper>

Parent Ts file

@Component({
  selector: 'app-customer.create.advertisement',
  templateUrl: './customer.create.advertisement.component.html',
  styleUrls: ['./customer.create.advertisement.component.scss']
})
export class CustomerCreateAdvertisementComponent implements OnInit {
  isLinear = false;
  selectAdvType: FormGroup;
  constructor(private _formBuilder: FormBuilder) { }
  ngOnInit() {
    this.selectAdvType = this._formBuilder.group({
      firstCtrl: ['', Validators.required]
    });
  }
}

Child component

<form [formGroup]="firstFormGroup">
    <ng-template matStepLabel>Fill out your name</ng-template>
    <mat-form-field>
        <input matInput placeholder="Last name, First name" formControlName="firstCtrl" required>
    </mat-form-field>
    <div>
        <button mat-button matStepperNext>Next</button>
    </div>
</form>


@Component({
  selector: 'app-advertisement-type',
  templateUrl: './advertisement-type.component.html',
  styleUrls: ['./advertisement-type.component.scss']
})
export class AdvertisementTypeComponent implements OnInit {
  firstFormGroup: FormGroup;
  constructor(private _formBuilder: FormBuilder) { }

  ngOnInit() {
    this.firstFormGroup = this._formBuilder.group({
      firstCtrl: ['', Validators.required]
    });
  }

}

Using separate components in a linear mat-horizontal-stepper , Here is the solution that work for me. <mat-horizontal-stepper [linear]="true" #​stepper> <mat-step [stepControl]="selectAdvType"> <ng-template  The only way to expand my content vertically in order to cover the entire vertical space is to add the style 'height: 100%' to 'mat-horizontal-stepper-content' and 'mat-horizontal-content-container' classes. Unfortunately, the 'mat-horizontal-stepper-content' is shared amongs all the steps and this will grow also the step 1 div (that is hidden).


You can use sub-forms to resolve it. I actually gave a talk a few months ago in Angular-UP conference about it: https://www.youtube.com/watch?v=sb7tgsNF2Jk

The idea, in general, is to create the form in the child component, inject the controlContainer using DI and setting the local form to be the controlContainer form.

Child Component:

 @Component({
  selector: 'app-company-info',
  templateUrl: './company-info.component.html',
  styleUrls: ['./company-info.component.scss'],
  viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class CompanyInfoComponent implements OnInit {

  form: FormGroup;
  constructor(
    private ctrlContainer: FormGroupDirective,
    private fb: FormBuilder) { }

  ngOnInit() {

    this.form = this.ctrlContainer.form;

    this.form.addControl('company',
      this.fb.group({
        'companyName': this.fb.control(null, [Validators.required]),
        'numOfEmployees': this.fb.control(null, [Validators.required])});

  }

}

Parent Component (html):

<mat-horizontal-stepper [linear]="isLinear" #stepper>
  <mat-step [stepControl]="companyInfo">
    <ng-template matStepLabel>Fill out your name</ng-template>

    <form [formGroup]="companyInfo">
      <app-company-info></app-company-info>
    </form>

    <div>
      <button mat-button matStepperNext>Next</button>
    </div>
  </mat-step>
</mat-horizontal-stepper>

Parent Component (ts):

export class WizardComponent implements OnInit {

  isLinear = true;
  companyInfo: FormGroup;

  constructor(private _formBuilder: FormBuilder) {

  }

  ngOnInit() {

    this.companyInfo = this._formBuilder.group({
    });

  }

}

Linear mode is not working in mat-horizontal-stepper with separate , You could access your child's components using @ViewChild and access the child's form from your parent's html, for example:. I'm having the same issue. I include two forms (each as a component) from a different module as two separate steps in a stepper control. Everything I've tried with this setup ("matStepperNext", etc.) all works well except for this linear=true.


Ok, I think I see a few issues:

<mat-horizontal-stepper [linear]="isLinear">
  <mat-step [stepControl]="foodFormGroup">
    <food-selection></food-selection>
  </mat-step>
  <mat-step [stepControl]="pieFormGroup">
    <pie-selection></pie-selection>
  </mat-step>
</mat-horizontal-stepper>

foodFormGroup and pieFormGroup need to be defined in your tough-choice.component.ts file (Which, btw is misspelled in your example code)

Here's an example (from the docs) of how this might look:

import {Component} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';

/**
 * @title Stepper overview
 */
@Component({
  selector: 'stepper-overview-example',
  templateUrl: 'stepper-overview-example.html',
  styleUrls: ['stepper-overview-example.css']
})
export class StepperOverviewExample {
  isLinear = false;
  firstFormGroup: FormGroup;
  secondFormGroup: FormGroup;

  constructor(private _formBuilder: FormBuilder) { }

  ngOnInit() {
    this.firstFormGroup = this._formBuilder.group({
      firstCtrl: ['', Validators.required]
    });
    this.secondFormGroup = this._formBuilder.group({
      secondCtrl: ['', Validators.required]
    });
  }
}

Also, I don't see a module.ts file in your example. That's where you would want to import your @angular/material modules, not in the component files.

I'd suggest just giving the Angular Material documentation a once-over. https://material.angular.io/components/stepper/overview

Stepper, mat-horizontal-stepper selector can be used to create a horizontal stepper, and mat-step components need to be placed inside either one of the two stepper The linear attribute can be set on mat-horizontal-stepper and mat-vertical-stepper a single form for stepper, and the other is using a different form for each step. Step headers can use either text or icons as the label. The actual step content can contain text, images, components or media. The Code. In our example, we use the mat-card in one of the steps. In order to separate the look of those cards, we add a bit of css to the component..example-card { max-width: 400px; margin: 1rem; }


Anwsered in this post: angular - Angular Material 2 Stepper Controls

*Sorry if this is not the correct way of linking another post.

Using separate components in a linear mat-horizontal-stepper, The only difference is the orientation of stepper. mat-horizontal-stepper need to be placed inside either one of the two stepper components. The linear attribute can be set on mat-horizontal-stepper and mat-vertical-stepper to One is using a single form for stepper, and the other is using a different form for each step. The Adafruit motor shield can run two stepper motors using four wires for each so we're going to connect white and red and orange and blue to stepper motor port to. The adafruit motor shield Has a library called AFmotorwhich is a high level library running the motor shield, we will use this library.


mat-horizontal-stepper: Unable to set linear=true · Issue #7699 , In Angular, is it possible to have a linear stepper where the individual steps are separate components? For example: <mat-horizontal-stepper  UI component infrastructure and Material Design components for mobile and desktop Angular web applications.


Stepper completes steps when component based forms are invalid , I include two forms (each as a component) from a different module as two separate steps in a stepper control. Everything I've tried with this setup (  Subscribe to this blog. Linear mode is not working in mat-horizontal-stepper with separate components


Angular Material Stepper, Linear Stepper should see invalid forms from component and NOT move upon Here is a github Repo where I use angular forms in 3 different components, and use the <mat-horizontal-stepper linear #stepper> <mat-step  Clash Royale CLAN TAG #URR8PPP. Child Component to wait for Parent Component ngOnInit async operation before initializing. I'm using mat-stepper for implementing customer onboarding process.