GASでWebアプリ｢映画鑑賞記録｣を作る⑬ ／ Googleカレンダーからデータを登録する（後編）

# 今回やること
　今まで、映画鑑賞記録を画面から入力していましたが、Googleカレンダーに映画館に行くスケジュールを事前登録している事に気が付きまして、このデータを使って画面からの入力を省きたいと思いました。

- 前回作成したプログラム（`addMovies()`）を、画面から呼び出します。    
（詳細は[前回⑫](https://qiita.com/pump33/items/240ce06996403361dda3)を参照ください）
- 「鑑賞日」入力用のダイアログボックスを追加します。

# プログラムの修正

#### calendarScript.html

　今回、HTMLファイル（**calendarScript.html**）を追加します。
　このファイルが、ダイアログボックスの本体になります。

```javascript
<script type="text/x-template" id="calendar-template">
  <transition name="modal">
    <div class="modal-mask">
      <div class="modal-wrapper">
        <div class="modal-container">

          <div class="modal-header">
            <slot name="header">
              default header
            </slot>
          </div>

          <div class="modal-body">
            <slot name="body">
              {{ message }}
            </slot>
            <form>
              <div class="form-group">
              <div class="input-group">
                <label for="viewing-date" class="col-form-label">鑑賞日：</label>
                <vuejs-datepicker input-class="form-control" id="viewing-date" v-model="cond.viewingDate" :format="datepicker.format"></vuejs-datepicker>
              </div>
              </div>
            </form>
          </div>

          <div class="modal-footer">
            <slot name="footer">
              default footer
              <button type="button" class="modal-default-button btn btn-primary" @click="addMovies">カレンダーから登録</button>
              <button type="button" class="modal-default-button btn btn-secondary" @click="$emit('close-calendar')">閉じる</button>
            </slot>
          </div>
        </div>
      </div>
    </div>
  </transition>
</script>
```

#### Vuejs.html

　今回追加するダイアログボックのコンポーネントを追加します。

```javascript
Vue.component("calendar", {
  template: "#calendar-template",
  props: {
    message: String,
    subject: String,
    cond: {
      viewingDate: String,
      year: String
    },
    datepicker: {
      format: String
    }
  },
  methods: {
    addMovies: function() {
      const day = this.cond.viewingDate.getFullYear() + '-' + ('00' + (this.cond.viewingDate.getMonth() + 1)).substr(-2) + '-' + ('00' + this.cond.viewingDate.getDate()).substr(-2);
      this.cond.viewingDate = day;
      this.$emit('add-movies', this.cond);
    }
  },
  components: {
    'vuejs-datepicker': vuejsDatepicker
  }
});
```
　`methods:`に次の関数（3つ）を追加します。

```javascript
<script>  
  ：
var app = new Vue({
  el: '#app',
    ：
  },
  methods: {
      ：
    },
    doHideCalendar: function() {
      this.showCalendar = false;
      this.message = '';
    },
    doShowCalendar: function() {
      this.subject = 'カレンダー登録';
      this.cond.viewingDate = new Date();
      this.cond.year = this.selectedYear;
      this.showCalendar = true;
    },
    doAddMovies: function(cond) {
      addMovies(cond);
    },
  }
});
</script>  
```
#### javascript.html
　`addMovies()`を追加します。この処理は、クライアント側からサーバ側の処理を呼び出しています。

```javascript
<script>
    ：
  function addMovies(cond) {
    google.script.run.withSuccessHandler(
      function(v, element) {
        app.message = v;
        let cond = {};
        cond.year = app.selectedYear;
        searchResults(cond);
      })
      .withFailureHandler(
        function(msg, element) {
          showError(msg);
        })
      .withUserObject(this)
      .doAddMovies(cond);
  }
    ：
</script>
```

#### Calendar.gs

　`doAddMovies()`を追加します。この処理で前回作成した`addMovies()`を呼び出しています。（詳細は[前回⑫](https://qiita.com/pump33/items/240ce06996403361dda3)を参照ください）

```javascript
function doAddMovies(cond) {
  const calId = 'xxxxx.xxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx@group.calendar.google.com'
  const day = new Date(cond.viewingDate.substr(0, 4), (cond.viewingDate.substr(5, 2) - 1), cond.viewingDate.substr(8, 2));
  const res = addMovies(day, calId, cond.year);

  let message = '';
  if(res > 0) {
    message = Utilities.formatDate(day, 'JST', 'MM/dd(E) ') + 'の、' + res + '件の鑑賞記録を追加しました。';
  }
  else {
    message = Utilities.formatDate(day, 'JST', 'MM/dd(E) ') + 'に、鑑賞予定はありませんでした。';
  }

  return message;
}
```
#### Index.html

　今回追加した **calendarScript.html** を読み込む記述を追加します。

```html
<!DOCTYPE html>
<html>
    ：
  <?!= HtmlService.createHtmlOutputFromFile('calendarScript').getContent(); ?>
```

　メイン画面に、今回追加したダイアログボックスを表示するボタンを追加します。（`<button id="show-calendar">`タグ部分）
　そして、今回追加したダイアログボックスの連携部を追加します。（`<calendar>`タグ部分）

```html
    <div style="text-align: center;">
        ：
      <button type="button" class="btn btn-primary" id="show-modal" @click="doShowModal">記録追加</button>&nbsp;&nbsp;&nbsp;&nbsp;
      <button type="button" class="btn btn-primary" id="show-calendar" @click="doShowCalendar">カレンダー登録</button>
    </div>
      ：
    <calendar v-if="showCalendar" v-on:close-calendar="doHideCalendar" v-on:add-movies="doAddMovies" v-bind:message="message" v-bind:subject="subject" v-bind:cond="cond" v-bind:datepicker="datepicker">
      <h3 slot="header">custom header {{ subject }}</h3>
    </calendar>
    </div>
      ：
  </body>
</html>
```

# 結果
　画面を表示すると、〔カレンダー登録〕ボタンの表示が追加されています。
![〔カレンダー登録〕ボタンの追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/d64c8db8-120b-e8df-1f9a-6b1ba05ea4b0.png)

　〔カレンダー登録〕ボタンをクリックすると、ダイアログボックスが表示されます。
![ダイアログボックスの表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/df597056-8e12-6b9c-10ad-8eafd174078e.png)

　「鑑賞日」を指定して、〔カレンダーから登録〕ボタンをクリックすると、カレンダーに入力している鑑賞予定から鑑賞記録が追加されます。
![追加処理後の表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/ec3d7d75-a8fc-e5f3-e25b-27c09ccf2ac4.png)

　鑑賞予定が無かった場合は、鑑賞記録は追加されずに画面の様に表示されます。
![鑑賞予定が無い場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/9a8c2452-cfd9-8d79-4b28-43935bf47938.png)

**◆前の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る⑫](https://qiita.com/pump33/items/240ce06996403361dda3)
**◆次の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る⑭](https://qiita.com/pump33/items/e90659484900a641bd8e)

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