【HTML】JavaScriptで検証結果のポップアップを呼び出す

ハマった。

デフォルトのValidationAPIはsubmitされないとポップアップしない?

<form id="f">
  <input type="text" name="firstname" id="firstname" required> 
  <button type="submit">submit</button>
</form>

これをJavaScriptから

let elForm = document.getElementById('f');
elForm.submit();

したら、検証を無視してページ遷移が発生。

で、それっぽいAPIがあるんだけど、どれを見ても検証結果の true / falseを知ることができるだけで、検証結果のメッセージがポップアップしない。

if (elForm.checkValidatity()) {
   document.getElementById('error').innerText = ('エラーがあります。');
}

俺はデフォルトのあの動作が欲しいんだ。

とりあえずの解決法

function popupInvalided(elForm) {

    const fnSubmitHandler = (event) {
        event.preventDefault();
    }

    let btn = document.createElement('button');
    btn.setAttribute('type', 'submit');
    btn.style.display = 'none';

    elForm.addEventHandler(fnSubmitHandler);
    elForm.appendChild(btn);
    
    setTimeout(() => {
        btn.click();
        setTimeout(() => {
            elForm.removeEventListener('submit', fnSubmitHandler);
            btn.remove();
        });
    }, 0);
}

探したらポップアップするAPIあると思うんだけど。 これだけのためにW3C文書読む気になれない。

おまけ:setCustomValitiyの挙動

setCustomValidityで自由にエラー扱いにできるしエラーメッセージも動的に決められるが、 JavaScriptで空文字を再設定しない限り、ずっとその項目はエラーになり続ける。

// 書きかけたバグ
if (!input.checkValidity()) {
    input.setCustomValidity('オリジナルのメッセージ');
}

回避策

  • HTMLにtitleつけて回避する。
<input type="text" required title="名前は必須です。">
  • setCustomValidityを使うところは、checkValidity()の前だけにする。