2023-07-11

How to sort table data in Angular reactive forms

I am trying to sort table data using an example from StackBlitz.

I am not getting any errors in my code or console. However, the table itself is not doing any sorting at all.

HTML

<thead class="bg-info white">
    <tr>
        <th scope="col" sortable="grade.ccode" (sort)="onSort($event)">
            Code
            <i class="la la-sort float-md-end"></i>
        </th>
        <th scope="col" sortable="gradescription" (sort)="onSort($event)">
            Description
            <i class="la la-sort float-md-end"></i>
        </th>
        <th>Delete Grade</th>
    </tr>
</thead>


<tr *ngFor="let grade of paginationService.paginatedData| gradeSort:filter" (dblclick)="openUpdateModal(editGradeModal, grade)" >
    <!-- <tr *ngFor="let grade of paginationService.paginatedData| grade:filter" (dblclick)="openUpdateModal(editGradeModal, grade)" ></tr> -->
    <td>
        <a href='javascript: void(0);'><u><ngb-highlight [result]="grade.code" [term]="paginationService.searchTerm"></ngb-highlight></u></a>
    </td>
    <td>
        <ngb-highlight [result]="grade.description" [term]="paginationService.searchTerm"></ngb-highlight>
    </td>
    <td>
        <button id="btnDeleteGrade" type="button"
            class="btn btn-block btn-primary glow"
            style="width:100px" (click)="onDeleteGrade(grade)">
            Delete
        </button>
    </td>
</tr>

TypeScript

import { SortableHeaderDirective, SortEvent, compare} from 'src/app/core/directives/sortable-header.directive'

export class ListGradesComponent implements OnInit {
    @ViewChildren(SortableHeaderDirective) headers: QueryList<SortableHeaderDirective>;
    onSort({ column, direction }: SortEvent) {
        // resetting other headers
        this.headers.forEach(header => {
            if (header.sortable !== column) {
                header.direction = '';
            }
        });

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

        //this.service.sortColumn = column;
        //this.service.sortDirection = direction;
    }
}

Sortable-header-directive.ts

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

export type SortColumn = keyof Country | '';
export type SortDirection = 'asc' | 'desc' | '';

const rotate: { [key: string]: SortDirection } = {
    asc: 'desc',
    desc: '',
    '': 'asc',
};

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

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

@Directive({
    selector: 'th[sortable]',
    host: {
        '[class.asc]': 'direction === "asc"',
        '[class.desc]': 'direction === "desc"',
        '(click)': 'rotate()',
    },
})
export class SortableHeaderDirective {
    @Input() sortable: SortColumn = '';
    @Input() direction: SortDirection = '';
    @Output() sort = new EventEmitter<SortEvent>();

    rotate() {
        this.direction = rotate[this.direction];
        this.sort.emit({ column: this.sortable, direction: this.direction });
    }
}


No comments:

Post a Comment