MW WP Formバリデーションのカスタマイズ(サンプル)

MW WP Formプラグインを使ってアンケートフォームを作りました。
バリデーション(入力チェック)を次のようにカスタマイズしています。

  • エラーメッセージの文言と表示位置をカスタマイズ
  • エラーの件数を画面上部に表示
  • 複数の項目で、回答が1つもない場合エラーを表示させる
  • ある項目を選択した場合、テキストフィールドを必須項目にする
  • 生年月日など複数のエラーをまとめる

サービスに関するアンケート(サンプル)です。バリデーションの動作を確認できます。
※確認画面は表示されますが、フォームは送信できないようになっています。

Q1. あなたが、このサービスを知ったきっかけをお聞かせください(複数選択可)

Q2. あなたが、このサービスを利用する頻度をお聞かせください

Q3. あなたは、このサービスにどれくらい満足していますか

基本情報

性別(必須)

生年月日(必須)

お住まいの都道府県(必須)


MW WP Form管理画面

<div class="display-error">[mwform_hidden name="アンケート_エラー" show_error="false"][mwform_error keys="アンケート_エラー"]</div>
<p class="q">Q1. あなたが、このサービスを知ったきっかけをお聞かせください(複数選択可)</p>
[mwform_checkbox name="サービス" children="テレビ,新聞,雑誌,検索エンジン,SNS・ブログ,家族・友人・知人,その他" separator="," vertically="true"]
<div class="display-error">[mwform_error keys="その他"]</div>
[mwform_textarea name="その他" cols="50" rows="5" placeholder="その他を選択した場合、入力してください" show_error="false"]


<p class="q">Q2. あなたが、このサービスを利用する頻度をお聞かせください</p>
[mwform_radio name="頻度" children="ほぼ毎日,1週間に一回,1ヶ月に数回,2〜3ヶ月に数回,それ以下" vertically="true"]

<p class="q">Q3. あなたは、このサービスにどれくらい満足していますか</p>
[mwform_radio name="満足" children="満足,やや満足,普通,やや不満,不満" vertically="true"]


<h4>基本情報</h4>
<div class="display-error">[mwform_error keys="性別"]</div>
<p class="mb10">性別(必須)</p>
[mwform_radio name="性別" children="男性,女性" show_error="false" vertically="true"]

<div class="display-error">[mwform_error keys="年,月,日"]</div>
<p class="mb10">生年月日(必須)</p>
<div class="barth_area">[mwform_select name="年" class="yarea" children=":--,2017(平成29),2016(平成28),2015(平成27),2014(平成26),2013(平成25),2012(平成24),2011(平成23),2010(平成22),2009(平成21),2008(平成20),2007(平成19),2006(平成18),2005(平成17),2004(平成16),2003(平成15),2002(平成14),2001(平成13),2000(平成12),1999(平成11),1998(平成10),1997(平成9),1996(平成8),1995(平成7),1994(平成6),1993(平成5),1992(平成4),1991(平成3),1990(平成2),1989(平成元年),1988(昭和63),1987(昭和62),1986(昭和61),1985(昭和60),1984(昭和59),1983(昭和58),1982(昭和57),1981(昭和56),1980(昭和55),1979(昭和54),1978(昭和53),1977(昭和52),1976(昭和51),1975(昭和50),1974(昭和49),1973(昭和48),1972(昭和47),1971(昭和46),1970(昭和45),1969(昭和44),1968(昭和43),1967(昭和42),1966(昭和41),1965(昭和40),1964(昭和39),1963(昭和38),1962(昭和37),1961(昭和36),1960(昭和35),1959(昭和34),1958(昭和33),1957(昭和32),1956(昭和31),1955(昭和30),1954(昭和29),1953(昭和28),1952(昭和27),1951(昭和26),1950(昭和25),1949(昭和24),1948(昭和23),1947(昭和22),1946(昭和21),1945(昭和20),1944(昭和19),1943(昭和18),1942(昭和17),1941(昭和16),1940(昭和15),1939(昭和14),1938(昭和13),1937(昭和12),1936(昭和11),1935(昭和10),1934(昭和9),1933(昭和8),1932(昭和7),1931(昭和6),1930(昭和5),1929(昭和4),1928(昭和3),1927(昭和2),1926(昭和元年),1925(大正14),1924(大正13),1923(大正12),1922(大正11),1921(大正10),1920(大正9),1919(大正8),1918(大正7),1917(大正6),1916(大正5),1915(大正4),1914(大正3),1913(大正2),1912(大正元年),1911(明治44),1910(明治43),1909(明治42),1908(明治41)" post_raw="true" show_error="false"] 年 [mwform_select select name="月" class="marea" children=":--,1,2,3,4,5,6,7,8,9,10,11,12" post_raw="true" show_error="false"] 月 [mwform_select select name="日" class="darea" children=":--,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31" post_raw="true" show_error="false"] 日
</div>

<div class="display-error">[mwform_error keys="都道府県"]</div>
<p class="mb10">お住まいの都道府県(必須)</div>
[mwform_select name="都道府県" children=":--,北海道,青森県,岩手県,宮城県,秋田県,山形県,福島県,茨城県,栃木県,群馬県,埼玉県,千葉県,東京都,神奈川県,新潟県,富山県,石川県,福井県,山梨県,長野県,岐阜県,静岡県,愛知県,三重県,滋賀県,京都府,大阪府,兵庫県,奈良県,和歌山県,鳥取県,島根県,岡山県,広島県,山口県,徳島県,香川県,愛媛県,高知県,福岡県,佐賀県,長崎県,熊本県,大分県,宮崎県,鹿児島県,沖縄県" show_error="false" post_raw="true"]


[mwform_bback value="back" class="back"]戻る[/mwform_bback]
[mwform_submitButton name="確認" confirm_value="確認画面へ" submit_value="送信する"]

functions.php

function form_validation_rule($Validation, $data, $Data)
{
  // サービスメニューのチェック
  if (
    isset($data['サービス']) ||
    isset($data['頻度']) ||
    isset($data['満足']) 
  ) {

    if (
      empty($data['サービス']['data']) &&
      empty($data['頻度']) &&
      empty($data['満足']) 
    ) {
      $Validation->set_rule('アンケート_エラー', 'noEmpty', array('message' => '最低1つの質問にお答えください'));
    }
  }
  // その他を選択した場合
  if (
    in_array('その他', $data['サービス']['data'])
  ) {
    $Validation->set_rule('その他', 'noEmpty', array('message' => 'その他を選択した場合、入力をお願いします'));
  }
  // 年月日をまとめる
  $validation_message = '生年月日を入力してください';

  if (empty($data['年'])) {
    $Validation->set_rule('年', 'noEmpty', array('message' => $validation_message));
  } elseif(empty($data['月'])) {
    $Validation->set_rule('月', 'noEmpty', array('message' => $validation_message));
  } elseif(empty($data['日'])) {
    $Validation->set_rule('日', 'noEmpty', array('message' => $validation_message));
  }

  // 基本情報のバリデーション
  $Validation->set_rule('性別', 'required', array('message' => '性別を選択してください'));
  $Validation->set_rule('都道府県', 'noEmpty', array('message' => '都道府県を選択してください'));

  return $Validation;
}

add_filter('mwform_validation_mw-wp-form-XXXX', 'form_validation_rule', 10, 3);

JavaScript

function formErrorAppear() {
    // エラーの数を取得
    const errorElm = document.querySelectorAll(".error");

    if (errorElm.length > 0) {
        // 表示するエラーの要素を作成
        errorElm[0].id = "errorTarget";
        const createErrorElm = document.createElement('div');
        const errorElemText = document.createTextNode(`入力エラーが${errorElm.length}件あります`);

        const createtargetElm = document.createElement('a');
        const targetElemText = document.createTextNode(`エラーに移動する▼`);

        createtargetElm.href = "#errorTarget";
        createtargetElm.appendChild(targetElemText);

        createErrorElm.appendChild(errorElemText);
        createErrorElm.appendChild(createtargetElm);

        createErrorElm.classList.add("error-notice");

        const parentElm = document.querySelector(".article-header"); // 要素を追加する親要素
        const titleElm = document.querySelector(".entry-title"); // この要素の前に追加
        parentElm.insertBefore(createErrorElm, titleElm);

    }
}

document.addEventListener("DOMContentLoaded", function() {
  // カレントURL
  const currrentURL = location.href;
  // フォームのページだけ実行
  if (currrentURL.indexOf(/mw-wp-form-error/) > 0 ) {
      formErrorAppear();
  }
});

CSS

.date-tags,
.sns-share,
.sns-follow,
.footer-meta {display: none !important}

/* 必須 */
.require {
    font-size: .7em;
    background: #ff0000;
    padding: 0.3em 0.5em;
    color: #fff;
    margin-left: 5px;
}


/* エラー */

.mw_wp_form .error {
    background: #ffeaea;
    padding: 0.3em 0.5em;
    margin-bottom: 10px;
    display: block;
    flex: 0 1 100%;
}

.error-notice {
    color: #B70000;
    background: #ffeaea;
    padding: 14px;
    text-align: center;
}

.error-notice a {
    display: block;
    font-size: 0.8em;
}

/* レイアウト */
.enquete_area { padding: 20px; border:1px solid #ccc;}
.enquete_area  .lead p { font-size: 0.9em; line-height: 1.6;}
.enquete_area  .q {background: #eaeaea;padding: 10px;}
.enquete_area  .barth_area { display: flex; align-items: center; margin-bottom: 30px}
.enquete_area  .barth_area  .yarea { flex: 0 0 30%; margin-right: 5px;}
.enquete_area  .barth_area  .marea,
.enquete_area  .barth_area  .darea { flex: 0 0 24%; margin-right: 5px; margin-left: 5px;}

/* 送信ボタン */
.enquete_area input[type='submit'] {
    max-width: 320px;
    display: block;
    margin: 0 auto;
    background: #c7a85e !important;
    color: #fff;
    font-size: 1em;
}

.enquete_area button[type='submit'].back {
    background: none;
    border: none;
    color: #000;
    font-family: 'Noto Sans JP';
    color: blue;
    text-decoration: underline;
    font-size: 1em;
}