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

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

ただいまの
回答率

90.45%

  • JavaScript

    21057questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

【transmitMail】非表示エリアのバリデーションを無効にしたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 90

kitty

score 8

やりたいこと

transmitMailを使用してメールフォームを作成しています。
ラジオボタンの電話をチェックすると、
メールアドレス入力欄が非表示になり、再度メールにチェックをすると
メールアドレス入力欄が表示される。
というラジオボタンのチェック状況によって表示/非表示を切り替えるところまではできています。
できていないこと
メールにチェックをした場合のみ、メールアドレス入力欄は必須項目となります。
現在、電話にチェックして、メールアドレス入力欄が非表示になっているにも関わらず
バリデーションが効いてしまっていて、確認画面に進むことができていません。

コード①:ラジオボタン選択箇所

            <tr>
              <th class="required">ご希望の連絡方法</th>
              <td>
                <div class="contact-radio">
                  <label class="contact-radio__item">
                    <input type="radio" name="ご希望の連絡方法" value="メール" {$checked.ご希望の連絡方法.メール}>
                    メール
                  </label>
                  <label class="contact-radio__item">
                    <input type="radio" name="ご希望の連絡方法" value="電話" {$checked.ご希望の連絡方法.電話}>
                    電話
                  </label>
                </div>
                <input type="hidden" name="required[]" value="ご希望の連絡方法">
                {if:$required.ご希望の連絡方法}
                <div class="contact-note--under">{$required.ご希望の連絡方法}</div>
                {/if:$required.ご希望の連絡方法}               
              </td>
            </tr>

コード②:表示/非表示が変わる箇所

            <tr id="js-mailArea">
              <th class="required">メールアドレス</th>
              <td>
                <div class="contact-paragraph">
                  <input type="email" name="メールアドレス" value="{$メールアドレス}" class="contact-input" placeholder="info@links-ap.jp">
                  <input type="hidden" name="email[]" value="メールアドレス">
                  {if:$email.メールアドレス}
                  {$email.メールアドレス}
                  {/if:$email.メールアドレス}
                  <input type="hidden" name="required[]" value="メールアドレス" class="requireMail"><!-- ←必須の記述① -->
                  {if:$required.メールアドレス}
                  <div class="contact-note--under font-bold font-red">{$required.メールアドレス}</div>
                  {/if:$required.メールアドレス}                  
                </div>
                <div class="contact-paragraph">
                  <p class="contact-note--top">確認のため、もう一度ご入力ください。</p>
                  <input type="email" name="メールアドレス確認用" value="{$メールアドレス確認用}" class="contact-input" placeholder="info@links-ap.jp">
                  <input type="hidden" name="match[]" value="メールアドレス メールアドレス確認用">
                  {if:$match.メールアドレス}
                  <div class="contact-note--under font-bold font-red">{$match.メールアドレス}</div>
                  {/if:$match.メールアドレス}
                  <input type="hidden" name="required[]" value="メールアドレス確認用" class="requireMail"><!-- ←必須の記述② -->
                  {if:$required.メールアドレス確認用}
                  <div class="contact-note--under">{$required.メールアドレス確認用}</div>
                  {/if:$required.メールアドレス確認用}
                </div>
              </td>
            </tr>


※電話の方は一旦割愛させていただきます。必要でしたら記載します。

const mailArea = document.getElementById('js-mailArea');
const telArea = document.getElementById('js-telArea');//割愛している電話エリアの指定
const form = document.getElementById('formArea');
const targets = document.getElementById('requireMail');
const value = targets.getAttribute(name);
const elm = document.querySelectorAll('.requireMail[name="require[]"]');//設定はしているものの使い方がわからない

let result = null;
const radios = document.getElementsByName('ご希望の連絡方法');

const output = () => {
  for(let i = 0;i < radios.length;i++) {
  if(radios[i].checked) {
    result = radios[i].value;
    if(result === 'メール') {
      mailArea.classList.remove('is-hidden');//is-hiddenをつけるとエリアが非表示になる
      telArea.classList.add('is-hidden');
    } else {
      telArea.classList.remove('is-hidden');
      mailArea.classList.add('is-hidden');
    }
  }
}
}

form.addEventListener('change',()=> {
  output();
});

試したこと

※1<input type="hidden" name="required[]" value="メールアドレス確認用" class="requireMail">
→これ(※1)が必須項目とさせている記述になるので、
電話を選択した時だけ「.requireMail」のname値「required[]」を空に
書き換えてしまおうと考えたのですが書き方が検討つきませんでした。

それなら、この(※1)記述自体を削除してしまおうとしたのですが
再度メールにチェックした際にこの要素が復活せず・・
(jqueryでいう、「append」や「detach」を使って削除した要素を復活できないのかなと考えていたが、javascriptで代わりのものが見つからなかった。)
例:https://www.sejuku.net/blog/39300#i-3

ちなみに、このTransmitMailには、バリデーションを考慮した上
でチェック状態によって出し分ける設定が用意されていないようです。
※ソース
https://github.com/dounokouno/TransmitMail/issues/2

TransmitMailで利用しているテンプレートには、if文の比較演算がありません。ですので、「ラジオボタンの選択内容を判別して表示を切り替える」ことはできません

正直全くわからないので・・・何かヒントでも回答でも
なんでもいただけたら嬉しいです。
よろしくお願いします。

追記

皆様のアドバイスを元に完成したものを一応記載します。
disabledの付け外しが少し苦戦したのでどなたかの参考になれば幸いです。
(もっと効率いい書き方はあると思いますが・・)
forEach文は勉強中のためfor文で。

let hiddenAdd;
let hiddenRemove;
//属性を追加
const hiddenAddFunc = (hiddenAdd) => {
    for(let i = 0;i < hiddenAdd.length;i++) {
    hiddenAdd[i].setAttribute('disabled','disabled');
  }  
}
//属性を削除
const hiddenRemoveFunc = (hiddenRemove) => {
    for(let i = 0;i < hiddenRemove.length;i++) {
    hiddenRemove[i].removeAttribute('disabled');
  }  
}
//判定文
let flag = 0;
const hantei = (flag) => {
  if(flag === 1) {
    let hiddenAdd = telArea.querySelectorAll('input');     
    let hiddenRemove = mailArea.querySelectorAll('input');     
    hiddenAddFunc(hiddenAdd);
    hiddenRemoveFunc(hiddenRemove);
  } else if(flag === 2) {
    let hiddenAdd = mailArea.querySelectorAll('input');     
    let hiddenRemove = telArea.querySelectorAll('input');     
    hiddenAddFunc(hiddenAdd);
    hiddenRemoveFunc(hiddenRemove);  
  }
}

const output = () => {
  for(let i = 0;i < radios.length;i++) {
  if(radios[i].checked) {
    result = radios[i].value;
    if(result === 'メール') {
      mailArea.classList.remove('is-hidden');
      telArea.classList.add('is-hidden');
      let flag = 1;
      hantei(flag);
    } else {
      telArea.classList.remove('is-hidden');
      mailArea.classList.add('is-hidden');
      let flag = 2;
      hantei(flag);
    }

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+3

TransmitMail の開発者です。 TransmitMail をご利用いただきありがとうございます。

x_x さんも書いてくださっていますが、 disabled 属性を付与するのが簡単そうです。( disabled 属性 を付与すると、その input は送信されなくなるので。)

disabled 属性の付与は、例えば下記のようなコードです。

document.querySelectorAll('.requireMail').forEach(element => {
    element.setAttribute('disabled', 'disabled');
});

ご参考になれば幸いです。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/06/16 12:56

    確認が遅くなってすみません。
    他にも応用できそうです。ありがとうございます。

    キャンセル

+1

.is-hiddenとrequiredの組み合わせの話でしょうか?

<script>
window.addEventListener('DOMContentLoaded', function(e){
  console.log(document.querySelectorAll('[required]:not(.is-hidden)').length);//命題はたぶんこれ
  console.log(document.querySelectorAll('[required]').length);
  console.log(document.querySelectorAll('[required].is-hidden').length);
  console.log(document.querySelectorAll('.is-hidden').length);
  console.log(document.querySelectorAll('.is-hidden:not([required])').length);
});

</script>
<input type="text" required>
<input type="text" required class="is-hidden">
<input type="text" class="is-hidden">

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/06/16 13:00

    ご確認ありがとうございました。
    また確認が遅くなってしまい申し訳ございません。is-hiddenがついている時にどうするか〜の判定の方が楽ですね。(targetの全てに".requireMail"をつけるより・・)。今回は開発者様のご提案で処理することにしました。また機会がありましたら宜しくお願いします。

    キャンセル

+1

(jqueryでいう、「append」や「detach」を使って削除した要素を復活できないのかなと考えていたが、javascriptで代わりのものが見つからなかった。)

jQuery は JavaScriptでできているので当然あります。
https://developer.mozilla.org/ja/docs/Web/API/Node/removeChild

しかし、要素自体を消したり追加するよりも disabled 属性をつけて無効にしたほうが簡単そうです。
https://developer.mozilla.org/ja/docs/Web/HTML/Element/Input#disabled

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/06/16 12:57

    ご確認ありがとうございました。
    また遅くなってしまい申し訳ございません。
    disabledをヒントに自分なりにも記述してみました。
    他にも応用したいと思います。
    また機会がありましたら宜しくお願いします。

    キャンセル

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

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

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

  • JavaScript

    21057questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。