ファイル
実装
メタデータ
selector |
app-search |
styleUrls |
./search.component.css |
templateUrl |
./search.component.html |
メソッド
initCheckBox
|
initCheckBox()
|
|
|
ngOnDestroy
|
ngOnDestroy()
|
|
|
Async
onChangeStep
|
onChangeStep(event)
|
|
|
selectAllGenre
|
selectAllGenre(isSelected: boolean)
|
|
パラメータ :
名前 |
Type |
オプション |
isSelected |
boolean
|
いいえ
|
|
Async
showData
|
showData()
|
|
|
AREA_FORM
|
既定値 : AREA_FORM
|
|
GENRE_FORM
|
既定値 : GENRE_FORM
|
|
GENRE_MAP
|
既定値 : GENRE_MAP
|
|
stepper
|
Type : MatVerticalStepper
|
デコレータ :
@ViewChild('mystepper')
|
|
import {Component, OnDestroy, OnInit, ViewChild} from "@angular/core";
import {Router} from "@angular/router";
import {FormControl, FormGroup} from "@angular/forms";
import {MatVerticalStepper} from "@angular/material";
import {ScrollService} from "../../service/scroll.service";
import {StateService} from "../../service/state.service";
import {DataService} from "../../service/data.service";
import {AREA_FORM, AREA_MAP, GENRE_FORM, GENRE_MAP} from "../../app.config";
import {Catch} from '../../class/log.class';
@Component({
selector: "app-search",
templateUrl: "./search.component.html",
styleUrls: ["./search.component.css"]
})
export class SearchComponent implements OnInit, OnDestroy {
@ViewChild("mystepper") stepper: MatVerticalStepper;
AREA_FORM = AREA_FORM;
GENRE_FORM = GENRE_FORM;
AREA_MAP = AREA_MAP;
GENRE_MAP = GENRE_MAP;
checkBoxGroup: FormGroup;
selectedAreaName;
selectedGenreName;
areas;
listPrefetchPromise;
constructor(
public router: Router,
public scrollService: ScrollService,
public stateService: StateService,
public dataService: DataService,
) {
}
ngOnInit() {
//ジャンル選択チェックボックス初期化
this.initCheckBox();
}
initCheckBox() {
// フォームグループを生成
this.checkBoxGroup = new FormGroup({});
//ジャンルごとにフォームコントロールを生成してフォームグループに登録
Object.keys(this.GENRE_MAP).forEach(code => {
this.checkBoxGroup.addControl(code, new FormControl(false));
});
//stateの値を反映
this.stateService.state.genres.forEach(code => {
this.checkBoxGroup.patchValue({[code]: true});
});
if (this.stateService.state.areas.length
&& this.stateService.state.genres.length) {
this.stepper.selectedIndex = 1;
}
// 選択の変更検知関数を登録
this.checkBoxGroup.valueChanges.subscribe(v => this.update());
this.update();
}
//エリアの選択をstateへ反映
setArea(code: string) {
//全国を選択
if (code === "0") {
this.stateService.state.areas = Object.keys(this.AREA_MAP).slice(1);
} else {
this.stateService.state.areas = [code];
}
this.update();
}
//ジャンルの選択をstateへ反映
setGenre() {
let values = this.checkBoxGroup.value;
let selectedCode = Object.keys(values).filter(key => values[key]);
this.stateService.state.genres = selectedCode || [];
}
//表示更新
update() {
//エリア選択表示更新
if (this.stateService.state.areas.length > 1) {
this.selectedAreaName = "全国";
} else {
this.selectedAreaName = this.AREA_MAP[this.stateService.state.areas[0]];
}
//ジャンル選択表示更新
let selectName="";
let selectedCode = [];
Object.keys(this.checkBoxGroup.value).forEach(code => {
if (this.checkBoxGroup.value[code]) {
selectName += this.GENRE_MAP[code] + ", ";
selectedCode.push(code);
}
});
selectName=selectName&&selectName.trim().replace(/,$/,"");
this.selectedGenreName =selectName;
this.stateService.state.genres = selectedCode;
//検索結果件数表示更新
let keys = [];
this.stateService.state.areas.forEach(area => {
selectedCode.forEach(genre => {
keys.push(area + genre);
});
});
this.stateService.state.selectedKeys = keys;
if (keys.length > 0) {
this.dataService.countDoc(keys);
} else {
this.stateService.docCount=null;
}
}
selectAllGenre(isSelected: boolean) {
let value = this.checkBoxGroup.value;
Object.keys(value).forEach(key => {
value[key] = isSelected;
});
this.checkBoxGroup.setValue(value);
}
//検索結果データの事前ロード
// async docLoad() {
// await this.scrollService.setBuffer();
// }
//検索結果画面へ遷移
async showData() {
// this.stateService.state.listMode = LIST_MODE.SEARCH;
this.router.navigate(["/list"]);
}
//ウイザードのステップ変更時の処理
async onChangeStep(event) {
this.update();
if (event.selectedIndex === 2) {
if(!this.stateService.state.setting.prefetch.value)return;
await this.scrollService.prefetch();
}
}
ngOnDestroy() {
// this.subscription.unsubscribe();
// this.setGenre();
}
}
<mat-vertical-stepper #mystepper
(selectionChange)="onChangeStep($event)">
<!--ステップ1-->
<mat-step id="step01">
<ng-template matStepLabel>エリアの選択</ng-template>
<div
style="display:flex; flex-direction: row; flex-wrap: wrap">
<button mat-button
matStepperNext
*ngFor="let areaObj of AREA_FORM"
color="primary"
(click)="setArea(areaObj.code)"
>
{{areaObj.name}}
</button>
</div>
</mat-step>
<!--ステップ2-->
<mat-step id="step02">
<form [formGroup]="checkBoxGroup">
<ng-template matStepLabel
style="margin-bottom: 0.5em;">
ジャンルの選択
</ng-template>
<div style="background-color: beige; padding:0.3em;line-height:130%;margin:0;">
<p>[エリア] {{selectedAreaName}}</p>
<p>[ジャンル] {{selectedGenreName}}</p>
</div>
<div>
<mat-accordion>
<div *ngFor='let categoryObj of GENRE_FORM'>
<mat-expansion-panel>
<mat-expansion-panel-header>
{{categoryObj.category}}
</mat-expansion-panel-header>
<div
style="display: flex; flex-direction: row;flex-wrap: wrap;justify-content: space-between;align-items: flex-start;align-content: flex-start">
<div>
<mat-checkbox
style="padding:1em;"
*ngFor="let genreObj of categoryObj.genre"
[formControlName]="genreObj.code"
>
{{genreObj.name}}
</mat-checkbox>
</div>
</div>
</mat-expansion-panel>
</div>
</mat-accordion>
</div>
<div>
<button mat-button matStepperPrevious>
戻る
</button>
<button mat-button
(click)="selectAllGenre(false)">
選択解除
</button>
<button mat-button
(click)="selectAllGenre(true)">
すべて選択
</button>
<button mat-button
matStepperNext
>
次へ
</button>
</div>
</form>
</mat-step>
<!--ステップ3-->
<mat-step id="step03">
<ng-template matStepLabel
style="margin-bottom: 0.5em;">
該当件数
</ng-template>
<div style="border:2px solid silver">
<div style="background-color: beige; padding:0.3em;line-height:130%;margin:0;">
<p>[エリア] {{selectedAreaName}}</p>
<p>[ジャンル] {{selectedGenreName}}</p>
</div>
<div style="font-size: 2em; text-align:center;font-weight:bold; margin:1em auto;">
{{stateService.docCount}}件
</div>
</div>
<div>
<button mat-button
matStepperPrevious>
戻る
</button>
<button mat-button
[disabled]="!stateService.docCount"
(click)="showData()"
>
表示
</button>
</div>
</mat-step>
</mat-vertical-stepper>
凡例
HTML と directed を組み合わせて利用