GASでWebアプリ｢映画鑑賞記録｣を作る⑯ ／「評価」を追加する

# 今回やること
　観た映画に対する「評価」を記録できる様にします。
![メイン画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/64004372-7019-b7c3-8344-df1196df9d49.png)
　「評価」は５段階評価で、値としては`0～5`（0：評価ナシ）で表します。
　「評価」の表示ならびに入力に使用するコントロール（部品）は、「**Element UI**」の **Rate** を使用します。

# スプレッドシートに「評価」を追加します
　「映画鑑賞記録」（スプレッドシート）の［鑑賞履歴］シートに「評価」列（H列）を追加します。
　そして、初期値として`0`をセットしておきます。
![スプレッドシートに「評価」列を追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/857e6ac7-beaf-7f9f-c18e-8ac6135ad632.png)

# プログラムの修正
### サーバ側処理の修正
　先ずは、サーバ側の処理について修正します。
#### ViewingRecord.gs
　スプレッドシートからデータを取得する処理（`getReportListBy()`）を修正します。
　データを取得する範囲を指定する箇所、6列（B～G列）を 7列（B～H列）に変更します。
```javascript
function getReportListBy(cond) {
  cond.type = 'viewingRecord';
  Logger.log(cond);

  var fileId = getFileIdFromYearSettings(cond.year);
  var sheet = SpreadsheetApp.openById(fileId).getSheetByName('鑑賞履歴');
  var lastRow = sheet.getLastRow();
  var results = [];
  if(lastRow >= 3) {
    //results = sheet.getRange(3, 2, (lastRow - 2), 6).getValues();
    results = sheet.getRange(3, 2, (lastRow - 2), 7).getValues();  // データの範囲指定を変更
  }

  return JSON.stringify(results);
}
```
　スプレッドシートへデータを更新（追加）する処理（`addData()`）を修正します。
　データをセットする範囲を1列増やして、「評価」の値をセットする様にします。
```javascript
function addData(cond) {
    ：
  const res = getViewingType(cond.theaterName, cond.year);
  //sheet.getRange(targetRow, 2, 1, 6).setValues([[cond.id, cond.viewingDate, cond.movieName, cond.firstLook, res.viewingType, res.theaterName]]);
  sheet.getRange(targetRow, 2, 1, 7).setValues([[cond.id, cond.viewingDate, cond.movieName, cond.firstLook, res.viewingType, res.theaterName, cond.rate]]);
}
```
### クライアント側処理の修正
　次に、クライアント（画面）側の処理を修正します。
#### Vuejs.html
　ダイアログボックス（データ入力画面）で使用する「評価」の変数（`cond.rate`）を追加します。
```html
<script>  
Vue.component("modal", {
  template: "#modal-template",
  props: {
    message: String,
    subject: String,
    cond: {
      id: Number,
        ：
      rate: Number,  //「評価」を追加
        ：
    },
      :
```
　続けて、メソッド（`methods:`）に次の関数（`clrRate()`）を追加します。
　この関数は、「評価」を評価ナシ（値：`0`）にする為の処理です。
```javascript
    ：
  },
  methods: {
      ：
    clrRate: function() {
      this.cond.rate = 0;
    }
```

　メイン画面で使用する「評価」の変数（`cond.rate`）も、データ（`data:`）に追加します。

```javascript
  :
var app = new Vue({
  el: '#app',
  data: {
    processingType: '記録追加',
    message: 'テスト',
      ：
    cond: {
      id: 0,
      viewingDate: '',
      movieName: '',
      theaterName: '',
      firstLook: 1,
      viewingType: 1,
      rate: 0,  //「評価」を追加
      year: ''
    },
      ：
```
　続けて、メソッド（`methods:`）の関数`doShowModal`と`doShowModalUpdate`に、`cond.rate`を設定する（初期化する）行を追加します。
　どちらも、ダイアログボックス（データ入力画面）を表示する際の準備処理です。
```javascript
    ：
  },
  methods: {
      ：
    doShowModal: function() {
      this.processingType = '記録追加';
      this.subject = '　追　加　';
      this.cond.id = 0;
      //let today = moment(new Date());
      //this.cond.viewingDate = (today.month() + 1) + '/' + today.date();
      this.cond.viewingDate = new Date();
      this.cond.movieName = '';
      this.cond.theaterName = '';
      this.cond.firstLook = 1;
      this.cond.viewingType = 1;
      this.cond.rate = 0;  //「評価」の処理を追加
      this.cond.year = this.selectedYear;
      this.showModal = true;
    },
    doShowModalUpdate: function(index) {
      this.processingType = '記録更新';
      this.subject = '　更　新　';
      this.cond.id = this.records[index][0];
      this.cond.viewingDate = this.convertDate(this.records[index][1]);
      this.cond.movieName = this.records[index][2];
      this.cond.firstLook = this.records[index][3];
      this.cond.viewingType = this.records[index][4];
      this.cond.theaterName = this.records[index][5];
      this.cond.rate = this.records[index][6];  //「評価」の処理を追加
      this.cond.year = this.selectedYear;
      this.showModal = true;
    },
```
### 画面表示の修正
　以下では、画面表示の修正を行います。
#### Index.html
　「**Element UI**」を導入する為、ライブラリをCDNで取得します。
　　**◆参考サイト** [Element（公式サイト）／ Installation](https://element.eleme.io/#/en-US/component/installation)
```html
  <!-- Element UI -->
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
```
　一覧表示に「評価」列を追加します。表示位置は「タイトル」と「初見」の間とします。
　「評価」の表示（:star: :star: :star: :star: :star:）は`<el-rate>`で行います。
　　　◆`<el-rate>`の説明
　　　　・`disabled`：このオプションを設定すると表示項目（入力不可）となります。
　　　　・`disabled-void-color`：入力不可時（前項設定時）の非選択の星印の色の設定。
　　　　　　　　　　　　　　　　　一覧表示がストライプ表示されている為、この設定を
　　　　　　　　　　　　　　　　　行わない（デフォルト色）と星印が見えなくなる場合が
　　　　　　　　　　　　　　　　　あるので、表示色を変更しています。
　　　**◆参考サイト** [Element（公式サイト）／ Rate](https://element.eleme.io/#/en-US/component/rate)
```html
    <table id="resultList" class="table-striped table-bordered table-headerfixed">
      <thead class="scrollHead">
        <tr class="alert-primary">
          <th class="head01">ID</th>
          <th class="head02">鑑賞日</th>
          <th class="head03">タイトル</th>
          <th class="head07">評価</th>  <!-- 「評価」を追加 -->
          <th class="head04">初見</th>
          <th class="head05">鑑賞種別</th>
          <th class="head06">映画館</th>
        </tr>
      </thead>
      <tbody class="scrollBody">
        <tr v-for="(record, index) in records" v-bind:key="record[0]" @click="doShowModalUpdate(index)">
          <td class="col01">{{ record[0] }}</td>
          <td class="col02">{{ record[1] | convDate }}</td>
          <td class="col03">{{ record[2] }}</td>
          <td class="col07"><el-rate v-bind:value="record[6]" disabled disabled-void-color="#E0E0E0"></el-rate></td>  <!-- 「評価」を追加 -->
          <td class="col04">{{ record[3] | convFirstLook }}</td>
          <td class="col05">{{ convViewingType(record[4]) }}</td>
          <td class="col06">{{ record[5] }}</td>
        </tr>
      </tbody>
    </table>
```
#### modalScript.html
　ダイアログボックス（入力画面）に「評価」項目を追加します。
　データは、`Vue.component("modal", {})`の`cond.rate`と連携します。
　`<el-rate>`は、評価ナシ（値：`0`）を入力できない様なので、この処理を`<el-button>`で実装しています。
```html
              <div class="form-group">
              <div class="input-group">
                <label for="my-rate" class="col-form-label">評価：</label>
                <el-rate class="form-control" id="my-rate" v-model="cond.rate" style="border: 0px;"></el-rate>
                <el-button type="text" class="form-control" @click="clrRate">クリア</el-button>
              </div>
              </div>
```
#### css.html
　スタイルシート（CSS）を設定ならびに修正します。
　一覧表示の縦スクロール・横スクロールに対応する為に次の設定を行います。
　一覧表示（`<table#resultList>`）の外側のブロック（`div.container-fluid`）に、次の設定を行います。
　　・`padding: 0px;`：内側のテーブル（`<table#resultList>`）との間に余白が無くなります。
　　・`overflow: auto;`：テーブル表示の大きさにより、自動的にスクロールバーが表示されます。
　　　【**重要**】表示されるスクロールバーは、テーブルのものではなく`div.container-fluid`の
　　　　　　　スクロールバーとなります。
　縦スクロールした時に、見出し行が固定表示される様にする為に`thead.scrollHead`に次の設定を行います。
　　・`position: sticky; top: 0; left: 0;`：該当のブロックが固定表示されます。
　　・`z-index: 1;`：この設定を行わないと、スクロールした一覧の表示が見出し行に透けて表示
　　　　　　　　　　　されます。
　　　　　　　　　　　これを防止する為に、見出し行のレイヤーを一覧表より前に表示します。
　**◆参考サイト** [マンガでわかるホームページ作成 ／【CSS/html】tableのヘッダを固定してスクロールさせる方法](https://csshtml.work/table-scroll/)
```css
<style>
  table#resultList {
    width: 1260px;
  }
  div.container-fluid {
    width: 1150px;
    height: 850px;
    padding: 0px;
    text-align: -webkit-center;
    overflow: auto;
  }
  /*スクロール用*/
  thead.scrollHead {
    display: block;
    position: sticky;
    top: 0;
    left: 0;
    z-index: 1;
  }
  tbody.scrollBody {
    display: block;
  }
```
　一覧表示に追加した「評価」列に対するスタイルを追加します。
```css
  .head07 {
    width: 130px;
    height: 50px;
    text-align: center;
  }
    ：
  .col07 {
    width: 130px;
    display: table-cell;
    text-align: center;
    vertical-align: middle;
  }
```
　以上で修正は完了です。

　なお、プログラムを修正した際のデプロイのやり方や開発時の確認の方法については、以下の投稿にまとめていますので参考にしてください。

　**◆参考サイト** [Qiita ／ GASでWebアプリを作る](https://qiita.com/pump33/items/ee76d791304a9e174989#%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%83%97%E3%83%AB%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AA%E3%82%B9%E3%83%88-1)

# 結果
　では、修正を確認してみます。
### メイン画面の表示
　［鑑賞履歴］シートの「評価」は全て`0`で初期化していますので、全ての映画が《評価ナシ》となっています。
![結果01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/025312f4-6601-8ba4-4171-6553a38ed47c.png)
### ダイアログボックス（データ入力画面）の表示
　先頭行（『ドライブ・マイ・カー』）をクリックすると、ダイアログボックス（データ入力画面）が表示されます。
　「評価」は、《評価ナシ》（未選択）となっています。
![結果02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/0ac1347a-5a7d-1a84-4f66-786ca7e7d4d6.png)
　「評価」を入力します。（当然、満点ですよネ。:sweat_smile:）
![結果03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/a75818a0-0621-5d71-14dd-1e3fd74cd68b.png)
　念の為、〔クリア〕をクリックして、「評価」が《評価ナシ》になる事を確認します。
![結果04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/f642f061-4de7-6b42-72fe-6e9f47e4e124.png)
　再度、「評価」を入力して〔更新〕ボタンをクリックします。
### 「評価」の更新結果
　一覧表示の「評価」が更新されました。
![結果05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/49f586ae-ff77-f27a-6424-66ea4feb923e.png)
　［鑑賞履歴］シート（スプレッドシート）を確認します。
　『ドライブ・マイ・カー』の「評価」に`5`がセットされています。
![結果06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/16a1ff44-713a-c439-4235-8ba9f697c15a.png)
**◆前の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る⑮](https://qiita.com/pump33/items/844d6bead8b911d898c6)
**◆次の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る⑰](https://qiita.com/pump33/items/58c237f34a14488ab34d)

**◆索引** [GASでWebアプリ｢映画鑑賞記録｣を作る《索引》](https://qiita.com/pump33/items/8ded0e6fd3c336e705f4)