0
votes

I am trying to build a web-page using angular. I need to connect only data's of 2nd ngFor loop that are correlated to 1st ngFor loop.

HTML CODE

<div *ngFor="let year of years">
    <h2> {{year}} </h2>   // For displaying the year row
    </div>


<div *ngFor="let month of months">
    <h4> {{month}}</h4> // For displaying the month row
    </div>


//Now i need to print all the data respect to each month and data.

year = ['2019','2018','2017','2016']

month = ['jan','feb','mar','apr','may','jun','jul', 'aug','sep','oct','nov','dec']

Output should be like 

2019 2018 2017 2016

jan feb mar apr may jun jul aug sep oct nov dec

(all data respect to each month and year should be present as shown)

2019

8th aug - data

5th aug - data

28th june - data

5 jan - data

2018

29th dec - data

21 dec - data

18 oct - data

(and so on...)

and if we click on any of the year, the page will scroll to that year. there may be all 12 months data for that year or may be only some months. so suppose if we click 2018 , then page will scroll to 2018 and then "if" i click on "oct" if there is a data for 2018 oct then it will scroll there else nothing will happen. it cant scroll to oct of any other year.


The structure of data is like 

year -- date -- data
2019 -- 8th aug -- data
2019 -- 5th aug -- data

3
please provide the code, which you have tried so far.. for better understanding of your requirement... ?Ganesh
i am new in angular, so dont know, how to do it. I tried reading data binding, but was unable to know how to use it in this case.Achal Utkarsh

3 Answers

0
votes

you can write second loop like below.

#1

<ng-container *ngFor="let names of name">
   <div *ngIf="names.startsWith(selectedAlphabets)">
     <h4> {{names}}</h4>
   </div>
</ng-container>

though this is not good approach as everytime you change selectedAlphabets and according to that it will have to iterate whole name list again. if you can change you names list to map of alphabet character to list of name then it will be more faster because it can directly pick list of selected alphabet as below.

#2

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

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

      alphaBet: string;
      english = ['a', 'b', 'c', 'd', 'e', 'f'];

      name = ['a1', 'a2', 'a3', 'a4',
        'b1', 'b2', 'b3', 'b4',
        'c1', 'c2', 'c3', 'c4',
        'd1', 'd2', 'd3', 'd4',
        'e1', 'e2', 'e3', 'e4',
        'f1', 'f2', 'f3', 'f4'
      ];

      nameMap = new Map<string, string[]>();

      public ngOnInit(){
          this.generateNameMap();
      }

      generateNameMap() {
        for (const item of this.name) {
            if (!this.nameMap.get(item.charAt(0))) {
                this.nameMap.set(item.charAt(0), []);
            }

            this.nameMap.get(item.charAt(0)).push(item);
        }
      }


      /* other code */
    }

and change second for loop html part like this

<div *ngFor="let names of nameMap.get(selectedAlphabets)">
  <h4> {{names}}</h4>
</div>
0
votes
<div *ngFor="let alphabets of english">
    <h2 (click)=scrollToLetter(alphabets)> {{alphabets}} </h2>
    </div>


<div *ngFor="let names of name">
    <h4 id="{{names}}">{{names}}</h4>
    </div>

And then in your TypeScript:

public scrollToLetter(letter) {
  console.log(`scrolling to ${letter}`);
  var id = this.name.find(function(element) {
      return element.toLowerCase().startsWith(letter);
  });
  if (id) {
      let el = document.getElementById(id);
      el.scrollIntoView();
  }
}

Remember to apply appropriate styling to the scrollable list, eg:

  height: 50px;
  max-height:50px;
  overflow-y: scroll;
0
votes

Here is one approach based on what you have provided in your description. You just need to filter the second list based on the first one's selected item. Stackblitz Demo

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

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

  alphaBet: string;
  english = ['a', 'b', 'c', 'd', 'e', 'f'];

  name = ['a1', 'a2', 'a3', 'a4',
    'b1', 'b2', 'b3', 'b4',
    'c1', 'c2', 'c3', 'c4',
    'd1', 'd2', 'd3', 'd4',
    'e1', 'e2', 'e3', 'e4',
    'f1', 'f2', 'f3', 'f4'
  ];

  scrollToNames(val) {
    const elems = [].slice.call(document.getElementsByClassName('names'));
    const macthes = elems.filter((item) => {
      return item.innerHTML.includes(val);
    });
    macthes[0].scrollIntoView();
  }
}
<div *ngFor="let alphabets of english">
  <h2 (click)="scrollToNames(alphabets)"> {{alphabets}} </h2>
</div>


<div *ngFor="let names of name">
  <h4 class="names"> {{names}}</h4>
</div>

Also you can use pipes to filter the second list based on the selection. This is just one way demonstrated above;

Hope this helps :)