質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.80%

Vue.jsを使ったフォーム作成

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,414

DUNK

score 12

Vue.jsを使いながら問い合わせ用のフォームを作っています。
個々のinputにバリデショーンをかけ、すべてのバリデーションをパスしたらフォームの送信ボタンから送信されるようにしています。未入力の場合は入力を促すメッセージを。それぞれの正規表現に合わない場合は正しく入力させるメッセージを表示するようにしています。

フォーカスを外した時のそれぞれのバリデーションは問題なく動いているのですが、送信ボタンを押下した時にinput内に文字は入っているのに入力を促すメッセージが出てきてしまうので困っています。
よろしくお願いします。

<body>
  <form id="test" name="inquiry" action="#" method="post" @submit.prevent="sendMail()">
    <input type="" name="email" @blur="validation">
    <p>{{ errors.email }}</p>
    <input type="" name="name" @blur="validation">
    <p>{{ errors.name }}</p>
    <input type="" name="namePhonetic" @blur="validation">
    <p>{{ errors.namePhonetic }}</p>
    <input type="" name="phoneNumber" @blur="validation">
    <p>{{ errors.phoneNumber }}</p>
    <input type="submit" name="send" href="#" value="送信">
    <p>{{ sendMessage }}</p>
  </form>

  <script type="text/javascript" src="vue.js"></script>
  <!-- <script type="text/javascript" src="for_study.js"></script> -->
  <script>

  var app =  new Vue({
    el:"#test",

    data:{
      sendMessage: "",
      values: {
        name: "",
        namePhonetic: "",
        phoneNumber: "" ,
        email: "" ,
      },
      validations: {
        email: {
          pattern: /^[A-Za-z0-9]{1}[A-Za-z0-9_.-]*@{1}[A-Za-z0-9_.-]{1,}\.[A-Za-z0-9]{1,}$/,
          required: true,
        },
        name:{
          pattern: "",
          required: true,
        },
        namePhonetic: {
          pattern: /^[ぁ-ん]+$/,
          required: true,
        },
        phoneNumber: {
          pattern: /^[0-9]*$/,
          required: false,
        },
      },
      errors: {
        email: "",
        name:"",
        namePhonetic:"",
        phoneNumber:"",
      },
      errorMessage: {
        required: "必須です",
        email: "正しい形式で入力してください",
        name:"",
        namePhonetic:"ひらがなで入力してください",
        phoneNumber:"半角数字で入力してください",
      },
    },
    methods:{
      validation:function(event) {

        if(!event){
          let errorCount = 0;
          for (var i=0; i < Object.keys(this.values).length; i++) {
            let key = Object.keys(this.values);
            let value = Object.values(this.values);
            if(this.validations[key].required) {
              if(value === "") {
                this.errors[key] = this.errorMessage.required;
                errorCount++;
              }
            }
            else {
              if(!value.match(this.validations[key].pattern)) {
                this.errors[key] = this.errorMessage[key];
                errorCount++;
              }
            }
          }
          /console.log(errorCount);
          return errorCount;
        } else {
          const form = event.target;
          if(this.validations[form.name].required) {
            if(!event.target.value) {
              this.errors[form.name] = this.errorMessage.required;
            } else if (
              !event.target.value.match(this.validations[form.name].pattern)) {
                this.errors[form.name] = this.errorMessage[form.name];
              }
              else {
                this.errors[form.name] = ""
              }
            }
            else if (!event.target.value.match(this.validations[form.name].pattern)) {
              this.errors[form.name] = this.errorMessage[form.name];
            }
            else {
              this.errors[form.name] = ""
            }
          }
        },


        sendMail:function(event) {
          console.log(this.validation());
          return true;
          //   if(this.validation()=== 0) {
          //     this.sendMessage = "送信されました"
          //   }else {alert("入力エラーがあります");
          //   return false;
          // }
        },
      }
    })
    </script>

試したこと

コードを改変してどこまでしっかり動いているか確認しようとしたところif(!event){....内を未入力の際のバリデーションにしたところ今度は未入力の状態でも送信できるようになってしまいました。

追記

ご回答頂いた通りにひとまず必須の部分が対応しているか確認すべく編集してみたのですが、以下の編集でよろしいのでしょうか。

validation:function(event) {
        if(!event){
          let errorCount = 0;
          // for (var i=0; i < Object.keys(this.values).length; i++){
          Object.entries(this.values).forEach((key, value) => {
          console.log(key,value);
            //let key = Object.keys(this.values);
            //let value= Object.values(this.values);
            if(this.validations.key.required) {
              if(value === "") {
                this.errors.key = this.errorMessage.required;
                errorCount++;
              }
            }
            // else {
            //   if([!value].match(this.validations[key].pattern)) {
            //     this.errors[key] = this.errorMessage[key];
            //     errorCount++;
            //   }
            // }
          })
          console.log(errorCount);
          return errorCount;
        } 


この場合ですと、以下のようなエラーになってしまいました。

[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'required' of undefined"


カッコをつけたり外したりしてみたのですが、エラーが出るか出なくても想定通りに動きません。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+3

まず最初のfor文の中で、
valuesのkeyを取り出して回しているイメージだと思うのですが、keyにvaluesのkeyの配列がそのまま入ってしまっています。

Objectの中身を取り出して回すという目的であれば、

Object.entries(this.values).forEach((key, value) => {
  // ここに処理を書く
})

が適していると思います。

まずこれを修正してみて、まだ想定通り動かなければお使いのブラウザのコンソールに出ているであろうエラーを追記してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/22 09:53

    ご回答ありがとうございます。
    初心者なのでメソッドを使いこなせていないので勉強になりました。
    試してみます

    キャンセル

  • 2019/04/22 13:08

    追記いたしましたが、上のような方法であっていますでしょうか

    キャンセル

  • 2019/04/22 17:25

    度々すいません。ご回答をもとに編集したところ解決いたしました。
    感謝します。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る