久しぶりの投稿です。今回はJavaScriptのミニネタ。
明細のある入力フォームを作っていて、明細部分の商品名が重複していたらエラーとなるように、jsでバリデーションをつけたかったのです。目指すのは以下の画像のような感じ。

そこでjQueryでこんなコードを書いてみました。保存ボタンをクリックすると、テキストフィールドの数ぶんループし、同じ入力値が2件以上あればエラーメッセージを表示するというもの。
<form>
<p class="cation"></p>
1. <input type="text"><br>
2. <input type="text"><br>
3. <input type="text"><br>
4. <input type="text"><br>
<button type="submit">保存</button>
</form>
$('button').on('click', function() {
$('input').each(function() {
var value = $(this).val();
if (value && $('input[value="' + value + '"]').length >= 2) {
$('.cation').html('重複しているよ!');
return false;
}
});
})
これでhogeを2箇所に入力して保存ボタンをクリックしても、バリデーションエラーになりません。ためしに$('input[value="hoge"]')
だけ実行してみると、domが取れません。なぜ…?
どうやらテキストフィールドに対してvalueの属性セレクタを使用すると、valueのデフォルト値でしか取得できないようです。つまりテキストフィールドに後から入力した値は、valueの属性セレクタでは取得できません。
この例ではvalueのデフォルト値は空のため、value=”hoge”は効かなかったようです。たしかに、hoge入力後に開発者ツールで中身を見ると、valueの値は入っていませんね…。

これはjQueryだけの問題ではなく、jsのDocument.querySelector()
の仕様みたいです。
ということで苦し紛れに以下のように書き換えました。jQueryのval()
なら今入力されている値が取得できました。
$('button').on('click', function() {
$('input').each(function() {
var value = $(this).val();
if (!value) {
return false;
}
var count = 0;
$('input').each(function() {
if ($(this).val() == value) {
count++;
}
});
if (count >= 2) {
$('.cation').html('重複しているよ!');
return false;
}
});
})