フットペダルとkintoneでアンケート作成

## はじめに
今回は、kintoneを使用してアンケートを作成しました。
キー操作・フットペダルの操作だけで、アンケートに回答できると便利ですよね。
ということで、**マウス操作なし**で「kitnoneにデータを登録したい！」という方必見です！

さらに今回はJavaScriptのカスタマイズ部分をVue.jsを利用して書いています。
Vue.jsを少し書いてみたい方もおすすめの記事になっています。

## 構成
![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168550/1da3bab1-a086-acad-1f5c-02b8ca65bfc8.png)



## 準備するもの
- kintone
- フットペダル・フットスイッチ または キーボード

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168550/c5f423ab-2b7f-d9fd-bc83-85ef03e79f74.png" width="40%">


## 手順
1. kintoneにアンケートアプリを作成
1. kintoneにカスタマイズビューを作成
    1. HTMLファイルを作成
1. Vue.jsを使ったカスタマイズスクリプトを作成
    1. CDN読み込み
    1. カスタムJavaScriptスクリプトを適用
    1. カスタムCSSスクリプトを適用
1. フットペダルをPC or モニターに接続
1. 完成


## 1. kintoneにアンケートアプリを作成
まずは、kintoneにアンケートアプリを作成します。


| フィールド | フィールド名 | フィールドコード | 値 |
|:-:|:-:|:-:|:-:|
| ラジオボタン| 餃子は |question1 | 好き・普通・苦手 |
| ラジオボタン| 餃子といえば |question2 |焼き餃子・水餃子・揚げ餃子 |
| ラジオボタン| どのくらいの頻度で餃子を食べますか |question3 |毎日・週に1回以上・月に1回以上|
| 作成日時| 作成日時 | 作成日時 | ※自動入力 |

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168550/3c3be05b-d0f5-917d-1682-2b62767283c5.png" width="50%">

設定できたら一旦フォームを保存してください。


## 2.kintoneにカスタマイズビューを作成

### HTMLファイルを作成
`kintoneアプリの設定　> 一覧 > ＋ボタン`

| 一覧名 | レコード一覧表示形式 |
|:-:|:-:|
| アンケート表示 | カスタマイズ |

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168550/82038487-2829-52f3-a366-644cb8ef68da.png" width="50%">

:::note warn
一覧のID
こちらは、後程利用します！コピーしておいて下さい。
:::

```html:custom_view.html
<div id="app" class="container">
    <div class="title">
      <h1 class="nes-text">足元のペダルを踏んでアンケートに回答してね！</h1>
    </div>
    <button v-if="startFlg!=true" type="button" class="nes-btn is-primary startButton mb-20" @click="AnswerStart">アンケートに回答する</button>
    <div v-if="startFlg==true && currentQuestionCounts != TotalQuestionCounts " class="quesion mb-20">
      <p>{{ currentQuestion }}</p>
      <label><input type="radio" class="nes-radio" v-on:keydown.a="onKeyDown" v-model="keyValue">左：{{ currentquestionKeyValueA }}</label>
      <label><input type="radio" class="nes-radio" v-on:keydown.b="onKeyDown" v-model="keyValue">中央：{{ currentquestionKeyValueB }}</label>
      <label><input type="radio" class="nes-radio" v-on:keydown.c="onKeyDown" v-model="keyValue">右：{{ currentquestionKeyValueC }}</label>
      <div class="nes-progress gaudeWrapper mb-20">
        <div v-bind:style="styleObject" class="gauge"></div>
      </div>
      <div>{{ currentQuestionCounts }}/{{ TotalQuestionCounts }}</div>
    </div>
    <div v-if="currentQuestionCounts == TotalQuestionCounts" class="finish">
      <p>回答ありがとうございました<i class="nes-icon is-medium star"></i></p>
      <div class="nes-progress gaudeWrapper mb-20">
        <div v-bind:style="styleObject" class="gauge"></div>
      </div>
      <div>{{ currentQuestionCounts }}/{{ TotalQuestionCounts }}</div>
    </div>
  </div>
```

## Vue.jsを使ったカスタマイズスクリプトを作成

### CDN読み込み
#### JavaScript/CSSでカスタマイズ
- PC用のJavaScriptファイル: https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js
- PC用のCSSファイル: https://unpkg.com/nes.css@latest/css/nes.min.css


:::note info
ポイント
CSSの記述を減らし、デザインをいい感じにするために、今回はNES.cssを使用します
:::
https://nostalgic-css.github.io/NES.css/


### カスタムJavaScriptスクリプトを適用

```javascript:custom.js
(() => {
  'use strict';
  kintone.events.on('app.record.index.show', (event) => {
   if (event.viewId !== カスタマイズビューの一覧ID) return; // 先程コピーしたカスタマイズビューの一覧IDを入れる
   // この下にカスタマイズスクリプト
   // :
   // :
  });
})();
```


```javascript:custom.js
(() => {
  'use strict';
  kintone.events.on('app.record.index.show', (event) => {
   if (event.viewId !== カスタマイズビューの一覧ID) return; // スタマイズビューの一覧ID
   new Vue({
      el: '#app',
      data: {
        startFlg: '',
        keyValue: '',
        currentQuestionCounts: 0,
        TotalQuestionCounts: 3, // 質問の総数
        currentQuestion: '',
        questions: [
          '餃子は',
          '餃子といえば',
          'どのくらいの頻度で餃子を食べますか',
        ],
        questionKeyValueA: [
          '好き',
          '焼き餃子',
          '毎日'
        ],
        questionKeyValueB: [
          '普通',
          '水餃子',
          '週に1回以上'
        ],
        questionKeyValueC: [
          '苦手',
          '揚げ餃子',
          '月に1回以上'
        ],
        currentquestionKeyValueA: '',
        currentquestionKeyValueB: '',
        currentquestionKeyValueC: '',
        submitVal: '',
        submitParams: [],
        width: '',
        color: ''
      },
      methods: {
        AnswerStart: function(){
          this.startFlg = true
        },
        onKeyDown:function(key) {
          this.keyValue = key
        }
      },
      computed: {
        styleObject: function(){
          this.width = 33.3 * this.currentQuestionCounts + "%"
          if(this.currentQuestionCounts == this.TotalQuestionCounts){
            this.color = "#ffc107"
          } else {
            this.color = "#ffeb3b"
          }
          return{
            'width': this.width,
            'background-color': this.color,
          }
        }
      },
      // 最初に読み込まれるため、初期値を設定しておく
      mounted: function(){
        console.log(this.currentQuestionCounts)
        this.currentQuestion = this.questions[0]
        this.currentquestionKeyValueA = this.questionKeyValueA[0]
        this.currentquestionKeyValueB = this.questionKeyValueB[0]
        this.currentquestionKeyValueC = this.questionKeyValueC[0]
        document.body.addEventListener('keydown',
          event => {
            if (event.key) {
              this.onKeyDown(event.key);
            }
          });
      },
      // 更新イベントを受け取って処理する
      watch: {
        keyValue: function(getKeyVal){
          if (getKeyVal == 'Enter') this.startFlg = true;
          if (this.currentQuestionCounts > 3 || getKeyVal == 'Shift') location.reload();

          if (getKeyVal == 'a' || getKeyVal == 'b' || getKeyVal == 'c'){
            if (getKeyVal == 'a'){
              this.submitVal = this.questionKeyValueA[this.currentQuestionCounts]
            } else if (getKeyVal == 'b'){
              this.submitVal = this.questionKeyValueB[this.currentQuestionCounts]
            } else {
              this.submitVal = this.questionKeyValueC[this.currentQuestionCounts]
            }
            this.currentQuestionCounts += 1
            this.questions.splice(0,1)
            this.currentQuestion = this.questions[0]
            this.currentquestionKeyValueA = this.questionKeyValueA[this.currentQuestionCounts] //表示する選択肢を更新する
            this.currentquestionKeyValueB = this.questionKeyValueB[this.currentQuestionCounts]
            this.currentquestionKeyValueC = this.questionKeyValueC[this.currentQuestionCounts]
            this.submitParams.push(this.submitVal) // 回答結果をkintoneにPOSTするため配列に入れておく
            this.keyValue = '' //同じキーを判別できないため,クリアしておく

            if (this.submitParams.length == this.TotalQuestionCounts){
              //kintoneにRESTでPOSTする
              var body = {
                'app': kintone.app.getId(),
                'record': {
                  'question1': {
                    'value': this.submitParams[0]
                  },
                  'question2': {
                    'value': this.submitParams[1]
                  },
                  'question3': {
                    'value': this.submitParams[2]
                  }
                }
              }

              kintone.api(kintone.api.url('/k/v1/record.json', true), 'POST', body, (resp) => {
                // success
                console.log(resp);
              }, function(error) {
                // error
                console.log(error);
              });
            }
          }
        }
      }
    })
  });
})();
```

### カスタムCSSスクリプトを適用

```css:style.css

@charset "UTF-8";
@import url("https://fonts.googleapis.com/css2?family=DotGothic16&display=swap");

* {
  font-size: inherit;
  font-family: "DotGothic16", sans-serif;
}

/*kintoneのDOM非表示*/
.gaia-header-header,
.gaia-header-toolbar-navigation,
.gaia-argoui-app-index-pager {
  display: none !important;
}

.box-gaia {
  height: 100vh;
  font-size: 32px;
  background-image: url("https://背景にしたい画像のURL,パス");
  background-size: cover;
  background-repeat: no-repeat;
  color: #fff;
  position: relative;
}

.mb-20 {
  margin-bottom: 20px;
}

#app {
  width: 80%;
  height: 500px;
  text-align: center;
  font-size: 40px;
  color: rgb(46, 46, 46);
  margin: 150px auto;
}

.title {
  position: relative;
  font-size: 30px;
  font-weight: bold;
  margin: 50px 0;
}

.startButton {
  width: 400px;
  font-size: 35px;
  position: absolute !important;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.gaudeWrapper {
  width: 600px;
  margin: 0 auto;
}

.gauge {
  height: 40px;
  transition: all 0.3s ease;
}

.nes-btn, .nes-progress {
  border-image-repeat: unset !important;
}
```

## 3. フットペダルをPC or モニターに接続
※ フットペダルを持っていない方は、パソコンのキー操作(A,B,C)からアンケートの回答ができます🎉


## 4. 完成

<img src="https://media.giphy.com/media/BjsgZOmKoNpGZfKByl/giphy.gif" width="90%">

<font color="Crimson">※今回は最初の「回答してね」ボタンを`Enter`でスタートするようにカスタマイズしています。</font>