[Angular] Checkbox篩選元素作法留存 (配reactive form)




目標資料

  questionLists: Question[] = [
    { qid: 10, businessQType: ['TSTK'], checked: false },
    {
      qid: 20,
      businessQType: ['TSTK', 'FUTB', 'SUBB', 'FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    { qid: 30, businessQType: ['TSTK'], checked: false },
    {
      qid: 40,
      businessQType: ['TSTK', 'FUTB', 'SUBB', 'FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 50,
      businessQType: ['FUTB', 'SUBB', 'FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 60,
      businessQType: ['FUTB', 'SUBB', 'FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 70,
      businessQType: ['FUTB'],
      checked: false,
    },
    {
      qid: 80,
      businessQType: ['FUTB'],
      checked: false,
    },
    {
      qid: 90,
      businessQType: ['TSTK', 'FUTB', 'SUBB', 'FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 100,
      businessQType: ['TSTK', 'FUTB'],
      checked: false,
    },
    {
      qid: 110,
      businessQType: ['TSTK', 'FUTB'],
      checked: false,
    },
    {
      qid: 120,
      businessQType: ['TSTK'],
      checked: false,
    },
    {
      qid: 130,
      businessQType: ['TSTK', 'FUTB', 'SUBB', 'FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 140,
      businessQType: ['SUBB', 'FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 150,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 160,
      businessQType: ['SUBB', 'FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 170,
      businessQType: ['TSTK'],
      checked: false,
    },
    {
      qid: 180,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 190,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 200,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 210,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 220,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 230,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 240,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 250,
      businessQType: ['FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 260,
      businessQType: ['FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 270,
      businessQType: ['FNCM', 'STUN'],
      checked: false,
    },
    {
      qid: 280,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 290,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 300,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 310,
      businessQType: ['FNCM'],
      checked: false,
    },
    {
      qid: 320,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 330,
      businessQType: ['FNCM'],
      checked: false,
    },
    {
      qid: 340,
      businessQType: ['FNCM'],
      checked: false,
    },
    {
      qid: 350,
      businessQType: ['FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 360,
      businessQType: ['FNCM'],
      checked: false,
    },
    {
      qid: 370,
      businessQType: ['OSUB'],
      checked: false,
    },
  ];


interface Question {
  qid: number;
  businessQType: business[];
  checked: boolean;
}





勾選選項HTML檔


<!-- 看json格式 -->
{{ kycSelectForm.value | json }}
<div class="">
  <form [formGroup]="kycSelectForm">
    <section class="">
      <mat-checkbox
        class=""
        value="TSTK"
        formControlName="TSTK"
        (change)="onTypeChange()"
        (click)="filterTheme('TSTK')"
        >台股</mat-checkbox
      >
      <mat-checkbox
        class=""
        value="FUTB"
        formControlName="FUTB"
        (change)="onTypeChange()"
        (click)="filterTheme('FUTB')"
        >期貨</mat-checkbox
      >
      <mat-checkbox
        class=""
        value="SUBB"
        formControlName="SUBB"
        (change)="onTypeChange()"
        (click)="filterTheme('SUBB')"
        >複委託</mat-checkbox
      >
      <mat-checkbox
        class=""
        value="FNCM"
        formControlName="FNCM"
        (change)="onTypeChange()"
        (click)="filterTheme('FNCM')"
        >財管</mat-checkbox
      >
      <mat-checkbox
        class=""
        value="OSUB"
        formControlName="OSUB"
        (change)="onTypeChange()"
        (click)="filterTheme('OSUB')"
        >OSU</mat-checkbox
      >
      <mat-checkbox
        class=""
        value="STUN"
        formControlName="STUN"
        (change)="onTypeChange($event)"
        (click)="filterTheme('STUN')"
        >結構型</mat-checkbox
      >
    </section>
  </form>
</div>



勾選選項的TS


export class KycSelectSubjectComponent implements OnInit {
  kycSelectForm: FormGroup;
  questionLists = this.kycQuestionService.questionLists;

  constructor(private kycQuestionService: KycQuestionService) {
    this.kycSelectForm = this.kycQuestionService.kycQuestionServiceFormGroup;
  }

  ngOnInit() {
    this.onTypeChange();
  }

  filterTheme(id) {
    this.kycQuestionService.filterTheme(id);
  }

  onTypeChange() {
    // console.log(this.kycSelectForm.value);

    const myFormArray = this.kycSelectForm.value as FormArray;
    const kycChooseNameFormArray = [];

    if (this.kycSelectForm.get('TSTK').value === true{
      kycChooseNameFormArray.push('TSTK');
    }
    if (this.kycSelectForm.get('FUTB').value === true{
      kycChooseNameFormArray.push('FUTB');
    }
    if (this.kycSelectForm.get('SUBB').value === true{
      kycChooseNameFormArray.push('SUBB');
    }
    if (this.kycSelectForm.get('FNCM').value === true{
      kycChooseNameFormArray.push('FNCM');
    }
    if (this.kycSelectForm.get('OSUB').value === true{
      kycChooseNameFormArray.push('OSUB');
    }
    if (this.kycSelectForm.get('STUN').value === true{
      kycChooseNameFormArray.push('STUN');
    }
    // console.log('myNameFormArray', kycChooseNameFormArray);

    this.kycQuestionService.kycChooseNameFormArray = kycChooseNameFormArray;

    this.kycQuestionService.filterTheme(kycChooseNameFormArray)

  }
}







Service


export class KycQuestionService {
  constructor(private fb: FormBuilder) {
    this.createKycForm();
    this.packageList();
  }

  // 按照KYC模板對題目編碼
  questionLists: Question[] = [
    { qid: 10, businessQType: ['TSTK'], checked: false },
    {
      qid: 20,
      businessQType: ['TSTK', 'FUTB', 'SUBB', 'FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    { qid: 30, businessQType: ['TSTK'], checked: false },
    {
      qid: 40,
      businessQType: ['TSTK', 'FUTB', 'SUBB', 'FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 50,
      businessQType: ['FUTB', 'SUBB', 'FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 60,
      businessQType: ['FUTB', 'SUBB', 'FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 70,
      businessQType: ['FUTB'],
      checked: false,
    },
    {
      qid: 80,
      businessQType: ['FUTB'],
      checked: false,
    },
    {
      qid: 90,
      businessQType: ['TSTK', 'FUTB', 'SUBB', 'FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 100,
      businessQType: ['TSTK', 'FUTB'],
      checked: false,
    },
    {
      qid: 110,
      businessQType: ['TSTK', 'FUTB'],
      checked: false,
    },
    {
      qid: 120,
      businessQType: ['TSTK'],
      checked: false,
    },
    {
      qid: 130,
      businessQType: ['TSTK', 'FUTB', 'SUBB', 'FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 140,
      businessQType: ['SUBB', 'FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 150,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 160,
      businessQType: ['SUBB', 'FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 170,
      businessQType: ['TSTK'],
      checked: false,
    },
    {
      qid: 180,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 190,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 200,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 210,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 220,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 230,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 240,
      businessQType: ['STUN'],
      checked: false,
    },
    {
      qid: 250,
      businessQType: ['FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 260,
      businessQType: ['FNCM', 'OSUB', 'STUN'],
      checked: false,
    },
    {
      qid: 270,
      businessQType: ['FNCM', 'STUN'],
      checked: false,
    },
    {
      qid: 280,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 290,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 300,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 310,
      businessQType: ['FNCM'],
      checked: false,
    },
    {
      qid: 320,
      businessQType: ['OSUB'],
      checked: false,
    },
    {
      qid: 330,
      businessQType: ['FNCM'],
      checked: false,
    },
    {
      qid: 340,
      businessQType: ['FNCM'],
      checked: false,
    },
    {
      qid: 350,
      businessQType: ['FNCM', 'OSUB'],
      checked: false,
    },
    {
      qid: 360,
      businessQType: ['FNCM'],
      checked: false,
    },
    {
      qid: 370,
      businessQType: ['OSUB'],
      checked: false,
    },
  ];


  package: any;
  filterData = [];


  // 用來裝select選的陣列內容(格式為['TSTK','FUTB'])

  public kycChooseNameFormArray = [{}];

  // 將資料引出來存在一個地方
  packageList() {
    for (const i of this.questionLists{
      this.filterData.push(i);
      this.package = this.filterData;
    }
    console.log('111', this.package);
  }


  businessQType: any = [];

  // 將formgroup選到什麼選項變成陣列
  filterTheme(id) {
    console.log('222',id);
    if (this.businessQType.some(a => a === id)) {
      this.businessQType = this.businessQType.filter(a => a !== id);
    } else {
      this.businessQType.push(id);
    }
    this.ApplyFilters();
  }

  // 篩選(return第一個用some為只要包含就出現;用every為必須完全符合)
  ApplyFilters() {
    this.package = this.filterData.filter(item => {
      return (
        item.businessQType.some(c => this.businessQType.some(d => d === c)) ||
        this.businessQType.length === 0
      );
    });

    console.log('33', this.package);
  }



  public kycQuestionServiceFormGroup: FormGroup;

  // 設定formGroup存選擇內容
  createKycForm() {
    this.kycQuestionServiceFormGroup = this.fb.group({
      TSTK: false,
      FUTB: false,
      SUBB: false,
      FNCM: false,
      OSUB: false,
      STUN: false,
    });
  }

}







inclusive和exclusive用法差別

inclusive用some

  // 篩選(return第一個用some為只要包含就出現;用every為必須完全符合)
  ApplyFilters() {
    this.package = this.filterData.filter(item => {
      return (
        item.businessQType.some(c => this.businessQType.some(d => d === c)) ||
        this.businessQType.length === 0
      );
    });

    console.log('33', this.package);
  }



exclusive用every

  // 篩選(return第一個用some為只要包含就出現;用every為必須完全符合)
  ApplyFilters() {
    this.package = this.filterData.filter(item => {
      return (
        item.businessQType.every(c => this.businessQType.some(d => d === c)) ||
        this.businessQType.length === 0
      );
    });

    console.log('33', this.package);
  }










參考引用

範例
https://stackoverflow.com/questions/53777133/angular-typescript-multi-filter-with-check-boxes
https://stackblitz.com/edit/angular-njtabf
https://stackblitz.com/edit/multiple-filters-kfykcy?file=app%2Fapp.component.ts

https://stackoverflow.com/questions/53994077/how-to-filter-results-for-range-slider-with-multiple-checkbox-together-in-angula
https://stackblitz.com/edit/angular-njtabf?file=src%2Fapp%2Ffilter.component.html


取值
https://stackoverflow.com/questions/40927167/angular-reactiveforms-producing-an-array-of-checkbox-values

inclusive和exclusive
https://stackoverflow.com/questions/54079219/how-do-i-make-my-checkbox-filter-inclusive-rather-than-exclusive


連動格式
https://stackoverflow.com/questions/49518939/angular-5-reactive-forms-pass-checkbox-ids-for-formarray

https://stackblitz.com/edit/angular-hilz9h


其他相關

https://stackoverflow.com/questions/34997128/angular-2-get-values-of-multiple-checked-checkboxes


https://stackoverflow.com/questions/54136477/reactive-forms-on-valuechanges-subscribe-update-checkbox-options
https://stackblitz.com/edit/on-select-change-update-checkboxes-6raxnq



https://blog.grossman.io/real-world-angular-reactive-forms/


https://stackoverflow.com/questions/49518939/angular-5-reactive-forms-pass-checkbox-ids-for-formarray

https://stackblitz.com/edit/angular-hilz9h


留言

這個網誌中的熱門文章

[Angular] 閒置登出作法

[Angular Materail] 檔案上傳範例

[Angular Material] 搜尋式下拉選單範例