Categories
Angular Material

Angular Material — Stepper

Angular Material is a popular UI framework based on Material Design for Angular.

In this article, we’ll look at how to use Angular Material into our Angular project.

Stepper

We can add steps display with the mat-horizontal-stepper component.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatStepperModule } from '@angular/material/stepper';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatStepperModule,
    MatFormFieldModule,
    FormsModule,
    ReactiveFormsModule,
    MatInputModule,
    MatButtonModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  firstFormGroup: FormGroup;
  secondFormGroup: FormGroup;
  isEditable = false;

  constructor(private _formBuilder: FormBuilder) { }

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

app.component.html

<div>
  <mat-horizontal-stepper linear #stepper>
    <mat-step [stepControl]="firstFormGroup" [editable]="true">
      <form [formGroup]="firstFormGroup">
        <ng-template matStepLabel>Fill out your name</ng-template>
        <mat-form-field>
          <mat-label>Name</mat-label>
          <input matInput formControlName="firstCtrl"
            placeholder="Name" required>
        </mat-form-field>
        <div>
          <button mat-button matStepperNext>Next</button>
        </div>
      </form>
    </mat-step>
    <mat-step [stepControl]="secondFormGroup" [editable]="true">
      <form [formGroup]="secondFormGroup">
        <ng-template matStepLabel>Fill out your address</ng-template>
        <mat-form-field>
          <mat-label>Address</mat-label>
          <input matInput formControlName="secondCtrl"
            placeholder="Address" required>
        </mat-form-field>
        <div>
          <button mat-button matStepperPrevious>Back</button>
          <button mat-button matStepperNext>Next</button>
        </div>
      </form>
    </mat-step>
    <mat-step>
      <ng-template matStepLabel>Done</ng-template>
      <p>You are now done.</p>
      <div>
        <button mat-button matStepperPrevious>Back</button>
        <button mat-button (click)="stepper.reset()">Reset</button>
      </div>
    </mat-step>
  </mat-horizontal-stepper>
</div>

We add the MatStepperModule to let us add the mat-horizontal-stepper and mat-step components.

The MatFormFieldComponent lets us add a form field.

The FormsModule and ReactiveFormsModule let us add the form validation to our app.

MatInputModule lets us add inputs to mat-form-fields with the matInput directive.

MatButtonModule lets us add Material Design style buttons.

In app.component.ts , we add the reactive forms.

Then in app.component.html , we add the mat-horizontal-stepper to add the stepper.

The mat-step components have the steps.

Each step has its own form with its own form field.

The editable attribute makes the step editable.

The matStepperNext directive makes the button go to the next step.

The formControlName attribute sets the form control name to the ones defined in the component class so that we can add form validation.

We need to add the formGroup attribute for this to work.

The stepper.reset method resets the stepper state.

Conclusion

We can add a stepper with the mat-step and mat-horizontal-stepper components.

Categories
Angular Material

Angular Material — Snackbar and Sort Header

Angular Material is a popular UI framework based on Material Design for Angular.

In this article, we’ll look at how to use Angular Material into our Angular project.

Snackbar

A snackbar is a container for notification.

The MatSnackBar service can be used to add it.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatButtonModule } from '@angular/material/button';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSnackBarModule,
    MatButtonModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';

@Component({
  selector: 'snack-bar-component-example-snack',
  template: 'pizza party',
  styles: [`
    .example-pizza-party {
      color: hotpink;
    }
  `],
})
export class PizzaPartyComponent { }

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  durationInSeconds = 5;

  constructor(private _snackBar: MatSnackBar) { }

  openSnackBar() {
    this._snackBar.openFromComponent(PizzaPartyComponent, {
      duration: this.durationInSeconds * 1000,
    });
  }
}

app.component.html

<div>
  <button mat-stroked-button (click)="openSnackBar()">
    Pizza party
  </button>
</div>

We add the MatSnackbarModule to let us add the snackbar.

Then in app.component.ts , we inject the MatSnackBar service into AppComponent to let us call the openFromComponent method with a component with the snackbar content.

The duration is in milliseconds.

In the template, we have a button to open the snackbar by calling the openSnackBar method.

Sort Header

We can add the sort header component to let us sort state and display tabular data.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSortModule } from '@angular/material/sort';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSortModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';
import { Sort } from '@angular/material/sort';

interface Dessert {
  name: string,
  calories: number,
  fat: number
}

const compare = (a: number | string, b: number | string, isAsc: boolean) => {
  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  desserts: Dessert[] = [
    { name: 'Frozen yogurt', calories: 159, fat: 6 },
    { name: 'Ice cream sandwich', calories: 237, fat: 4 },
    { name: 'Eclair', calories: 262, fat: 16, },
    { name: 'Cupcake', calories: 305, fat: 4, },
    { name: 'Gingerbread', calories: 356, fat: 16 },
  ];

  sortedData: Dessert[];

  constructor() {
    this.sortedData = this.desserts.slice();
  }

  sortData(sort: Sort) {
    const data = this.desserts.slice();
    if (!sort.active || sort.direction === '') {
      this.sortedData = data;
      return;
    }

    this.sortedData = data.sort((a, b) => {
      const isAsc = sort.direction === 'asc';
      switch (sort.active) {
        case 'name': return compare(a.name, b.name, isAsc);
        case 'calories': return compare(a.calories, b.calories, isAsc);
        case 'fat': return compare(a.fat, b.fat, isAsc);
        default: return 0;
      }
    });
  }
}

app.component.html

<div>
  <table matSort (matSortChange)="sortData($event)">
    <tr>
      <th mat-sort-header="name">Dessert (100g)</th>
      <th mat-sort-header="calories">Calories</th>
      <th mat-sort-header="fat">Fat (g)</th>
    </tr>

    <tr *ngFor="let dessert of sortedData">
      <td>{{dessert.name}}</td>
      <td>{{dessert.calories}}</td>
      <td>{{dessert.fat}}</td>
    </tr>
  </table>
</div>

We add the MatSortModule so that we can use the matSort directive into the table element.

Then we can click on the table header to sort the columns.

When we click on the header, the matSortChange event is emitted.

When it’s emitted, sortData is called.

Then, in app.component.ts , we call sort on the data and call our compare function to do the sorting.

Conclusion

We can add a snackbar and a sort header to sort table columns with Angular Material.

Categories
Angular Material

Angular Material — Sidenavs, Side Toggles, and Sliders

Angular Material is a popular UI framework based on Material Design for Angular.

In this article, we’ll look at how to use Angular Material into our Angular project.

Sidenav

Angular comes with a sidenav component.

We can add it by writing:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatButtonModule } from '@angular/material/button';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSidenavModule,
    MatButtonModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.module.html

<div>
  <mat-drawer-container class="example-container" autosize>
    <mat-drawer #drawer class="example-sidenav" mode="side">
      <p>Auto-resizing sidenav</p>
      <p *ngIf="showFiller">Lorem, ipsum dolor sit amet consectetur.</p>
      <button (click)="showFiller = !showFiller" mat-raised-button>
        Toggle extra text
      </button>
    </mat-drawer>

    <div class="example-sidenav-content">
      <button type="button" mat-button (click)="drawer.toggle()">
        Toggle sidenav
      </button>
    </div>
  </mat-drawer-container>
</div>

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  showFiller = false;
}

styles.css

.example-container {
  height: 100vh;
}

We add the sidenav with the mat-drawer-container as its container.

mat-drawer is the sidenav drawer.

The Toggle sidenav button shows the drawer.

The Toggle extra text button closes the drawer.

The filler text display is controlled by showFiller .

drawer.toggle() lets us toggle the drawer.

Slide Toggles

We can add a toggle with the mat-slide-toggle component.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSlideToggleModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<div>
  <mat-slide-toggle color="red" [checked]="true" [disabled]="false">
    Slide me!
  </mat-slide-toggle>
</div>

We add the MatSlideToggleModule into our module so that we can add the mat-slide-toggle component into the template.

checked sets the checked state.

disabled makes it disabled if it’s true .

color sets the color.

Slider

We can add a slider with the mat-slider component.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSliderModule } from '@angular/material/slider';
import { MatCardModule } from '@angular/material/card';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSliderModule,
    MatCardModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<div>
  <mat-card class="example-result-card">
    <mat-card-content>
      <mat-slider min="1" max="5" step="0.5" value="1.5"></mat-slider>
    </mat-card-content>
  </mat-card>
</div>

Adding the MatSliderModule lets us add the mat-slider to our template.

min has the minimum allowed value.

max has the maximum allowed value.

step has the interval we can set.

value is the value of the slider.

Conclusion

We can add sidenavs, slide toggles, and sliders into our Angular app with Angular Material.

Categories
Angular Material

Angular Material — Radio Buttons, Ripple Effects, and Select Dropdowns

Angular Material is a popular UI framework based on Material Design for Angular.

In this article, we’ll look at how to use Angular Material into our Angular project.

Radio Button

We can add a radio button with Angular Material.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatRadioModule } from '@angular/material/radio';
import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatRadioModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  favoriteFruit: string;
  fruits: string[] = ['apple', 'orange', 'grape'];
}

app.component.html

<div>
  <label>Pick your favorite fruit</label>
  <mat-radio-group [(ngModel)]="favoriteFruit">
    <mat-radio-button *ngFor="let fruit of fruits" [value]="fruit">
      {{fruit}}
    </mat-radio-button>
  </mat-radio-group>
  <div>Your favorite fruit is: {{favoriteFruit}}</div>
</div>

We import the MatRadioModule and FormsModule to add the radio button with data binding.

Then in app.component.html , we add the mat-radio-group to bind the value with ngModel .

Inside it, we loop through the fruits array and render the buttons with the mat-radio-button component.

The value has the radio button value.

Now when we click on a radio button, we should see the favoriteFruit value change since we bind the radio button value with ngModel .

Ripples

We can add a ripple effect when we click or tap on something.

For example, we can write:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatRippleModule } from '@angular/material/core';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatRippleModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  myColor = 'lightyellow'
}

app.component.html

<div>
  <div matRipple [matRippleColor]="myColor">
    hello world
  </div>
</div>

We import the MatRippleModule to add the effect.

Then we add the matRipple directive to the div with the matRippleColor to set the color of the ripple effect.

Now when we click or tap on ‘hello world’, we see the ripple effect.

Select

We can add a select dropdown with the MatSelectModule .

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSelectModule } from '@angular/material/select';
import { MatFormFieldModule } from '@angular/material/form-field';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSelectModule,
    MatFormFieldModule,
    FormsModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  toppings = new FormControl();
  toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato'];
}

app.component.html

<div>
  <mat-form-field appearance="fill">
    <mat-label>Toppings</mat-label>
    <mat-select [formControl]="toppings" multiple>
      <mat-select-trigger>
        {{toppings.value ? toppings.value[0] : ''}}
        <span *ngIf="toppings.value?.length > 1">
          (+{{toppings.value.length - 1}}
          {{toppings.value?.length === 2 ? 'other' : 'others'}})
        </span>
      </mat-select-trigger>
      <mat-option *ngFor="let topping of toppingList" [value]="topping">
        {{topping}}</mat-option>
    </mat-select>
  </mat-form-field>
</div>

We add the FormsModule and ReactiveFormsModule to let us bind the value selected with a reactive form control.

In the template, we rendered the toppingList with the mat-option component.

The mat-select-trigger lets us trigger the dropdown.

We display the selected items by rendering the toppings string.

Now we should see a dropdown that lets us pick one or more items from the list.

Conclusion

We can add radio buttons, ripple effects, and dropdowns with Angular Material.

Categories
Angular Material

Angular Material — Paginator and, Progress Bar, and Progress Spinner

Angular Material is a popular UI framework based on Material Design for Angular.

In this article, we’ll look at how to use Angular Material into our Angular project.

Paginator

The paginator component lets us add a form control to control the pagination settings.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatPaginatorModule } from '@angular/material/paginator';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatPaginatorModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<div>
  <mat-paginator [length]="100" [pageSize]="10"
    [pageSizeOptions]="[5, 10, 25, 100]">
  </mat-paginator>
</div>

We add the mat-paginator component to add a pagination control.

length is the total number of entries.

pageSize is the size of the page.

pageSizeOptions is an array of page sizes we can set.

Progress Bar

We can add a progress bar with the mat-progress-bar component.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatProgressBarModule } from '@angular/material/progress-bar';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatProgressBarModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<div>
  <mat-progress-bar mode="buffer"></mat-progress-bar>
</div>

We add the MatProgressBarModule to add a progress bar.

The mat-progress-bar adds the progress bar.

The mode attribute sets the appearance of the progress bar.

We can also make it determinate:

<div>
  <mat-progress-bar mode="determinate" value="40"></mat-progress-bar>
</div>

or indeterminate:

<div>
  <mat-progress-bar mode="indeterminate"></mat-progress-bar>
</div>

Progress Spinner

The mat-progress-spinner lets us add a progress spinner to our app.

For example, we can write:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatProgressSpinnerModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';
import { ThemePalette } from '@angular/_material_/core';
import { ProgressSpinnerMode } from '@angular/material/progress-spinner';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  color: ThemePalette = 'primary';
  mode: ProgressSpinnerMode = 'indeterminate';
  value = 50;
}

app.component.html

<div>
  <mat-progress-spinner class="example-margin" [color]="color" [mode]="mode"
    [value]="value">
  </mat-progress-spinner>
</div>

We add the MatProgressSpinnerModule to let us add the progress spinner.

Then in app.component.ts , we add the color , mode and value variables to set the color, spinner mode, and the progress value respectively.

In the template, we add the mat-progress-spinner component to set those variables to the attributes.

The value is used when the progress spinner has mode set to 'determinate' .

Conclusion

We can add the paginator, progress bar, and progress spinner with Angular Material.