DEV Community

Cover image for Develop a cross-platform application by Angular and Ignite UI for Angular part 1
Kenichiro Nakamura
Kenichiro Nakamura

Posted on • Edited on

Develop a cross-platform application by Angular and Ignite UI for Angular part 1

In this article, I will create simple sample user management application.

Ignite UI for Angular

Ignite UI for Angular is released from Infragistics. It is free of charge if you use it for community effort.Ignite UI for Angular
Even though it works very well as mobile application, I will create desktop size application first.

The environment I use in this article

  • Node.js v8.7.0 and npm v5.5.1
  • Visual Studio Code

Create an Angular Project

Follow the steps below to create new Angular project.

1. Install Angular CLI via npm

npm install -g @angular/cli
Enter fullscreen mode Exit fullscreen mode

2. Run the Angular CLI command to create a project. In this case, I specify --routing option to enable routing for the project.

ng new ignite-ui-app --routing
cd ignite-ui-app
Enter fullscreen mode Exit fullscreen mode

3. Then install Ignite UI component and dependencies. hammer.js is library to support touch and gesture.

npm install igniteui-angular hammerjs @types/hammerjs
npm install
Enter fullscreen mode Exit fullscreen mode

4. Launch the project via Visual Studio Code.

code .
Enter fullscreen mode Exit fullscreen mode

5. Then include css for styles in .angular-cli.json.

Capture.PNG

6. Try to run it at this moment to make sure all works.

ng server --open
Enter fullscreen mode Exit fullscreen mode

It opens a browser and you shall see the basic application like below.
Capture.PNG

Right start developing the application using Ignite UI!

Create an application shell

Navigation Bar

1. First of all, let's add navigation on top of the application. To use Ignite UI controls, you need to register appropriate modules in src/app/app.module.ts. I also added hammer.js at this point as dependency module.

src/app/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 { IgxNavbarModule } from 'igniteui-angular/main';
import "hammerjs"; 

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    IgxNavbarModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

2. Add component to .html file and logics to .ts file. In this case, I use "menu" icon, but you can pick up whatever you want from https://material.io/icons/.

src/app/app.component.html

<!--The content below is only a placeholder and can be replaced.-->
<igx-navbar [title]="title"    
   actionButtonIcon="menu"
   (onAction)="onClickMenu()">
</igx-navbar>

<router-outlet></router-outlet>
Enter fullscreen mode Exit fullscreen mode

src/app/app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styles: []
})
export class AppComponent {
  title = 'Ignite Ui App';

  onClickMenu(){
    window.alert("menu clicked");
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Once you saved, the browser automatically reload the contents.
Capture.PNG

4. Click the menu icon on upper left corner to make sure it shows an alert.

Icon

There are many ways to utilize icons. Let's add them inside the navigation bar.

1. Add a module first.

src/app/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 { IgxNavbarModule, IgxIconModule } from 'igniteui-angular/main';
import "hammerjs"; 

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    IgxNavbarModule,
    IgxIconModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

2. Then add "Add" icon to igx-icon element.

src/app/app.component.html

<!--The content below is only a placeholder and can be replaced.-->
<igx-navbar [title]="title"    
   actionButtonIcon="menu"
   (onAction)="onClickMenu()">
   <igx-icon name="add" (click)="onClickAdd()"></igx-icon>
   <igx-icon name="refresh" (click)="onClickRefresh()"></igx-icon>
</igx-navbar>

<router-outlet></router-outlet>
Enter fullscreen mode Exit fullscreen mode

src/app/app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'Ignite Ui App';

  onClickMenu(){
    window.alert("menu clicked");
  }

  onClickAdd(){
    window.alert("add clicked");
  }

  onClickRefresh(){
    window.alert("refresh clicked");
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Once saved, try clicking each buttons.
Capture.PNG

List

Now the application has navigation bar on top, let's add list on the left pane.

Scroll List

Ignite UI provide "List" control and "Scroll" control. List provides more capabilities, and scroll gives use scrolling capability. I use scroll control in this application.

1. Add module first.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { IgxNavbarModule, IgxIconModule, IgxScrollModule } from 'igniteui-angular/main';
import "hammerjs"; 

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    IgxNavbarModule, 
    IgxIconModule, 
    IgxScrollModule, 
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

2. Then add Angular Component to the application. You can keep adding the features inside main module, but to simply it, you can create separate module for each feature.

ng generate component list
Enter fullscreen mode Exit fullscreen mode

3. Modify app.component.html to load the added module and update app.component.css for styling. To bi-directional binding, you can combine [] and () like [(selectedUser)].

src/app/app.component.html

<!--The content below is only a placeholder and can be replaced.-->
<igx-navbar [title]="title" actionButtonIcon="menu" (onAction)="onClickMenu()">
  <igx-icon name="add" (click)="onClickAdd()"></igx-icon>
  <igx-icon name="refresh" (click)="onClickRefresh()"></igx-icon>
</igx-navbar>

<app-list [(selectedUser)]="selectedUser"></app-list> 
<router-outlet></router-outlet>
<div>{{selectedUser.name}}</div>
Enter fullscreen mode Exit fullscreen mode

src/app/app.component.css

app-list, div {
    float: left;
}
Enter fullscreen mode Exit fullscreen mode

src/app/app.component.ts

import { Component } from '@angular/core';
import { User } from './models/user';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'Ignite Ui App';
  public selectedUser: User = new User("", "", 0);

  onClickMenu() {
    window.alert("menu clicked");
  }

  onClickAdd() {
    window.alert("add clicked");
  }

  onClickRefresh() {
    window.alert("refresh clicked");
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Next, add a User model in Models folder. You can do so by running Angular CLI command.

ng generate class models/user
Enter fullscreen mode Exit fullscreen mode

src/app/models/user.ts

export class User {
    public image: string
    public name: string
    public id: number

    constructor(image: string, name: string, id: number) {
        this.image = image;
        this.name = name;
        this.id = id;
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Now, modify the List component you just added. First of all, import modules, and update UI. The modules I use this time are IxgScroll and IgxScrollEvent, which support scrolling and related event. To bind selectedUser, you need to add @Input and @Output property, and return the value in OnItemSelect function. Once you get used to how Angular works with binding, it shouldn't be too difficult.

src/app/list/list.component.ts

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { IgxScroll, IgxScrollEvent } from "igniteui-angular/main";
import { User } from '../models/user';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {
  @Input() selectedUser: User;
  @Output() selectedUserChange: EventEmitter<User> = new EventEmitter();

  constructor() {
    for (let i = 1; i <= 22; i++) {
      this.users.push(new User(
        `http://www.infragistics.com/angular-demos/assets/images/avatar/${i}.jpg`,
        "User: " + i,
        i
      ));
    }

    this.visibleUsers = this.users.slice(0, this.visibleUsersCount);
  }

  public users: User[] = new Array<User>();
  public visibleUsers: User[];
  public visibleUsersCount: number = 8;

  ngOnInit() {
  }

  private onItemSelect(user: User): void {
    this.selectedUserChange.emit(user);
  }

  private updateList($event: IgxScrollEvent): void {
    this.visibleUsers = this.users.slice($event.currentTop, $event.currentTop + this.visibleUsersCount);
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Modify UI components.

src/app/list/list.component.html

<igx-scroll #scroll (onScroll)="updateList($event)" 
    [visibleItemsCount]="visibleUsersCount" 
    [itemHeight]="70" 
    [totalItemsCount]="users.length">
    <ul class="list">
        <li class="list-item" *ngFor="let user of visibleUsers" (click)="onItemSelect(user)">
            <h5 class="list-item-value">{{user.name}}</h5>
        </li>
    </ul>
</igx-scroll>
Enter fullscreen mode Exit fullscreen mode

src/app/list/list.component.css

.list {
    width: 250px;
}
Enter fullscreen mode Exit fullscreen mode

6. Save and confirm the change. You can click any item in the List to see how it is passed to main.

Capture.PNG

Avatar

The image in the list doesn't look cool, as every profile image supposed to be rounded these days. Avatar control solves it.

1. Add module as usual.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { IgxNavbarModule, IgxIconModule, IgxScrollModule, IgxAvatarModule } from 'igniteui-angular/main';
import "hammerjs"; 
import { ListComponent } from './list/list.component';

@NgModule({
  declarations: [
    AppComponent,
    ListComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    IgxNavbarModule,
    IgxIconModule,
    IgxScrollModule,
    IgxAvatarModule,  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

2. Import IgxAvatar to list.component.ts, too so that you can use it in related html.

src/app/list/list.component.ts

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { IgxScroll, IgxScrollEvent, IgxAvatar } from "igniteui-angular/main";
import { User } from '../models/user';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {
  @Input() selectedUser: User;
  @Output() selectedUserChange: EventEmitter<User> = new EventEmitter();

  constructor() {
    for (let i = 1; i <= 22; i++) {
      this.users.push(new User(
        `http://www.infragistics.com/angular-demos/assets/images/avatar/${i}.jpg`,
        "User: " + i,
        i
      ));
    }

    this.visibleUsers = this.users.slice(0, this.visibleUsersCount);
  }

  public users: User[] = new Array<User>();
  public visibleUsers: User[];
  public visibleUsersCount: number = 8;

  ngOnInit() {
  }

  private onItemSelect(user: User): void {
    this.selectedUserChange.emit(user);
  }

  private updateList($event: IgxScrollEvent): void {
    this.visibleUsers = this.users.slice($event.currentTop, $event.currentTop + this.visibleUsersCount);
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Lastly, update html and css.

src/app/list/list.component.html

<igx-scroll #scroll (onScroll)="updateList($event)" 
    [visibleItemsCount]="visibleUsersCount" 
    [itemHeight]="70" 
    [totalItemsCount]="users.length">
    <ul class="list">
        <li class="list-item" *ngFor="let user of visibleUsers" (click)="onItemSelect(user)">
            <igx-avatar class="list-item-image" roundShape="true" src="{{user.image}}"></igx-avatar>
            <h5 class="list-item-value">{{user.name}}</h5>
        </li>
    </ul>
</igx-scroll>
Enter fullscreen mode Exit fullscreen mode

src/app/list/list.component.css

.list {
    width: 250px;
}

.list-item {
    list-style: none;
    height: 64px;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;    
}

.list-item-image, .list-item-value {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: auto;
}
Enter fullscreen mode Exit fullscreen mode

4. Save and check the result.
Capture.PNG

Detail Screen

Now the application has navigation and list, let's add another component to display user detail. I also add service which feeds user information to the application as data source.

Angular 2 Routing and Detail Component.

Before implementing detail screen with Ignite UI, I restructure the application to utilize routing capability.

1. Run the command below to add detail component.

ng generate component detail
Enter fullscreen mode Exit fullscreen mode

2. Add the component to app-routing.module.ts so that Angular recognize the module as part of routing. It expects "id" as parameter for detail component.

src/app/app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DetailComponent } from './detail/detail.component'; 

const routes: Routes = [
  { path: 'detail/:id', component: DetailComponent } 
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
Enter fullscreen mode Exit fullscreen mode

3. Update app component to delete test data as well as SelectedUser as we don't need it anymore with routing feature.

src/app/app.component.ts

import { Component } from '@angular/core';
import { User } from './models/user';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'Ignite Ui App';

  onClickMenu() {
    window.alert("menu clicked");
  }

  onClickAdd() {
    window.alert("add clicked");
  }

  onClickRefresh() {
    window.alert("refresh clicked");
  }
}
Enter fullscreen mode Exit fullscreen mode

src/app/app.component.html

<!--The content below is only a placeholder and can be replaced.-->
<igx-navbar [title]="title" actionButtonIcon="menu" (onAction)="onClickMenu()">
  <igx-icon name="add" (click)="onClickAdd()"></igx-icon>
  <igx-icon name="refresh" (click)="onClickRefresh()"></igx-icon>
</igx-navbar>

<app-list></app-list> 
<router-outlet></router-outlet>
Enter fullscreen mode Exit fullscreen mode

src/app/app.component.css

app-list, router-outlet {
    float: left;
}
Enter fullscreen mode Exit fullscreen mode

4. Update detail.component.ts and html to receive the user id parameter.

src/app/detail/detail.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})
export class DetailComponent implements OnInit {

  public id: string;
  constructor( private route: ActivatedRoute ) {
  }

  ngOnInit() {
    // Monitoring the parameter change.
    this.route.params.subscribe(params => {
      this.id = params.id;
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

src/app/detail/detail.component.html

<p>
  {{id}}
</p>
Enter fullscreen mode Exit fullscreen mode

5. Next, modify list component to adopt the routing. Router is passed as constructor and you may wonder where it comes from. This is an injection feature of Angular that you can easily inject any service which registered to the application. Also delete Input/Output for SelectedUser.

src/app/list/list.component.ts

import { Component, OnInit, EventEmitter } from '@angular/core';
import { IgxScroll, IgxScrollEvent, IgxAvatar } from "igniteui-angular/main";
import { User } from '../models/user';
import { Router } from '@angular/router';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {

  constructor(private router: Router) {
    for (let i = 1; i <= 22; i++) {
      this.users.push(new User(
        `http://www.infragistics.com/angular-demos/assets/images/avatar/${i}.jpg`,
        "User: " + i,
        i
      ));
    }

    this.visibleUsers = this.users.slice(0, this.visibleUsersCount);
  }

  public users: User[] = new Array<User>();
  public visibleUsers: User[];
  public visibleUsersCount: number = 8;

  ngOnInit() {
  }

  private onItemSelect(user: User): void {
    this.router.navigate([`/detail/${user.id}`]);
  }

  private updateList($event: IgxScrollEvent): void {
    this.visibleUsers = this.users.slice($event.currentTop, $event.currentTop + this.visibleUsersCount);
  }
}
Enter fullscreen mode Exit fullscreen mode

6. Save and confirm if the application works as expected.

Capture.PNG

Serivce in Angular

Okay!, the routing part is completed. Let's move on to service.

1. Run the command below to create service. Unlike component, service files will be created under default app module. I specify --flat false so that it lives under its own folder.

ng generate service user --module=app --flat false
Enter fullscreen mode Exit fullscreen mode

2. Specify the service as provider in 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 { IgxNavbarModule, IgxIconModule, IgxScrollModule, IgxAvatarModule } from 'igniteui-angular/main';
import "hammerjs"; 
import { ListComponent } from './list/list.component';
import { DetailComponent } from './detail/detail.component';
import { UserService } from './user/user.service';

@NgModule({
  declarations: [
    AppComponent,
    ListComponent,
    DetailComponent   
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    IgxNavbarModule,
    IgxIconModule,
    IgxScrollModule, 
    IgxAvatarModule, 
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

3. Implement the service to return users. Even though this service returns user information immediately, in real world, it should be asynchronous call. Thus I use Observe and of to make it asynchronous call.

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { User } from '../models/user'
@Injectable()
export class UserService {

  private users: Array<User>;

  constructor() {
    this.users = new Array<User>();
    for (let i = 1; i <= 22; i++) {

      this.users.push(new User(
        `http://www.infragistics.com/angular-demos/assets/images/avatar/${i}.jpg`,
        "User: " + i,
        i
      ));
    }
   }

  getUsers(): Observable<User[]>{
      return of(this.users)
  }

  getUser(id: number): Observable<User>{
      return of(this.users.find(x=>x.id === +id));
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Replace the hardcoded user generation part in list.component.ts to user the service.

src/app/list/list.component.ts

import { Component, OnInit, EventEmitter } from '@angular/core';
import { IgxScroll, IgxScrollEvent, IgxAvatar } from "igniteui-angular/main";
import { User } from '../models/user';
import { UserService } from '../user/user.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {

  constructor(private userService: UserService, private router: Router) {
    // Fetch user information as async service.
    this.userService.getUsers().subscribe(
      (users) => {
        this.users = users;
        this.visibleUsers = this.users.slice(0, this.visibleUsersCount);
      }
    );
  }

  public users: User[] = new Array<User>();
  public visibleUsers: User[];
  public visibleUsersCount: number = 8;

  ngOnInit() {
  }

  private onItemSelect(user: User): void {
    this.router.navigate([`/detail/${user.id}`]);
  }

  private updateList($event: IgxScrollEvent): void {    
    this.visibleUsers = this.users.slice($event.currentTop, $event.currentTop + this.visibleUsersCount);
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Update detail.component.ts and html, too

src/app/detail/detail.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { UserService } from '../user/user.service';
import { User } from '../models/user';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})

export class DetailComponent implements OnInit {

  public user: User;
  constructor( private route: ActivatedRoute, private userService: UserService ) {
  }

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.userService.getUser(params.id).subscribe(
        (user) => {this.user = user;}
      );
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

src/app/detail/detail.component.html

<p>
  {{user.name}}
</p>
Enter fullscreen mode Exit fullscreen mode

6. Save and check if it works as expected.

Display Detail

Great work, the re-structure of the application has been done! Now let's implement the user detail component.

Input and Label

Ignite UI provides Input and Label controls which are useful for display and modify the record.

1. Add modules first. By some reason, the Input module doesn't have "module" as part of it's name. So be careful not to forget to add it. I also added FormsModule of Angular to support form.

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { IgxNavbarModule, IgxIconModule, IgxScrollModule, IgxAvatarModule,
IgxLabelModule, 
IgxLabel, IgxInput} from 'igniteui-angular/main';
import "hammerjs"; 
import { ListComponent } from './list/list.component';
import { DetailComponent } from './detail/detail.component';
import { UserService } from './user/user.service';

@NgModule({
  declarations: [
    AppComponent,
    ListComponent,
    DetailComponent   
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    IgxNavbarModule,
    IgxIconModule,
    IgxScrollModule,
    IgxAvatarModule,
    IgxLabelModule,
    IgxInput,
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

2. Update detail.component next.

src/app/detail/detail.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { IgxLabel, IgxInput, IgxAvatar } from 'igniteui-angular/main';
import { UserService } from '../user/user.service';
import { User } from '../models/user';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})

export class DetailComponent implements OnInit {

  public user: User;
  constructor( private route: ActivatedRoute, private userService: UserService ) {
  }

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.userService.getUser(params.id).subscribe(
        (user) => {this.user = user;}
      );
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

src/app/detail/detail.component.html

<div class="detail">
  <div>
      <h2 igxLabel>User ID: {{user.id}}</h2>
      <igx-avatar size="large" roundShape="true" src="{{user.image}}"></igx-avatar>
  </div>
  <div class="igx-form-group">
    <input [(ngModel)]="user.name" igxInput type="text" />
    <label igxLabel>Name</label>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

src/app/detail/detail.component.css

.detail {
    float: left;
    margin: 30px;
}
Enter fullscreen mode Exit fullscreen mode

3. Save them all to confirm the behavior.

Capture.PNG

DateTime picker

As you may know, datetime format is a tedious yet troublesome from developer point of view, as we have no idea which format each user uses. DateTime picker is handy solution and Ignite UI provides the control.

1. Add birthday for the user model.

src/app/models/user.ts

export class User {
    public image: string
    public name: string
    public id: number
    public birthdate: Date

    constructor(image: string, name: string, id: number, birthdate: Date) {
        this.image = image;
        this.name = name;
        this.id = id;
        this.birthdate = birthdate;
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Update the user service. I also added a function to save the user.

src/app/user/user.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { User } from '../models/user'
@Injectable()
export class UserService {

  private users: Array<User>;

  constructor() {
    this.users = new Array<User>();
    for (let i = 1; i <= 22; i++) {
      let birthdate = new Date(2018, 0, i);
      this.users.push(new User(
        `http://www.infragistics.com/angular-demos/assets/images/avatar/${i}.jpg`,
        "User: " + i,
        i,
        birthdate
      ));
    }
   }

  getUsers(): Observable<User[]>{
      return of(this.users)
  }

  getUser(id: number): Observable<User>{
      return of(this.users.find(x=>x.id === +id));
  }

  save(user: User): Observable<boolean> {
    let index = this.users.indexOf(user);
    if (index !== -1) {
      this.users[index] = user;
      return of(true);
    }
    else {
      return of(false);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Add module for DateTime picker. It depends on BrowserAnimation module, so I added it as well.

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { IgxNavbarModule, IgxIconModule, IgxScrollModule, IgxAvatarModule,
IgxLabelModule, IgxLabel, IgxInput, IgxDatePickerModule } from 'igniteui-angular/main';
import "hammerjs"; 
import { ListComponent } from './list/list.component';
import { DetailComponent } from './detail/detail.component';
import { UserService } from './user/user.service';

@NgModule({
  declarations: [
    AppComponent,
    ListComponent,
    DetailComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    FormsModule,
    IgxNavbarModule,
    IgxIconModule,
    IgxScrollModule,
    IgxAvatarModule,
    IgxLabelModule,
    IgxInput, 
    IgxDatePickerModule
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

4. Add DatePicker to detail.component.html. The control provides many features and I use "close", "select today", "data bind" and "select locale" features here.

src/app/detail/detail.component.html

<div class="detail">
  <div>
      <h2 igxLabel>User ID: {{user.id}}</h2>
    <igx-avatar size="large" roundShape="true" src="{{user.image}}"></igx-avatar>
  </div>
  <div class="igx-form-group">
    <input [(ngModel)]="user.name" igxInput type="text" />
    <label igxLabel>Name</label>
  </div>
  <div class="igx-form-group">
    <input style="display: none" [(ngModel)]="user.birthdate" igxInput type="text" />
    <igx-datePicker [cancelButtonLabel]="'Close'" [todayButtonLabel]="'Today'" [locale]="'ja-JP'" [(ngModel)]="user.birthdate"></igx-datePicker>
      <label igxLabel>Birthday</label>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

5. Save them all and try the DatePicker. It works beautifully.

Capture.PNG

Save the record

So far, the application simply displays information. Now add the feature to save the modification.

Buttons

Of course buttons are essential to any application and Ignite UI provides buttons control.

1. Add module first. I added Ripple in addition to Button. Ripple module provides animation effect when you click the button and its nice to have.

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { IgxNavbarModule, IgxIconModule, IgxScrollModule, IgxAvatarModule,
IgxLabelModule, IgxLabel, IgxInput, IgxDatePickerModule, IgxButtonModule, IgxRippleModule } from 'igniteui-angular/main';
import "hammerjs"; 
import { ListComponent } from './list/list.component';
import { DetailComponent } from './detail/detail.component';
import { UserService } from './user/user.service';

@NgModule({
  declarations: [
    AppComponent,
    ListComponent,
    DetailComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    FormsModule,
    IgxNavbarModule,
    IgxIconModule, 
    IgxScrollModule,
    IgxAvatarModule,
    IgxLabelModule,
    IgxInput, 
    IgxDatePickerModule, 
    IgxButtonModule, 
    IgxRippleModule,
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

2. Update detail Component to add a button.

src/app/detail/detail.component.ts

import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { IgxLabel, IgxInput, IgxAvatar } from 'igniteui-angular/main';
import { UserService } from '../user/user.service';
import { User } from '../models/user';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})

export class DetailComponent implements OnInit {

  public user: User;
  constructor( private route: ActivatedRoute, private userService: UserService ) {
  }

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.userService.getUser(params.id).subscribe(
        (user) => {this.user = user;}
      );
    });
  }

  public save(){
    this.userService.save(this.user);
  }
}
Enter fullscreen mode Exit fullscreen mode

src/app/detail/detail.component.html

<div class="detail">
  <div>
    <h2 igxLabel>User ID: {{user.id}}</h2>
    <igx-avatar size="large" roundShape="true" src="{{user.image}}"></igx-avatar>
  </div>
  <div class="igx-form-group">
    <input [(ngModel)]="user.name" igxInput type="text" />
    <label igxLabel>Name</label>
  </div>
  <div class="igx-form-group">
    <input style="display: none" [(ngModel)]="user.birthdate" igxInput type="text" />
    <igx-datePicker [cancelButtonLabel]="'Close'" [todayButtonLabel]="'Today'" [locale]="'ja-JP'" [(ngModel)]="user.birthdate"></igx-datePicker>
    <label igxLabel>Birthday</label>
  </div>
  <div>
    <span igxButton="raised" igxRipple (click)="save()">Save</span>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

3. Save them all and check the behavior. Select a user and modify the birthday, then click Save. Then select another user and come back to the original user to see if the birthday remains changed.

Capture.PNG

Toast Notification

It works. Yes it does. But from user point of view, it is a bit difficult to see if it actually did save or not. So let's add toast notification control.

1. Add module first.

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { IgxNavbarModule, IgxIconModule, IgxScrollModule, IgxAvatarModule,
IgxLabelModule, IgxLabel, IgxInput, IgxDatePickerModule, IgxButtonModule, IgxRippleModule,
IgxToastModule } from 'igniteui-angular/main';
import "hammerjs"; 
import { ListComponent } from './list/list.component';
import { DetailComponent } from './detail/detail.component';
import { UserService } from './user/user.service';

@NgModule({
  declarations: [
    AppComponent,
    ListComponent,
    DetailComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    FormsModule,
    IgxNavbarModule, 
    IgxIconModule, 
    IgxScrollModule, 
    IgxAvatarModule,
    IgxLabelModule,
    IgxInput,
    IgxDatePickerModule, 
    IgxButtonModule,
    IgxRippleModule,
    IgxToastModule,  
  ],
  providers: [UserService], 
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

2. Then update detail component. To reference the element inside HTML, you can use ViewChild feature. If you directly reference a component inside HTML, you can use (#) to specify the name.

src/app/detail/detail.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { IgxLabel, IgxInput, IgxAvatar, IgxToastModule, IgxToast } from 'igniteui-angular/main';
import { UserService } from '../user/user.service';
import { User } from '../models/user';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})

export class DetailComponent implements OnInit {

  @ViewChild('toast') toast: IgxToast;

  public user: User;
  constructor( private route: ActivatedRoute, private userService: UserService ) {
  }

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.userService.getUser(params.id).subscribe(
        (user) => {this.user = user;}
      );
    });
  }

  public save(){
    this.userService.save(this.user).subscribe(()=>{
      this.toast.show();
    });    
  }
}
Enter fullscreen mode Exit fullscreen mode

src/app/detail/detail.component.html

<div class="detail">
  <div>
    <h2 igxLabel>User ID: {{user.id}}</h2>
    <igx-avatar size="large" roundShape="true" src="{{user.image}}"></igx-avatar>
  </div>
  <div class="igx-form-group">
    <input [(ngModel)]="user.name" igxInput type="text" />
    <label igxLabel>Name</label>
  </div>
  <div class="igx-form-group">
    <input style="display: none" [(ngModel)]="user.birthdate" igxInput type="text" />
    <igx-datePicker [cancelButtonLabel]="'Close'" [todayButtonLabel]="'Today'" [locale]="'ja-JP'" [(ngModel)]="user.birthdate"></igx-datePicker>
    <label igxLabel>Birthday</label>
  </div>
  <div>
    <span igxButton="raised" igxRipple (click)="save()">Save</span>
  </div>
  <igx-toast #toast message="Updated!">
  </igx-toast>
</div>
Enter fullscreen mode Exit fullscreen mode

3. Save and confirm the behavior. You shall see the toast notification when you save the birthday.

Capture.PNG

Delete a record

Next, implement delete feature.

Dialog

Showing confirmation dialog is important whenever user does some dangerous operation. Ignite UI provides Dialog control to achieve it.

1. Add the module first

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { IgxNavbarModule, IgxIconModule, IgxScrollModule, IgxAvatarModule,
IgxLabelModule, IgxLabel, IgxInput, IgxDatePickerModule, IgxButtonModule, IgxRippleModule,
IgxToastModule, IgxDialogModule } from 'igniteui-angular/main';
import "hammerjs"; 
import { ListComponent } from './list/list.component';
import { DetailComponent } from './detail/detail.component';
import { UserService } from './user/user.service';

@NgModule({
  declarations: [
    AppComponent,
    ListComponent,
    DetailComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    FormsModule,
    IgxNavbarModule, 
    IgxIconModule, 
    IgxScrollModule,
    IgxAvatarModule, 
    IgxLabelModule, 
    IgxInput, 
    IgxDatePickerModule, 
    IgxButtonModule,
    IgxRippleModule, 
    IgxToastModule,   
    IgxDialogModule 
  ],
  providers: [UserService], 
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

2. Update detail component. When user delete a record, it shows a confirmation dialog. And if user actually deletes the record, it navigate back to home by using Router service.

src/app/detail/detail.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { IgxLabel, IgxInput, IgxAvatar, IgxToastModule, IgxToast, IgxDialogModule } from 'igniteui-angular/main';
import { UserService } from '../user/user.service';
import { User } from '../models/user';
import { Router } from '@angular/router';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})

export class DetailComponent implements OnInit {

  @ViewChild('toast') toast: IgxToast;
  public user: User;
  constructor( private route: ActivatedRoute, private router: Router,private userService: UserService ) {
  }

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.userService.getUser(params.id).subscribe(
        (user) => {this.user = user;}
      );
    });
  }

  public save(){
    this.userService.save(this.user).subscribe(()=>{
      this.toast.show();
    });    
  }

  public delete(){
    this.userService.delete(this.user).subscribe(()=>{
      this.toast.message = "deleted";
      this.toast.show();
      this.router.navigate([`/`]);
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

src/app/detail/detail.component.html

<div class="detail">
  <div>
    <h2 igxLabel>User ID: {{user.id}}</h2>
    <igx-avatar size="large" roundShape="true" src="{{user.image}}"></igx-avatar>
  </div>
  <div class="igx-form-group">
    <input [(ngModel)]="user.name" igxInput type="text" />
    <label igxLabel>Name</label>
  </div>
  <div class="igx-form-group">
    <input style="display: none" [(ngModel)]="user.birthdate" igxInput type="text" />
    <igx-datePicker [cancelButtonLabel]="'Close'" [todayButtonLabel]="'Today'" [locale]="'ja-JP'" [(ngModel)]="user.birthdate"></igx-datePicker>
    <label igxLabel>Birthday</label>
  </div>
  <div>
    <span igxButton="raised" igxRipple (click)="save()">Save</span>
    <span igxButton="raised" igxRipple (click)="dialog.open()">Delete</span>
  </div>
  <igx-toast #toast message="Updated!">
  </igx-toast>

  <igx-dialog #dialog
    title="Confirmation"
    message="Are you sure you want to delete the user?"
    leftButtonLabel="Cancel"
    (onLeftButtonSelect)="dialog.close()"
    rightButtonLabel="OK"
    (onRightButtonSelect)="delete()">
</igx-dialog>
</div>
Enter fullscreen mode Exit fullscreen mode

3. UI is done, but user service needs to support delete features. The list also needs to know when user delete a record so that it can refresh the list. To achieve it, I user Subject of rxjs.

src/app/user/user.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { User } from '../models/user'
import { Subject }    from 'rxjs/Subject';
@Injectable()
export class UserService {

  private users: Array<User>;
  // Provision a Subject
  private userUpdate = new Subject<string>()
  public userUpdateSource$ = this.userUpdate.asObservable();

  constructor() {
    this.users = new Array<User>();
    for (let i = 1; i <= 22; i++) {
      let birthdate = new Date(2018, 0, i);
      this.users.push(new User(
        `http://www.infragistics.com/angular-demos/assets/images/avatar/${i}.jpg`,
        "User: " + i,
        i,
        birthdate
      ));
    }
  }

  getUsers(): Observable<User[]> {
    return of(this.users)
  }

  getUser(id: number): Observable<User> {
    return of(this.users.find(x => x.id === +id));
  }

  save(user: User): Observable<boolean> {
    let index = this.users.indexOf(user);
    if (index !== -1) {
      this.users[index] = user;
      return of(true);
    }
    else {
      return of(false);
    }
  }

  delete(user: User): Observable<boolean> {
    let index = this.users.indexOf(user);
    if (index !== -1) {
      this.users.splice(index, 1);
      // Notify that user deleted a record to subject.
      this.userUpdate.next("updated");
      return of(true);
    }
    else {
      return of(false);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Next, update the list component to receive the notification when user deletes a record.

src/app/list/list.component.ts

import { Component, OnInit, EventEmitter } from '@angular/core';
import { IgxScroll, IgxScrollEvent, IgxAvatar } from "igniteui-angular/main";
import { User } from '../models/user';
import { UserService } from '../user/user.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {

  constructor(private userService: UserService, private router: Router) {
    this.load();
  }

  public users: User[] = new Array<User>();
  public visibleUsers: User[];
  public visibleUsersCount: number = 8;

  ngOnInit() {
    // Reload the list when user delete a record.
    this.userService.userUpdateSource$.subscribe(
      (user)=>{this.load();}
    )
  }

  public load():void{    
    this.userService.getUsers().subscribe(
      (users) => {
        this.users = users;
        this.visibleUsers = this.users.slice(0, this.visibleUsersCount);
      }
    );
  }

  private onItemSelect(user: User): void {
    this.router.navigate([`/detail/${user.id}`]);
  }

  private updateList($event: IgxScrollEvent): void {    
    this.visibleUsers = this.users.slice($event.currentTop, $event.currentTop + this.visibleUsersCount);
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Save them all and confirm if it works as expected. In the screenshot below, I deleted User:5.

Capture.PNG
Capture.PNG

Add Record

When you can delete a user, you should be able to add new one! Let's implement add feature, shall we?

Checkbox, Switch, Slider and Radio Box

Ignite UI provides various controls to support user input.

1. Add more fields to User first.

export class User {
    public image: string
    public name: string
    public id: number
    public birthdate: Date
    public gender: Gender
    public userRank: number
    public isAdmin: boolean

    constructor(image: string, name: string, id: number, birthdate: Date,
    gender: Gender, userRank: number, isAdmin: boolean ) {
        this.image = image;
        this.name = name;
        this.id = id;
        this.birthdate = birthdate;
        this.gender = gender;
        this.userRank = userRank;
        this.isAdmin = isAdmin;
    }
}

export enum Gender {
    Male = 1,
    Female,
    Other,
}
Enter fullscreen mode Exit fullscreen mode

2. Update the user service to handle new fields. Also add a function to create new user.

src/app/user/user.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { User, Gender } from '../models/user'
import { Subject } from 'rxjs/Subject';

@Injectable()
export class UserService {

  private users: Array<User>;
  private userUpdate = new Subject<string>()
  public userUpdateSource$ = this.userUpdate.asObservable();

  constructor() {
    this.users = new Array<User>();
    for (let i = 1; i <= 22; i++) {
      let birthdate = new Date(2018, 0, i);
      this.users.push(new User(
        `http://www.infragistics.com/angular-demos/assets/images/avatar/${i}.jpg`,
        "User: " + i,
        i,
        birthdate,
        Gender.Other,
        i,
        false
      ));
    }
  }

  getUsers(): Observable<User[]> {
    return of(this.users)
  }

  getUser(id: number): Observable<User> {
    return of(this.users.find(x => x.id === +id));
  }

  add(user: User): Observable<boolean> {
    this.users.push(user);
    this.userUpdate.next("updated");
    return of(true);
  }

  save(user: User): Observable<boolean> {
    let index = this.users.indexOf(user);
    if (index !== -1) {
      this.users[index] = user;
      return of(true);
    }
    else {
      return of(false);
    }
  }

  delete(user: User): Observable<boolean> {
    let index = this.users.indexOf(user);
    if (index !== -1) {
      this.users.splice(index, 1);
      this.userUpdate.next("updated");
      return of(true);
    }
    else {
      return of(false);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Run the command to add "new" component.

ng generate component new
Enter fullscreen mode Exit fullscreen mode

4. Add the module to routing.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DetailComponent } from './detail/detail.component'; 
import { NewComponent } from './new/new.component'; 

const routes: Routes = [
  { path: 'detail/:id', component: DetailComponent },
  { path: 'new', component: NewComponent } 
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
Enter fullscreen mode Exit fullscreen mode

5. Add Ignite UI modules.

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {
  IgxNavbarModule, IgxIconModule, IgxScrollModule, IgxAvatarModule,
  IgxLabelModule, IgxLabel, IgxInput, IgxDatePickerModule, IgxButtonModule, IgxRippleModule,
  IgxToastModule, IgxDialogModule, IgxCheckboxModule, IgxSwitchModule, IgxSliderModule, IgxRadioModule
 } from 'igniteui-angular/main';
import "hammerjs";
import { ListComponent } from './list/list.component';
import { DetailComponent } from './detail/detail.component';
import { UserService } from './user/user.service';
import { NewComponent } from './new/new.component';

@NgModule({
  declarations: [
    AppComponent,
    ListComponent,
    DetailComponent,
    NewComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    FormsModule,
    IgxNavbarModule,
    IgxIconModule, 
    IgxScrollModule, 
    IgxAvatarModule,
    IgxLabelModule,
    IgxInput, 
    IgxDatePickerModule,
    IgxButtonModule, 
    IgxRippleModule,
    IgxToastModule,     
    IgxDialogModule, 
    IgxCheckboxModule, 
    IgxSwitchModule,
    IgxSliderModule,
    IgxRadioModule, 
  ],
  providers: [UserService], 
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

6. Implement Logics and UI for new component. I also use CSS to modify the default color of Ignite UI controls.

src/app/new/new.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { User, Gender } from '../models/user';
import { UserService } from '../user/user.service';
import { IgxLabel, IgxInput, IgxAvatar, IgxToast, IgxDialog, IgxCheckbox, IgxSwitch, IgxSlider, IgxRadio } from 'igniteui-angular/main';
import { Router } from '@angular/router';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-new',
  templateUrl: './new.component.html',
  styleUrls: ['./new.component.css']
})
export class NewComponent implements OnInit {

  constructor(private userService: UserService, private router: Router) {   
  }

  @ViewChild('toast') toast: IgxToast;
  public user: User;
  public gender: string[];

  ngOnInit() {
    this.user = new User("", "", 0, null, Gender.Other, 0, true);
    let genderValues = Object.keys(Gender);
    this.gender = genderValues.slice(genderValues.length / 2);
  }

  public loadImage(input: HTMLInputElement): void {
    if (!input.value) {
      return;
    }

    let reader = new FileReader();
    // Callback when file read.
    reader.onload = () => {
      input.value = "";
      this.user.image = reader.result;
    }

    reader.readAsDataURL(input.files[0]);
  }

  public create() {
    this.userService.add(this.user).subscribe(() => {
      this.toast.show();
      this.router.navigate([`/`]);
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

src/app/new/new.component.html

<div class="new">
  <div>
    <input #imageInput [(ngModel)]="user.image" igxInput type="file" (change)="loadImage(imageInput)" />
    <igx-avatar size="large" roundShape="true" src="{{user.image}}"></igx-avatar>
  </div>
  <div class="igx-form-group">
      <input [(ngModel)]="user.id" igxInput type="number" />
      <label igxLabel>User ID</label>
    </div>
  <div class="igx-form-group">
    <input [(ngModel)]="user.name" igxInput type="text" />
    <label igxLabel>Name</label>
  </div>
  <div class="igx-form-group">
    <input style="display: none" [(ngModel)]="user.birthdate" igxInput type="text" />
    <igx-datePicker [cancelButtonLabel]="'Close'" [todayButtonLabel]="'Today'" [locale]="'ja-JP'" [(ngModel)]="user.birthdate"></igx-datePicker>
    <label igxLabel>Birthday</label>
  </div>
  <igx-radio *ngFor="let item of gender" value="{{item}}" name="group" [(ngModel)]="user.gender">{{item}}</igx-radio>

  <div class="igx-form-group slider">
    <igx-slider [minValue]="0" [maxValue]="50" [lowerBound]="0" [value]="0" [(ngModel)]="user.userRank"></igx-slider>
    <label igxLabel>User Rank</label>
  </div>
  <igx-switch [checked]="user.isAdmin" [(ngModel)]="user.isAdmin" >
      Is Admin
  </igx-switch>

  <div>
      <span igxButton="raised" igxRipple (click)="create()">Create</span>
    </div>
  <igx-toast #toast message="Created!">
  </igx-toast>
</div>
Enter fullscreen mode Exit fullscreen mode

src/app/new/new.component.css

.new {
    float: left;
    margin: 30px;
}

.slider {
    padding-top: 10px;
    margin-bottom: -10px
}

igx-slider >>> .igx-slider__track-fill {
    background: #e41c77;
}
Enter fullscreen mode Exit fullscreen mode

7. Update navigation bar to support new button, as well as refresh button.

src/app/app.component.ts

import { Component, ViewChild, ElementRef } from '@angular/core';
import { User } from './models/user';
import { ListComponent } from './list/list.component';
import { Router } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

  @ViewChild('applist') listComponent: ListComponent;
  selectedUser: User;

  title = 'Ignite Ui App';

  constructor(private router: Router) {
  }

  onClickMenu(){
    window.alert("menu clicked");
  }

  onClickAdd(){
    this.router.navigate(['/new']);
  }

  onClickRefresh(){
    this.listComponent.load();
  }
}
Enter fullscreen mode Exit fullscreen mode

src/app/app.component.html

<!--The content below is only a placeholder and can be replaced.-->
<igx-navbar [title]="title" actionButtonIcon="menu" (onAction)="onClickMenu()">
  <igx-icon name="add" (click)="onClickAdd()"></igx-icon>
  <igx-icon name="refresh" (click)="onClickRefresh()"></igx-icon>
</igx-navbar>

<app-list #applist></app-list> 
<router-outlet></router-outlet>
Enter fullscreen mode Exit fullscreen mode

8. Save them all and try the application.

Capture.PNG

Summary

In this article, I use Angular and Ignite UI to quickly create simple application. Ignite UI has way more capability than I introduce here. So, in the next article, I will enhance the application by using other control. Stay tuned!

References

Ignite UI for Angular
Ignite UI GitHub
Angular Tutorial

Top comments (2)

Collapse
 
hungitk46 profile image
Hung Nguyen

I can't find IgxScrollModule in the igniteui-angular version 8.2.2. Did it remove?

Collapse
 
kenakamu profile image
Kenichiro Nakamura

I don't know but it keeps changing..