Top

Tables


you have to install angular bootstrap


 npm i @ng-bootstrap/ng-bootstrapp
# First Name Last Name Username Role Country
1 Alexander Orton @mdorton Admin USA
2 John Deo Deo @johndeo User USA
3 Randy Orton the Bird @twitter admin UK
4 Randy Mark Ottandy @mdothe user AUS
5 Ram Jacob Thornton @twitter admin IND

<div class="table-responsive">
  <table class="table">
    <thead>
      <tr>
        <th scope="col">#</th>
        <th scope="col">First Name</th>
        <th scope="col">Last Name</th>
        <th scope="col">Username</th>
        <th scope="col">Role</th>
        <th scope="col">Country</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th scope="row">1</th>
        <td>Alexander</td>
        <td>Orton</td>
        <td>@mdorton</td>
        <td>Admin</td>
        <td>USA</td>
      </tr>
      <tr>
        <th scope="row">2</th>
        <td>John Deo</td>
        <td>Deo</td>
        <td>@johndeo</td>
        <td>User</td>
        <td>USA</td>
      </tr>
      <tr>
        <th scope="row">3</th>
        <td>Randy Orton</td>
        <td>the Bird</td>
        <td>@twitter</td>
        <td>admin</td>
        <td>UK</td>
      </tr>
      <tr>
        <th scope="row">4</th>
        <td>Randy Mark</td>
        <td>Ottandy</td>
        <td>@mdothe</td>
        <td>user</td>
        <td>AUS</td>
      </tr>
      <tr>
        <th scope="row">5</th>
        <td>Ram Jacob</td>
        <td>Thornton</td>
        <td>@twitter</td>
        <td>admin</td>
        <td>IND</td>
      </tr>
    </tbody>
  </table>
</div>

You have to change only table sizing class.you can use table-*(sm,lg,xl,xs) class

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 Larry the Bird @twitter
                  
    <table class="table table-lg">
           <thead>
              <tr>
               <th scope="col">Id</th>
               <th scope="col">Employee Name</th>
               <th scope="col">Date</th>
               <th scope="col">Status</th>
               <th scope="col">Hours</th>
               <th scope="col">Performance</th>
              </tr>
           </thead>
           <tbody>
             <ng-container *ngFor="let table of sizingData">
                <tr>
                 <th scope="row">{{table.id}}</th>
                 <td>{{table.name}}</td>
                 <td>{{table.date}}</td>
                 <td class="font-{{table.class}}">{{table.text}}</td>
                 <td>{{table.performance}}</td>
                 <td>{{table.hours}}</td>
                </tr>
              </ng-container>
            </tbody>
      </table>
To use Sizing table you have to add the following type script


import { Component } from '@angular/core';
import * as data from '../../../../shared/data/data/table/bootstrap-table';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-sizing-tables',
  imports:[CommonModule],
  templateUrl: './sizing-tables.component.html',
  styleUrls: ['./sizing-tables.component.scss']
})

export class SizingTablesComponent {

  export const sizingTable = [
  {
    id: 1,
    name: 'Mark Jecno',
    date: '22/08/2023',
    class: 'danger',
    text: 'on leave',
    hours: 0,
    performance: '29/30'
     },
    {
    id: 2,
    name: 'Elana Robbert',
    date: '21/08/2023',
    class: 'success',
    text: 'Present',
    hours: 10,
    performance: '30/30'
     },
    {
    id: 3,
    name: 'John Deo',
    date: '18/08/2023',
    class: 'danger',
    text: 'on leave',
    hours: 8,
    performance: '28/30'
     },
   ]
 
}

Name Position Office Age Start date Salary
Tiger Nixon System Architect Edinburgh 61 2011/04/25 $320,800
Garrett Winters Accountant Tokyo 63 2011/07/25 $170,750

<div class="container-fluid">
  <div class="row">
    <div class="col-sm-12">
      <div class="card">
        <div class="card-header">
          <h4>Zero Configuration</h4><span>DataTables has most features enabled by default, so all you need to do to use
            it
            with your own tables is to call the construction
            function:<code>$().DataTable();</code>.</span><span>Searching,
            ordering and paging goodness will be immediately added to the table, as shown in this example.</span>
        </div>
        <div class="card-body">
          <div class="table-responsive theme-scrollbar">
            <div class="dataTables_wrapper no-footer">
              <div id="basic-1_filter" class="dataTables_filter">
                <label>Search:<input type="search" [(ngModel)]="service.searchTerm"></label>
                @if (service.loading$ | async) {
                <span class="col col-form-label">Loading...</span>
                }
              </div>
              <table class="display dataTable no-footer" id="basic-1">
                <thead>
                  <tr>
                    <th sortable="name" (sort)="onSort($event)">Name</th>
                    <th sortable="position" (sort)="onSort($event)">position</th>
                    <th sortable="office" (sort)="onSort($event)">Office</th>
                    <th sortable="age" (sort)="onSort($event)">Age</th>
                    <th sortable="startDate" (sort)="onSort($event)">Start Date</th>
                    <th sortable="salary" (sort)="onSort($event)">Salary</th>
                    <th>Action</th>
                  </tr>
                </thead>
                <tbody>
                  @for (item of basicDataTable$ | async; track item) {
                  <tr>
                    <td>{{item.name}}</td>
                    <td>{{item.position}}</td>
                    <td>{{item.office}}</td>
                    <td>{{item.age}}</td>
                    <td>{{item.startDate}}</td>
                    <td>{{item.salary}}</td>
                    <td>
                      <ul class="action">
                        <li class="edit"><a href="javascript:void(0)"><i class="icon-pencil-alt"></i></a></li>
                        <li class="delete"><a href="javascript:void(0)"><i class="icon-trash"></i></a></li>
                      </ul>
                    </td>
                  </tr>
                  }
                  @if (basicData.length === 0) {
                  <tr>
                    <td>No matching records found</td>
                  </tr>
                  }
                </tbody>
              </table>
              <div class="d-flex justify-content-between p-2">
                <select class="form-select" style="width: auto" name="pageSize" [(ngModel)]="service.pageSize">
                  <option [ngValue]="10">10 items per page</option>
                  <option [ngValue]="25">25 items per page</option>
                  <option [ngValue]="50">50 items per page</option>
                  <option [ngValue]="100">100 items per page</option>
                </select>
                <ngb-pagination [collectionSize]="(total$ | async)!" [(page)]="service.page"
                  [pageSize]="service.pageSize"> </ngb-pagination>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
To use datatable you have to add the following type script fills

import { CommonModule, DecimalPipe } from "@angular/common";
import { Component, QueryList, ViewChildren } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { NgbPaginationModule } from "@ng-bootstrap/ng-bootstrap";
import { Observable } from "rxjs";
import { Table } from "../../../shared/data/data/table/data-table";
import {
  BasicDataTableDirective,
  SortEvent,
} from "../../../shared/directive/basic-data-table.directive";
import { BasicdatatableService } from "../../../shared/services/basicdatatable.service";

@Component({
  selector: "app-data-tables",
  imports: [FormsModule, CommonModule, NgbPaginationModule,BasicDataTableDirective],
  templateUrl: "./data-tables.component.html",
  styleUrls: ["./data-tables.component.scss"],
  providers: [BasicdatatableService, DecimalPipe],
})

export class DataTablesComponent {
  public isShow: boolean = false;
  public basicDataTable$: Observable;
  public total$: Observable;
  public basicData: Table[];
  @ViewChildren(BasicDataTableDirective)
  public headers: QueryList;

  constructor(public service: BasicdatatableService) {
    this.basicDataTable$ = service.basicDataTable$;
    this.total$ = service.total$;
  }

  ngOnInit() {
    this.service.basicDataTable$.subscribe((data) => {
      if (data) {
        this.basicData = data;
      }
    });
  }

  onSort({ column, direction }: SortEvent) {
    this.headers.forEach((header) => {
      if (header.sortable !== column) {
        header.direction = "";
      }
    });
    this.service.sortColumn = column;
    this.service.sortDirection = direction;
  }
}

you have use this services fill

import { Injectable, PipeTransform } from '@angular/core';
import { Table, basicDataTable } from '../data/data/table/data-table';
import { BehaviorSubject, Observable, Subject, debounceTime, delay, of, switchMap, tap } from 'rxjs';
import { DecimalPipe } from '@angular/common';
import { SortColumn, SortDirection } from '../directive/basic-data-table.directive';

interface SearchResult {
	products: Table[];
	total: number;
}

interface State {
	page: number;
	pageSize: number;
	searchTerm: string;
	sortColumn: SortColumn;
	sortDirection: SortDirection;
}

function sort(products: Table[], column: SortColumn, direction: string): Table[] {
	if (direction === '' || column === '') {
		return products;
	} else {
		return [...products].sort((a, b) => {
			const res = compare(a[column], b[column]);
			return direction === 'asc' ? res : -res;
		});
	}
}

const compare = (v1: string | number, v2: string | number) => (v1 < v2 ? -1 : v1 > v2 ? 1 : 0);


function matches(product: Table, term: string, pipe: PipeTransform) {
	return (
		product.name.toLowerCase().includes(term.toLowerCase()) ||
		product.office.toLowerCase().includes(term.toLowerCase()) ||
		product.position.toLowerCase().includes(term.toLowerCase()) ||
		product.salary.toLowerCase().includes(term.toLowerCase()) ||
		product.startDate.toLowerCase().includes(term.toLowerCase()) ||
		pipe.transform(product.age).includes(term) ||
		pipe.transform(product.id).includes(term)
	)

}

@Injectable({
	providedIn: 'root'
})

export class BasicdatatableService {

	private _loading$ = new BehaviorSubject(true);
	private _search$ = new Subject();
	private _orderList$ = new BehaviorSubject([]);
	private _total$ = new BehaviorSubject(0);

	private _product: State = {
		page: 1,
		pageSize: 10,
		searchTerm: '',
		sortColumn: '',
		sortDirection: '',
	};

	constructor(private pipe: DecimalPipe) {
		this._search$
			.pipe(
				tap(() => this._loading$.next(true)),
				debounceTime(200),
				switchMap(() => this._search()),
				delay(200),
				tap(() => this._loading$.next(false)),
			)
			.subscribe((result) => {
				this._orderList$.next(result.products);
				this._total$.next(result.total);
			});
		this._search$.next();
	}

	get basicDataTable$() {
		return this._orderList$.asObservable();
	}
	get total$() {
		return this._total$.asObservable();
	}
	get loading$() {
		return this._loading$.asObservable();
	}
	get page() {
		return this._product.page;
	}
	get pageSize() {
		return this._product.pageSize;
	}
	get searchTerm() {
		return this._product.searchTerm;
	}

	set page(page: number) {
		this._set({ page });
	}
	set pageSize(pageSize: number) {
		this._set({ pageSize });
	}
	set searchTerm(searchTerm: string) {
		this._set({ searchTerm });
	}
	set sortColumn(sortColumn: SortColumn) {
		this._set({ sortColumn });
	}
	set sortDirection(sortDirection: SortDirection) {
		this._set({ sortDirection });
	}

	private _set(patch: Partial) {
		Object.assign(this._product, patch);
		this._search$.next();
	}

	private _search(): Observable {
		const { sortColumn, sortDirection, pageSize, page, searchTerm } = this._product;

		// 1. sort
		let products = sort(basicDataTable, sortColumn, sortDirection);

		// 2. filter
		products = products.filter((list) => matches(list, searchTerm, this.pipe));
		const total = products.length;

		// 3. paginate
		products = products.slice((page - 1) * pageSize, (page - 1) * pageSize + pageSize);
		return of({ products, total });
	}
}

you have use this directive

import { Directive, EventEmitter, Input, Output } from '@angular/core';
import { Table } from '../data/data/table/data-table';

export type SortColumn = keyof Table | '';
export type SortDirection = 'asc' | 'desc' | '';
const rotate: {[key: string]: SortDirection} = { 'asc': 'desc', 'desc': '', '': 'asc' };

export interface SortEvent {
  column: SortColumn;
  direction: SortDirection;
}

@Directive({
  selector: 'th[sortable]',
  host: {
    '[class.asc]': 'direction === "asc"',
    '[class.desc]': 'direction === "desc"',
    '(click)': 'rotate()',
  },
})

export class BasicDataTableDirective {

  constructor() { }

  @Input() sortable: SortColumn = '';
  @Input() direction: SortDirection = '';
  @Output() sort = new EventEmitter();
  rotate() {
    this.direction = rotate[this.direction];
    this.sort.emit({ column: this.sortable, direction: this.direction });
  }
  
}