1

I want to create a dropdown (or mat-select) to use as a sorting mechanism instead of the Angular Material Sort Header. So, if I for example click on the 'username' inside the dropdown, I want the table to sort by the username (instead of clicking on the header).

enter image description here

How can I do it? Any documentation online on how to achieve this?

Thank you for any help.

As required, I attach some code:


  ngOnInit(): void {
    this.filteredOptions = this.myControl.valueChanges.pipe(
      startWith(""),
      map((value) => this._filter(value))
    );
  }

  ngAfterViewInit() {
    this.providersAdmin.sort = this.sort;
  }

  getAllAdmins() {
    this.isLoading = true;
    this.homeService.getAllAdmins().subscribe(
      (response) => {
        this.admins = response;
          this.providersAdmin = new MatTableDataSource(this.admins);
        this.isLoading = false;
      },
      (error) => {}
    );
  }

  sortTableBy(event: any) {
    const sortState: Sort = {
      active: "username",
      direction: "desc",
    };
    this.sort.active = sortState.active;
    this.sort.direction = sortState.direction;
    this.sort.sortChange.emit(sortState);

    console.log(event);
  }

The sortTableBy method is the one I found on here but nothing happens.

I added matSort on the mat-table and I added mat-sort-header on the header cell.

EDIT: Hi, I managed to fix the problem by writing the following:

sortTableBy(event: any) {
    const sortState: Sort = {
      active: "username",
      direction: "desc",
    };
    this.sort.active = sortState.active;
    this.sort.direction = sortState.direction;
    this.sort.sortChange.emit(sortState);
    this.providersAdmin.sort = this.sort;
  }
5
  • What did you try so far? Show us some code Commented Sep 8, 2021 at 19:51
  • Well, basically nothing because I don't know how to start. I did use this tutorial htmlgoodies.com/javascript/custom-sort-javascript-tables, and I managed to catch the emit to the MatSort but it didn't update my table. Actually, let me add the code in the main thread for what I have currently. Commented Sep 8, 2021 at 19:53
  • 1
    A tip - here is the source of sort function that MatSort uses github.com/angular/components/blob/master/src/material/sort/… Commented Sep 8, 2021 at 19:59
  • 1
    @SOverfow Yeah I assumed that I would have to dig inside the source to find the source of what messed the sort... Will do! Commented Sep 8, 2021 at 20:00
  • Hi, I tried to fix this for a long time until I realized that I just have to reset the new Admins after the sort inside the sortTableBy method. I will post the solution in the OP. Now it works, If anyone else has the same problem! Commented Sep 11, 2021 at 17:48

2 Answers 2

1

I am going to set up an example which you can adapt easily:

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

  sortData() {
    let isAsc = this.sort.direction != "" ? 
      event.direction == SortDirection.asc : 
      true;
    let data = this.dataSource.data.slice();
    data.sort((a, b) => {
      switch (this.myChosenSort) {
        case 'healthCareCenterName':
          return this.compare(a.healthCareCenterName, b.healthCareCenterName, isAsc);
        case 'address':
          return this.compare(a.address, b.address, isAsc);
        case 'contact':
          return this.compare(a.contact, b.contact, isAsc);
        default:
          return 0;
      }
    });
    this.dataSource = new MatTableDataSource<ServiceProviderTable>(data);
  }

To change the sort.direction you need to play around a little bit with the code, maybe directly from the dropdown and hardcoding the isAsc when calling the compare method, depending on the value of the this.myChosenSort.

Sign up to request clarification or add additional context in comments.

Comments

0

There is an example for you: Example

Your sort function has a wrong implementation, this is work for me:

  sortData(fieldName: string) {
    if (!fieldName) {
      return;
    }

    const sortState: MatSortable = {
      id: fieldName,
      start: 'desc',
      disableClear: true
    };
    this.sort.sort(sortState);
  }

3 Comments

Don't answer with just a link and no explanation: paste the important pieces of code in your answer and explain the idea.
OP is using Angular Material tables with MatSort directive. Not a "simple array".
@GaëlJ my first version was written before the author's code preview. So now I implemented right solution :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.