Back

Dynamic data example

In this Generic UI example you can learn how to dynamically change the grid data source. On the grid below you can see a list of projects. Each project has some basic data information like: 'name', 'leader', 'start date', 'end date' and progress. 'New Project' form allows you to add a new entry to the projects list. To change project data inside grid simply click on any cell and type in a new value.

The source code at the bottom of this page shows how to manipulate Generic UI data source.

New Project

Source Code

Stackblitz: Link
Repository github: Link
dynamic-data-grid.html
dynamic-data-grid.ts
projects.ts
ProjectRepository
create-project.request
<div class="gw-dynamic-data-form">

  <gui-grid [cellEditing]="true"
            [columns]="columns"
            [maxHeight]="466"
            [sorting]="true"
            [source]="source"
            class="gw-dynamic-data-grid">
  </gui-grid>

  <form [formGroup]="createProjectForm">

    <h3>New Project</h3>

    <label>
      Project name:
      <input formControlName="name" gui-input>
    </label>

    <label>
      Project leader:
      <input formControlName="leader" gui-input>
    </label>

    <label>
      Start date:
      <input formControlName="startDate" gui-input type="date">
    </label>

    <label>
      End date:
      <input formControlName="endDate" gui-input type="date">
    </label>

    <label>
      Progress:
      <mat-slider [formControlName]="'progress'"
                  max="100"
                  min="0"
                  step="1"
                  thumbLabel
                  tickInterval="10"></mat-slider>
    </label>


    <button (click)="createProject()"
            [disabled]="!createProjectForm.valid"
            gui-button
            type="submit">
      Add
    </button>

  </form>

</div>
import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { GuiCellView, GuiColumn, GuiDataType } from '@generic-ui/ngx-grid';

import { Project } from './data/project';
import { CreateProjectRequest } from './data/create-project.request';
import { ProjectRepository } from './data/project.repository';


@Component({
  selector: 'gw-example-dynamic-data-grid',
  templateUrl: `./example-dynamic-data-grid.component.html`,
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ExampleDynamicDataGridComponent implements OnInit {

  columns: Array<GuiColumn> = [{
    header: 'Project Name',
    field: 'name'
  }, {
    header: 'Leader',
    field: 'leader'
  }, {
    header: 'Start Date',
    field: 'startDate',
    type: GuiDataType.DATE
  }, {
    header: 'End Date',
    field: 'endDate',
    type: GuiDataType.DATE
  }, {
    header: 'Progress',
    field: 'progress',
    type: GuiDataType.NUMBER,
    view: GuiCellView.PERCENTAGE_BAR
  }];

  source: Array<any> = [];

  createProjectForm: FormGroup;

  constructor(private projectRepository: ProjectRepository,
              private formBuilder: FormBuilder) {
    this.createProjectForm = this.formBuilder.group({
      'name': ['', [Validators.required]],
      'leader': ['', [Validators.required]],
      'startDate': ['', [Validators.required]],
      'endDate': ['', [Validators.required]],
      'progress': ['', [Validators.required, Validators.min(0), Validators.max(100)]]
    });
  }

  ngOnInit() {
    this.projectRepository
        .getAll()
        .subscribe((projects: Array<Project>) => {
          this.source = projects;
        });
  }

  createProject(): void {
    let request = new CreateProjectRequest(this.createProjectForm.value);

    this.projectRepository.addProject(request.getProject());

    this.createProjectForm.reset();
  }
}

export class Project {

	constructor(readonly id: string,
				readonly name: string,
				readonly leader: string,
				readonly startDate: Date,
				readonly endDate: Date,
				readonly progress: number) {
	}

}

export const projects = [
	new Project('#1', 'Build a House', 'Chuck Norris', new Date(2012, 0, 1), new Date(2013, 0, 1), 43),
	new Project('#2', 'Start online book store', 'Jeff', new Date(2019, 0, 1), new Date(2020, 6, 1), 90),
	new Project('#3', 'Build a space station', 'Elon', new Date(1999, 5, 12), new Date(2015, 0, 1), 39),
	new Project('#4', 'Create operation system', 'Bill', new Date(2004, 3, 12), new Date(2007, 4, 12), 24),
	new Project('#5', 'Make online music store', 'Steve', new Date(2001, 2, 12), new Date(204, 8, 12), 80),
	new Project('#6', 'Develop online radio broadcast', 'Mark', new Date(2011, 5, 12), new Date(2011, 9, 12), 58),
	new Project('#7', 'Start a vending machine business', 'Warren', new Date(2011, 5, 12), new Date(2018, 5, 12), 90),
	new Project('#8', 'Start a dojo', 'Steven', new Date(2001, 5, 12), new Date(2002, 5, 12), 82),
	new Project('#9', 'Make a transportation app', 'Adam', new Date(1987, 5, 12), new Date(1989, 1, 12), 32),
	new Project('#10', 'Start a pod-cast show', 'Joe', new Date(1982, 5, 12), new Date(1999, 3, 12), 99),
	new Project('#11', 'Build a car', 'Robert', new Date(2002, 5, 12), new Date(2003, 5, 12), 1),
	new Project('#12', 'Re-evaluate the number of stars', 'Neil', new Date(2009, 5, 12), new Date(2015, 5, 12), 100),
	new Project('#13', 'Build a wall', 'Donald', new Date(2015, 5, 12), new Date(2016, 5, 12), 40),
	new Project('#14', 'Start a shoe company', 'Al', new Date(2018, 5, 12), new Date(2020, 5, 12), 2),
	new Project('#15', 'Build a new cell phone', 'Wang Wei', new Date(2019, 5, 12), new Date(2021, 5, 12), 70),
	new Project('#16', 'Create a board game', 'Elizabeth', new Date(2005, 5, 12), new Date(2006, 5, 12), 72),
	new Project('#17', 'Build a dishwasher', 'Anna', new Date(2001, 5, 12), new Date(2010, 5, 12), 30),
	new Project('#18', 'Invent fire proof material', 'Patricia', new Date(2003, 5, 12), new Date(2004, 5, 12), 75),
	new Project('#19', 'Build a reinforced body suit', 'Stephanie', new Date(2001, 5, 12), new Date(2003, 5, 12), 92),
	new Project('#20', 'Create a battery', 'Olga', new Date(2003, 5, 12), new Date(2008, 5, 12), 50)
];
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';

import { Project } from './project';
import { projects } from './projects';
import { CreateProjectRequest } from '../create-project.request';

@Injectable()
export class ProjectRepository {

	private readonly projects = new Map<string, Project>();

	private readonly projects$ = new ReplaySubject<Array<Project>>(1);

	constructor() {
		this.initProjects();
	}

	getAll(): Observable<Array<Project>> {
		return this.projects$.asObservable();
	}

	addProject(request: CreateProjectRequest): void {

		const id = `#$ {this.createId() + 1}`,
			project = new Project(
				id,
				request.name,
				request.leader,
				request.startDate,
				request.endDate,
				request.progress);

		this.projects.set(project.id, project);
		this.emitProjects();
	}

	private initProjects(): void {
		for (let project of projects) {
			this.projects.set(project.id, project);
		}
		this.emitProjects();
	}

	private emitProjects(): void {
		const projects = Array.from(this.projects as any, (v: Project) => Object.values(v)[1]);
		this.projects$.next(projects);
	}

	private createId(): number {

		const projectIds = Array.from(this.projects as any, (v: Project) => Object.values(v)[0]);

		let idNumbers = [];

		for (let i = 0; i < projectIds.length; i++) {
			let idNumber = projectIds[i].replace(/^\D+/g, '');
			idNumbers.push(idNumber);
		}

		return Math.max.apply(Math, idNumbers);
	}
}
import { Project } from './data/project';

export class CreateProjectRequest {

	private project: Project;

	constructor(project: Project) {
		this.project = project;
	}

	setProject(project: Project): void {
		this.project = project;
	}

	getProject(): Project {
		return this.project;
	}
}