前提・実現したいこと
お問い合わせフォームでgoogle reCTPTCHAv2を実装した際、チェックを入れなければ送信されないようにしたい
発生している問題・エラーメッセージ
バリデーションは問題なく進んだがチェックを入れずに「送信ボタン」を押すと、「チェックを入れてください」と表示されたあと送信されてしまいます。
該当のソースコード
ソースコード
index.php 冒頭部分
<?php // セッションを開始 session_start(); // セッションIDを変更(セッションハイジャック対策) session_regenerate_id(TRUE); //reCAPTCHA の情報(Site Key)の読み込み require_once('./recaptchavars.php'); // //データの検証とエスケープ処理の関数の読み込み require './functions.php'; //初回以外ですでにセッション変数に値が代入されていれば、その値を。そうでなければNULLで初期化 $name = isset($_SESSION['name']) ? $_SESSION['name'] : NULL; $email = isset($_SESSION['email']) ? $_SESSION['email'] : NULL; $message = isset($_SESSION['mmessage']) ? $_SESSION['message'] : NULL; $error = isset($_SESSION['error']) ? $_SESSION['error'] : NULL; //CSRF対策の固定トークンを生成 if(!isset($_SESSION['ticket'])){ //セッション変数にトークンを代入 $_SESSION['ticket'] = sha1(uniqid(mt_rand(), TRUE)); } //トークンを変数に代入 $ticket = $_SESSION['ticket']; ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0"> <title>SAYAKA ONO -portfolio-</title> <link href="https://fonts.googleapis.com/css?family=Spinnaker&display=swap" rel="stylesheet"> <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet"> <link rel="stylesheet" href="css/normalize.css"> <link rel="stylesheet" href="css/style.css"> <!-- <script src="https://www.google.com/recaptcha/api.js" async defer></script> --> <script src="js/jquery-3.4.1.min.js"></script> <!-- reCAPTCHA --> <script type="text/javascript"> var onloadCallback = function() { grecaptcha.render('recaptcha', { 'sitekey' : "<?php echo RC_SITE_KEY; ?>", 'callback' : verifyRecaptcha, 'expired-callback' : expiredCallback, 'theme' : 'light', 'size' : 'compact' }); }; var verifyRecaptcha = function(response) { if(response != "") { document.getElementById('recaptcha').className = "g-recaptcha verified"; var recaptchaError = document.getElementById('recaptcha_error'); if(recaptchaError != null) { recaptchaError.parentNode.removeChild(recaptchaError); } var recaptchaExpired = document.getElementById('expired'); if(recaptchaExpired != null) { recaptchaExpired.parentNode.removeChild(recaptchaExpired); } } }; var expiredCallback = function() { var p = document.createElement('p'); p.textContent = 'チェックボックスをもう一度オンにしてください。'; p.setAttribute('class', 'error'); p.setAttribute('id', 'expired'); var recaptcha_div = document.getElementById('recaptcha'); var recaptchaExpired = document.getElementById('expired'); if(recaptchaExpired == null) { recaptcha_div .appendChild(p); } document.getElementById('recaptcha').className = "g-recaptcha"; }; </script> <!-- reCAPTCHA -->
script.php
``` $("form").submit(function(){ //submit イベント //エラー表示の初期化 $("p.error").remove(); //reCAPTCHA の検証 if(!$('#recaptcha').hasClass('verified')) { $('#recaptcha').append("<p class='error' id='recaptcha_error'>チェックを入れてください</p>"); } //error クラスの追加の処理 if($("p.error").length() > 0){ //エラーがあれば $("p.error").parent().addClass("error"); //親要素にクラスを追加 } //エラーがあれば送信しない if($("p.error").length() > 0){ return btn_flg = false; } }); contact.js 部分
let form_confirm = document.getElementById('form-confirm'); // 送信後の装飾 let submit_btn = document.getElementById('send-btn'); let recaptcha = document.getElementById('recaptcha'); let return_message = document.getElementById('return-message'); form_confirm.addEventListener('click', () => { // フォームの名前 let form_name = document.getElementById('form-name').value; // let confirm_name = document.getElementById('confirm-name'); let name = document.getElementById('name'); // フォームのメールアドレス let form_email = document.getElementById('form-email').value;// let confirm_email = document.getElementById('confirm-email'); let email = document.getElementById('email'); // フォームの問い合わせ内容 let form_content = document.getElementById('form-content').value; let confirm_content = document.getElementById('confirm-content'); let message = document.getElementById('message'); // ボタンの表示有無 let send_btn = document.getElementById('mail-form'); // 初期化 confirm_name.classList.remove('text-danger'); confirm_email.classList.remove('text-danger'); confirm_content.classList.remove('text-danger'); let btn_flg = true; // フォームのバリデーション // 未入力検出 if (form_name === '') { form_name = '名前が未入力です。' confirm_name.classList.add('text-danger'); btn_flg = false; } // フォームのバリデーション // 未入力検出 if (form_email === '') { form_email = 'メールアドレスが未入力です。' confirm_email.classList.add('text-danger'); btn_flg = false; } else { // メールフォーマットのバリデーション if (form_email.match(/.+@.+..+/) === null) { form_email = '不正なメールアドレスです。正しい形式例:sample@sayaka-log.com' confirm_email.classList.add('text-danger'); btn_flg = false; } } // フォームのバリデーション // 未入力検出 if (form_content === '') { form_content = 'お問い合わせ内容が未入力です。' confirm_content.classList.add('text-danger'); btn_flg = false; } // 送信ボタンの表示有無 if (btn_flg === false) { send_btn.style.display = 'none'; } else { send_btn.style.display = 'block'; close.style.display = 'none'; } confirm_name.textContent = form_name; name.value = form_name; confirm_email.textContent = form_email; email.value = form_email; confirm_content.textContent = form_content; message.value = form_content; }); (() => { let server = './sendmail.php'; //送信先サーバーのURLを設定する; let xhr = new XMLHttpRequest(); let form = document.getElementById('mail-form'); let formHTML = form.innerHTML; let tempForm = {}; form.onsubmit = (e) => { e.preventDefault(); //多重送信を防止; let submit = form.querySelector('input[type="submit"]'); submit.disabled = false; //formの内容を保存; (() => { let elements = form.elements; for(var i = 0; i < elements.length; i++) { tempForm[elements[i].name] = elements[i].value; } })(); //サーバーにFormDataを送信; (() => { //FormDataを取得し、送信元サーバーを追加; let formData = new FormData(form); formData.append('from', location.host); xhr.open('POST', server); //カスタムヘッダーをつける; xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); //結果はjsonだが、IEが対応していないのでtextで受け取る; xhr.responseType = 'text'; xhr.timeout = '10000'; xhr.send(formData); })(); }; xhr.addEventListener('loadend', () => { //ボタンを削除 submit_btn.classList.add('hidden'); recaptcha.classList.add('hidden'); // let spinner = document.getElementById('spinner'); // spinner.classList.remove('hidden'); if(xhr.status === 200) { let response = JSON.parse(xhr.response); if(response.result) { //メールが送信された時の処理; // resultElements.p.textContent = '送信に成功しました。'; // spinner.classList.add('hidden'); return_message.childNodes[0].textContent = 'メールの送信が完了しました。'; return_message.childNodes[1].textContent = '担当から連絡しますので少々お待ちください。'; return_message.classList.remove('hidden'); return; } } //メールが送信されなかった時の処理; // spinner.classList.add('hidden'); return_message.childNodes[0].textContent = '送信に失敗しました。'; return_message.childNodes[1].textContent = 'ページを更新して再度送信していただくか、しばらく経ってから連絡ください。'; return_message.classList.remove('hidden'); return; }, false); })();
試したこと
.length を .size にしましたが同じエラーでした。こちらです。
[
[追記」
エラー文章は
Type Error: $(...).length is not a function です。
lengthの後ろに()がついていたのでそれをとって見たところ、チェックをしていないのに「チェックを入れてください」も表示されず送信されてしまいます。
よろしくおねがします。