PrimeNGのDropdownにアイコンを表示して動的に変更する

2020年1月8日(水)

環境

目次

  1. nvmをバージョンアップする
    1. インストールスクリプトを実行する
  2. nodeをバージョンアップする
    1. 利用可能なnodeのバージョンを調べる
    2. LTS版の最新のnodeをバージョンを指定してインストールする
    3. 最新のnodeをバージョンを指定してインストールする
    4. インストール済みのnodeのバージョンを表示する
    5. 古いnodeのバージョンをアンインストールする
  3. Angularプロジェクトを作成する
    1. Angular CLIのコマンドでプロジェクトを作成する
    2. このプロジェクトにPrimeNGをインストールする
    3. このプロジェクトにPrimeIconsをインストールする
    4. このプロジェクトに@angular/cdkをインストールする
  4. Dropdownを表示する
    1. CSSをインポートする
    2. モジュールをインポートする
    3. HTMLを記述する
    4. コードを記述する
    5. サーバーにデプロイする
  5. Dropdownにアイコンを表示する
    1. <ng-template>を使ってアイコンを表示する
    2. サーバーにデプロイする
  6. Dropdownのアイコンを動的に変更する
    1. モジュールをインポートする
    2. *ngIfを使ってアイコンの表示/非表示を切り替える
    3. サーバーにデプロイする

ディレクトリ構成

/
+-home
|   +-mizuki
|       +-.nvm
|       |   +-versions
|       |       +-node
|       |           +-v12.14.1
|       |           +-v13.6.0
|       |
|       +-opt
|       |   +-eclipse-jee -> /home/mizuki/opt/eclipse-jee-201912
|       |   |
|       |   |-eclipse-jee-201912
|       |
|       +-workspace
|       |   +-angular
|       |   |   +-primeng-dropdown-with-icon-and-checkbox
|       |   |       +-node_modules
|       |   |       |   +-primeng
|       |   |       |   +-primeicons
|       |   |       |   +-@angular/cdk
|       |   |       |
|       |   |       |-package-lock.json
|       |   |       |
|       |   |       +-src
|       |   |           +-app
|       |   |           |   |-app.component.css
|       |   |           |   |-app.component.html
|       |   |           |   |-app.component.ts
|       |   |           |   |
|       |   |           |   |-member.ts
|       |   |           |   |
|       |   |           |   |-app.module.ts
|       |   |           |
|       |   |           |-styles.css
|       |   |
|       |   +-node_modules
|       |   |   +-@angular
|       |   |   +-@angular-devkit
|       |   |
|       |   |-package-lock.json
|       |
|       +-www
|           +-html
|               +-static
|                   |-index.html
|
+-media
|   +-sf_sharedfolder
|
+-opt
    |-apache-tomcat -> /opt/apache-tomcat-9.0.29
    |
    +-apache-tomcat-9.0.29
    |   +-bin
    |   |   |-startup.sh
    |   |   |-shutdown.sh
    |   |   |-setenv.sh
    |   |
    |   +-conf
    |       |-tomcat-users.xml
    |
    |-java -> /opt/oracle-jdk-11.0.5
    |
    +-oracle-jdk-11.0.5
        +-bin
            |-java
          

GitHub repository

Display the icon on the PrimeNG Dropdown component and change it dynamically.

1. nvmをバージョンアップする

1-1. インストールスクリプトを実行する

バージョンアップの場合もインストールスクリプトを実行すればよい。

To install or update nvm, you should run the install script.

https://github.com/nvm-sh/nvm#install--update-script

0.35.1 から 0.35.2 にバージョンアップする。

$ pwd
/home/mizuki

$ nvm --version
0.35.1

$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
        

新しい端末を起動してインストールされたバージョンを確認する。

$ pwd
/home/mizuki

$ nvm --version
0.35.2
        

参考

2. nodeをバージョンアップする

2-1. 利用可能なnodeのバージョンを調べる

$ pwd
/home/mizuki

$ nvm ls-remote
->     v12.14.0   (LTS: Erbium)
       v12.14.1   (Latest LTS: Erbium)
       v13.5.0
       v13.6.0
        

2-2. LTS版の最新のnodeをバージョンを指定してインストールする

$ pwd
/home/mizuki

$ nvm install 12.14.1
        

2-3. 最新のnodeをバージョンを指定してインストールする

$ pwd
/home/mizuki

$ nvm install 13.6.0
        

2-4. インストール済みのnodeのバージョンを表示する

$ pwd
/home/mizuki

$ nvm ls
        v12.14.0
        v12.14.1
        v13.5.0
->      v13.6.0
default -> 12.14.0 (-> v12.14.0)
node -> stable (-> v13.6.0) (default)
stable -> 13.6 (-> v13.6.0) (default)
iojs -> N/A (default)
unstable -> N/A (default)
lts/* -> lts/erbium (-> v12.14.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.18.0 (-> N/A)
lts/erbium -> v12.14.1
        

2-5. 古いnodeのバージョンをアンインストールする

$ pwd
/home/mizuki

$ nvm uninstall 13.5.0
$ nvm uninstall 12.14.0

$ nvm ls
        v12.14.1
->      v13.6.0
default -> 12.14.0 (-> N/A)
node -> stable (-> v13.6.0) (default)
stable -> 13.6 (-> v13.6.0) (default)
iojs -> N/A (default)
unstable -> N/A (default)
lts/* -> lts/erbium (-> v12.14.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.18.0 (-> N/A)
lts/erbium -> v12.14.1

"default"のエイリアスをLTS版の最新のnodeに設定して使えるようにする。
$ nvm alias default 12.14.1
default -> 12.14.1 (-> v12.14.1)
$ nvm use default
Now using node v12.14.1 (npm v6.13.4)

$ nvm ls
->      v12.14.1
        v13.6.0
default -> 12.14.1 (-> v12.14.1)
node -> stable (-> v13.6.0) (default)
stable -> 13.6 (-> v13.6.0) (default)
iojs -> N/A (default)
unstable -> N/A (default)
lts/* -> lts/erbium (-> v12.14.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.18.0 (-> N/A)
lts/erbium -> v12.14.1

$ node -v
v12.14.1
        

3. Angularプロジェクトを作成する

3-1. Angular CLIのコマンドでプロジェクトを作成する

$ pwd
/home/mizuki/workspace/angular

$ npx ng new primeng-dropdown-with-icon-and-checkbox
? Would you like to add Angular routing? (y/N) [y]
? Which stylesheet format would you like to use? (Use arrow keys) [CSS]
> CSS
  SCSS   [ https://sass-lang.com/documentation/syntax#scss                ]
  Sass   [ https://sass-lang.com/documentation/syntax#the-indented-syntax ]
  Less   [ http://lesscss.org                                             ]
  Stylus [ http://stylus-lang.com                                         ]
        

3-2. このプロジェクトにPrimeNGをインストールする

プロジェクトのディレクトリでインストールを行う。

$ pwd
/home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox

インストール可能なバージョンを調べる。
$ npm info primeng versions
[
  '8.1.0', '8.1.1', '9.0.0-rc.1', '9.0.0-rc.2'
]

バージョンを指定してインストールする。
$ npm install primeng@8.1.1

インストールされたバージョンを確認する。
$ npm ls primeng
primeng-dropdown-with-icon-and-checkbox@0.0.0 /home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox
└── primeng@8.1.1
        

参考

3-3. このプロジェクトにPrimeIconsをインストールする

プロジェクトのディレクトリでインストールを行う。

$ pwd
/home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox

インストール可能なバージョンを調べる。
$ npm info primeicons versions
[
  '1.0.0', '2.0.0'
]

バージョンを指定してインストールする。
$ npm install primeicons@2.0.0

インストールされたバージョンを確認する。
$ npm ls primeicons
primeng-dropdown-with-icon-and-checkbox@0.0.0 /home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox
└── primeicons@2.0.0
        

3-4. このプロジェクトに@angular/cdkをインストールする

PrimeNGのDropdownには@angular/cdkが必要。

プロジェクトのディレクトリでインストールを行う。

$ pwd
/home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox

インストール可能なバージョンを調べる。
$ npm info @angular/cdk versions
[
  '8.2.0', '8.2.1', '8.2.2', '8.2.3',
]

バージョンを指定してインストールする。
$ npm install @angular/cdk@8.2.3

インストールされたバージョンを確認する。
$ npm ls @angular/cdk
primeng-dropdown-with-icon-and-checkbox@0.0.0 /home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox
└── @angular/cdk@8.2.3
        

参考

4. Dropdownを表示する

4-1. CSSをインポートする

src/styles.css

@import url("../node_modules/primeicons/primeicons.css");
@import url("../node_modules/primeng/resources/themes/nova-light/theme.css");
@import url("../node_modules/primeng/resources/primeng.min.css");
        

4-2. モジュールをインポートする

3つのモジュールをインポートする。

import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DropdownModule } from 'primeng/dropdown';
        

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DropdownModule } from 'primeng/dropdown';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    BrowserAnimationsModule,
    DropdownModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
        

4-3. HTMLを記述する

src/app/app.component.html

<div>
  <span>Selected: {{selectedMemberName}}</span>
</div>
<div>
  <p-dropdown [options]="dropdownMemberList" [(ngModel)]="selectedMember" (onChange)="onDropdownChange()"></p-dropdown>
</div>
        

4-4. コードを記述する

src/app/member.ts

$ pwd
/home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox

$ npx ng generate class member
        
export class Member {
  id: number;
  name: string;
}
        

src/app/app.component.ts

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

import { SelectItem } from 'primeng/components/common/selectitem';
import { Member } from './member';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  memberNameList: string[];
  dropdownMemberList: SelectItem[];
  dropdownMemberMap: Map<number, Member>;
  selectedMember: Member;
  selectedMemberName: string;

  constructor() {
    this.memberNameList = [];
    this.dropdownMemberList = [];
    this.dropdownMemberMap = new Map();
    this.selectedMemberName = '';
  }

  ngOnInit() {
    this.memberNameList = this.getMemberNameList();

    for (let i = 0; i < this.memberNameList.length; i++) {
      let member: Member = new Member();
      member.id = i + 1;
      member.name = this.memberNameList[i];

      this.dropdownMemberList.push({label:member.name, value:member});
      this.dropdownMemberMap.set(member.id, member);
    }

    this.selectedMember = this.dropdownMemberMap.get(3);
    this.selectedMemberName = this.selectedMember.name;
  }

  onDropdownChange() {
    this.selectedMemberName = this.selectedMember.name;
  }

  getMemberNameList(): string[] {
    let memberNameList: string[] = [];

    memberNameList.push('譜久村聖');
    memberNameList.push('生田衣梨奈');
    memberNameList.push('石田亜佑美');
    memberNameList.push('佐藤優樹');
    memberNameList.push('小田さくら');
    memberNameList.push('野中美希');
    memberNameList.push('牧野真莉愛');
    memberNameList.push('羽賀朱音');
    memberNameList.push('加賀楓');
    memberNameList.push('横山玲奈');
    memberNameList.push('森戸知沙希');
    memberNameList.push('北川莉央');
    memberNameList.push('岡村ほまれ');
    memberNameList.push('山﨑愛生');

    return memberNameList;
  }
}
        

4-5. サーバーにデプロイする

リリース用のファイルを作成する。

$ pwd
/home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox

$ npx ng build --prod
        

distディレクトリ配下にプロジェクト名のディレクトリとファイルが出力される。

$ pwd
/home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox/dist/primeng-dropdown-with-icon-and-checkbox

$ ls -al
合計 2536
drwxrwxr-x. 2 mizuki mizuki   4096  1月 11 17:45 .
drwxrwxr-x. 3 mizuki mizuki     53  1月 11 17:45 ..
-rw-rw-r--. 1 mizuki mizuki  17811  1月 11 17:45 3rdpartylicenses.txt
-rw-rw-r--. 1 mizuki mizuki  10355  1月 11 17:45 color.c7a33805ffda0d32bd2a.png
-rw-rw-r--. 1 mizuki mizuki    948  1月 11 17:45 favicon.ico
-rw-rw-r--. 1 mizuki mizuki    293  1月 11 17:45 hue.0614c27197fc3ce572e1.png
-rw-rw-r--. 1 mizuki mizuki    830  1月 11 17:45 index.html
-rw-rw-r--. 1 mizuki mizuki  13112  1月 11 17:45 line.567f57385ea3dde2c9ae.gif
-rw-rw-r--. 1 mizuki mizuki   9427  1月 11 17:45 loading.8732a6660b528fadfaeb.gif
-rw-rw-r--. 1 mizuki mizuki 676858  1月 11 17:45 main-es2015.a8ee5ec790a1576dcedd.js
-rw-rw-r--. 1 mizuki mizuki 785015  1月 11 17:45 main-es5.a8ee5ec790a1576dcedd.js
-rw-rw-r--. 1 mizuki mizuki  27604  1月 11 17:45 open-sans-v15-latin-300.177cc92d2e8027712a8c.ttf
-rw-rw-r--. 1 mizuki mizuki  55181  1月 11 17:45 open-sans-v15-latin-300.27ef0b062b2e221df16f.svg
-rw-rw-r--. 1 mizuki mizuki  18280  1月 11 17:45 open-sans-v15-latin-300.521d17bc9f3526c690e8.woff
-rw-rw-r--. 1 mizuki mizuki  14564  1月 11 17:45 open-sans-v15-latin-300.60c866748ff15f5b347f.woff2
-rw-rw-r--. 1 mizuki mizuki  15545  1月 11 17:45 open-sans-v15-latin-300.76b56857ebbae3a5a689.eot
-rw-rw-r--. 1 mizuki mizuki  15667  1月 11 17:45 open-sans-v15-latin-700.148a6749baa5f658a451.eot
-rw-rw-r--. 1 mizuki mizuki  55652  1月 11 17:45 open-sans-v15-latin-700.2e00b2635b51ba336b4b.svg
-rw-rw-r--. 1 mizuki mizuki  18476  1月 11 17:45 open-sans-v15-latin-700.623e3205570002af47fc.woff
-rw-rw-r--. 1 mizuki mizuki  28192  1月 11 17:45 open-sans-v15-latin-700.7e08cc656863d52bcb5c.ttf
-rw-rw-r--. 1 mizuki mizuki  14720  1月 11 17:45 open-sans-v15-latin-700.d08c09f2f169f4a6edbc.woff2
-rw-rw-r--. 1 mizuki mizuki  56266  1月 11 17:45 open-sans-v15-latin-regular.7aab4c13671282c90669.svg
-rw-rw-r--. 1 mizuki mizuki  15050  1月 11 17:45 open-sans-v15-latin-regular.9dce7f01715340861bdb.eot
-rw-rw-r--. 1 mizuki mizuki  17704  1月 11 17:45 open-sans-v15-latin-regular.bf2d0783515b7d75c35b.woff
-rw-rw-r--. 1 mizuki mizuki  26488  1月 11 17:45 open-sans-v15-latin-regular.c045b73d86803686f4cd.ttf
-rw-rw-r--. 1 mizuki mizuki  14048  1月 11 17:45 open-sans-v15-latin-regular.cffb686d7d2f4682df83.woff2
-rw-rw-r--. 1 mizuki mizuki    118  1月 11 17:45 password-meter.d59e6dc2616c53ce8e77.png
-rw-rw-r--. 1 mizuki mizuki  37293  1月 11 17:45 polyfills-es2015.2987770fde9daa1d8a2e.js
-rw-rw-r--. 1 mizuki mizuki 126094  1月 11 17:45 polyfills-es5.6696c533341b95a3d617.js
-rw-rw-r--. 1 mizuki mizuki  39748  1月 11 17:45 primeicons.2d2afb2719a1ee903e57.eot
-rw-rw-r--. 1 mizuki mizuki  39648  1月 11 17:45 primeicons.66ee0deb739ca71f0ecd.woff
-rw-rw-r--. 1 mizuki mizuki  39572  1月 11 17:45 primeicons.df0140f8e79ecfeffaf8.ttf
-rw-rw-r--. 1 mizuki mizuki 163568  1月 11 17:45 primeicons.e5e0e94474d5fd92e7e8.svg
-rw-rw-r--. 1 mizuki mizuki   1485  1月 11 17:45 runtime-es2015.edb2fcf2778e7bf1d426.js
-rw-rw-r--. 1 mizuki mizuki   1485  1月 11 17:45 runtime-es5.edb2fcf2778e7bf1d426.js
-rw-rw-r--. 1 mizuki mizuki 167919  1月 11 17:45 styles.4845a8f53ff8c0fb6037.css
        

index.htmlのbase hrefを変更する。デフォルトではサーバールートを基準にして相対パスの解決が行われてしまう。

<base href="/">
        
<base href="/code/2020/01/dist/0801/">
        

ファイルをサーバーにアップロードする。

サンプルページを表示する

参考

5. Dropdownにアイコンを表示する

5-1. <ng-template>を使ってアイコンを表示する

アイコンのクラス名は動的に設定することができる。

src/app/app.component.html 変更箇所

<p-dropdown [options]="dropdownMemberList" [(ngModel)]="selectedMember" (onChange)="onDropdownChange()">
  <ng-template let-item pTemplate="selectedItem">
    <div class="my-dropdown-selected-item">
      <i class="{{item.value.iconClass}}"></i>
      <span>{{item.value.name}}</span>
    </div>
  </ng-template> 
  <ng-template let-item pTemplate="item"> 
    <div class="ui-helper-clearfix my-dropdown-item" style="position:relative;height:32px;">
      <i class="{{item.value.iconClass}}"></i>
      <span>{{item.value.name}}</span>
    </div>
  </ng-template>
</p-dropdown>
        

src/app/app.component.html

<div>
  <span>Selected: {{selectedMemberName}}</span>
</div>
<div>
  <p-dropdown [options]="dropdownMemberList" [(ngModel)]="selectedMember" (onChange)="onDropdownChange()">
    <ng-template let-item pTemplate="selectedItem">
      <div class="my-dropdown-selected-item">
        <i class="{{item.value.iconClass}}"></i>
        <span>{{item.value.name}}</span>
      </div>
    </ng-template> 
    <ng-template let-item pTemplate="item"> 
      <div class="ui-helper-clearfix my-dropdown-item" style="position:relative;height:32px;">
        <i class="{{item.value.iconClass}}"></i>
        <span>{{item.value.name}}</span>
      </div>
    </ng-template>
  </p-dropdown>
</div>
        

src/app/app.component.css

.my-dropdown-selected-item {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
}

.my-dropdown-item {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
}
        

src/app/member.ts

export class Member {
  id: number;
  name: string;
  iconClass: string;
}
        

src/app/app.component.ts 変更箇所

for (let i = 0; i < this.memberNameList.length; i++) {
  let member: Member = new Member();
  member.id = i + 1;
  member.name = this.memberNameList[i];
  member.iconClass = (i % 2 === 0) ? 'pi pi-key' : 'pi pi-paperclip';

  this.dropdownMemberList.push({label:member.name, value:member});
  this.dropdownMemberMap.set(member.id, member);
}
        

src/app/app.component.ts

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

import { SelectItem } from 'primeng/components/common/selectitem';
import { Member } from './member';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  memberNameList: string[];
  dropdownMemberList: SelectItem[];
  dropdownMemberMap: Map<number, Member>;
  selectedMember: Member;
  selectedMemberName: string;

  constructor() {
    this.memberNameList = [];
    this.dropdownMemberList = [];
    this.dropdownMemberMap = new Map();
    this.selectedMemberName = '';
  }

  ngOnInit() {
    this.memberNameList = this.getMemberNameList();

    for (let i = 0; i < this.memberNameList.length; i++) {
      let member: Member = new Member();
      member.id = i + 1;
      member.name = this.memberNameList[i];
      member.iconClass = (i % 2 === 0) ? 'pi pi-key' : 'pi pi-paperclip';

      this.dropdownMemberList.push({label:member.name, value:member});
      this.dropdownMemberMap.set(member.id, member);
    }

    this.selectedMember = this.dropdownMemberMap.get(3);
    this.selectedMemberName = this.selectedMember.name;
  }

  onDropdownChange() {
    this.selectedMemberName = this.selectedMember.name;
  }

  getMemberNameList(): string[] {
    let memberNameList: string[] = [];

    memberNameList.push('譜久村聖');
    memberNameList.push('生田衣梨奈');
    memberNameList.push('石田亜佑美');
    memberNameList.push('佐藤優樹');
    memberNameList.push('小田さくら');
    memberNameList.push('野中美希');
    memberNameList.push('牧野真莉愛');
    memberNameList.push('羽賀朱音');
    memberNameList.push('加賀楓');
    memberNameList.push('横山玲奈');
    memberNameList.push('森戸知沙希');
    memberNameList.push('北川莉央');
    memberNameList.push('岡村ほまれ');
    memberNameList.push('山﨑愛生');

    return memberNameList;
  }
}
        

5-2. サーバーにデプロイする

リリース用のファイルを作成する。

$ pwd
/home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox

$ npx ng build --prod
        

distディレクトリ配下にプロジェクト名のディレクトリとファイルが出力される。

index.htmlのbase hrefを変更する。デフォルトではサーバールートを基準にして相対パスの解決が行われてしまう。

<base href="/">
        
<base href="/code/2020/01/dist/0802/">
        

ファイルをサーバーにアップロードする。

サンプルページを表示する

6. Dropdownのアイコンを動的に変更する

6-1. モジュールをインポートする

Checkboxのモジュールをインポートする。

import { CheckboxModule } from 'primeng/checkbox';
        

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DropdownModule } from 'primeng/dropdown';
import { CheckboxModule } from 'primeng/checkbox';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    BrowserAnimationsModule,
    DropdownModule,
    CheckboxModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
        

6-2. *ngIfを使ってアイコンの表示/非表示を切り替える

src/app/app.component.html

<div>
  <span>Selected: {{selectedMemberName}}</span>
</div>
<div>
  <p-dropdown [options]="dropdownMemberList" [(ngModel)]="selectedMember" (onChange)="onDropdownChange()">
    <ng-template let-item pTemplate="selectedItem">
      <div class="my-dropdown-selected-item">
        <i class="{{item.value.iconClass}}"></i>
        <span>{{item.value.name}}</span>
        <i *ngIf="item.value.checked" class="pi pi-check"></i>
      </div>
    </ng-template> 
    <ng-template let-item pTemplate="item"> 
      <div class="ui-helper-clearfix my-dropdown-item" style="position:relative;height:32px;">
        <i class="{{item.value.iconClass}}"></i>
        <span>{{item.value.name}}</span>
        <i class="{{item.value.iconClassChecked}}"></i>
        <i *ngIf="item.value.checked" class="pi pi-check"></i>
      </div>
    </ng-template>
  </p-dropdown>
</div>
<div>
  <p-checkbox label="Select All" [(ngModel)]="selectAllMember" binary="true" (onChange)="onSelectAllMemberChange()"></p-checkbox>
  <ul>
    <li *ngFor="let item of dropdownMemberList">
      <p-checkbox [label]="item.value.name" [(ngModel)]="item.value.checked" binary="true"></p-checkbox>
    </li>
  </ul>
</div>
        

src/app/app.component.ts

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

import { SelectItem } from 'primeng/components/common/selectitem';
import { Member } from './member';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  memberNameList: string[];
  dropdownMemberList: SelectItem[];
  dropdownMemberMap: Map<number, Member>;
  selectedMember: Member;
  selectedMemberName: string;
  selectAllMember: boolean;

  constructor() {
    this.memberNameList = [];
    this.dropdownMemberList = [];
    this.dropdownMemberMap = new Map();
    this.selectedMemberName = '';
    this.selectAllMember = false;
  }

  ngOnInit() {
    this.memberNameList = this.getMemberNameList();

    for (let i = 0; i < this.memberNameList.length; i++) {
      let member: Member = new Member();
      member.id = i + 1;
      member.name = this.memberNameList[i];
      member.iconClass = (i % 2 === 0) ? 'pi pi-key' : 'pi pi-paperclip';
      member.checked = false;

      this.dropdownMemberList.push({label:member.name, value:member});
      this.dropdownMemberMap.set(member.id, member);
    }

    this.selectedMember = this.dropdownMemberMap.get(3);
    this.selectedMemberName = this.selectedMember.name;
  }

  onDropdownChange() {
    this.selectedMemberName = this.selectedMember.name;
  }

  onSelectAllMemberChange() {
    for (let member of this.dropdownMemberList) {
      member.value.checked = this.selectAllMember;
    }
  }

  getMemberNameList(): string[] {
    let memberNameList: string[] = [];

    memberNameList.push('譜久村聖');
    memberNameList.push('生田衣梨奈');
    memberNameList.push('石田亜佑美');
    memberNameList.push('佐藤優樹');
    memberNameList.push('小田さくら');
    memberNameList.push('野中美希');
    memberNameList.push('牧野真莉愛');
    memberNameList.push('羽賀朱音');
    memberNameList.push('加賀楓');
    memberNameList.push('横山玲奈');
    memberNameList.push('森戸知沙希');
    memberNameList.push('北川莉央');
    memberNameList.push('岡村ほまれ');
    memberNameList.push('山﨑愛生');

    return memberNameList;
  }
}
        

src/app/member.ts

export class Member {
  id: number;
  name: string;
  iconClass: string;
  checked: boolean;
}
        

6-3. サーバーにデプロイする

リリース用のファイルを作成する。

$ pwd
/home/mizuki/workspace/angular/primeng-dropdown-with-icon-and-checkbox

$ npx ng build --prod
        

distディレクトリ配下にプロジェクト名のディレクトリとファイルが出力される。

index.htmlのbase hrefを変更する。デフォルトではサーバールートを基準にして相対パスの解決が行われてしまう。

<base href="/">
        
<base href="/code/2020/01/dist/0803/">
        

ファイルをサーバーにアップロードする。

サンプルページを表示する