web-dev-qa-db-ja.com

e.preventDefault()を呼び出した後にフォームを送信する

ここでいくつかの簡単なフォーム検証を行っていますが、非常に基本的な問題にこだわっています。名前と前菜用の5つのフィールドペアがあります(ディナー登録用)。ユーザーは1〜5ペアを入力できますが、名前が存在する場合は前菜を選択する必要があります。コード:

http://jsfiddle.net/eecTN/1/

<form>
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    <input type="submit" value="Submit">
</form>
// Prevent form submit if any entrees are missing
$('form').submit(function(e){

    e.preventDefault();

    // Cycle through each Attendee Name
    $('[name="atendeename[]"]', this).each(function(index, el){

        // If there is a value
        if ($(el).val()) {

            // Find adjacent entree input
            var entree = $(el).next('input');

            // If entree is empty, don't submit form
            if ( ! entree.val()) {
                alert('Please select an entree');
                entree.focus();
                return false;
            }
        }
    });

    $('form').unbind('submit').submit();

});

エラーメッセージは機能していますが、毎回フォームを送信しています。私はこの行に何か問題があることを知っています:

$('form').unbind('submit').submit();

...しかし、私は何をする必要があるのか​​分かりません。

55
Wesley Murch

最も簡単な解決策は、検証が実際に失敗しない限り、単にnot call e.preventDefault()にすることです。その行を内側のifステートメント内に移動し、.unbind().submit()を持つ関数の最後の行を削除します。

71
nnnnnn

ネイティブelement.submit()を使用してjQueryハンドラーのpreventDefaultを回避します。returnステートメントは各ループからのみ戻り、イベントハンドラーからは戻りません。

$('form').submit(function(e){
    e.preventDefault();

    var valid = true;

    $('[name="atendeename[]"]', this).each(function(index, el){

        if ( $(el).val() ) {
            var entree = $(el).next('input');

            if ( ! entree.val()) {
                entree.focus();
                valid = false;
            }
        }
    });

    if (valid) this.submit();

});
29
adeneo

問題は、エラーが表示された場合でも、return false.each()メソッドのコールバックに影響するということです。そのため、エラーがあったとしても、

$('form').unbind('submit').submit();

フォームが送信されます。

たとえば、変数validatedを作成し、trueに設定する必要があります。次に、コールバックで、return falseの代わりにvalidated = falseを設定します。

最後に...

if (validated) $('form').unbind('submit').submit();

この方法では、エラーがない場合にのみフォームが送信されます。

13
Oscar Paz
$('form').submit(function(e){

    var submitAllow = true;

    // Cycle through each Attendee Name
    $('[name="atendeename[]"]', this).each(function(index, el){

        // If there is a value
        if ($(el).val()) {

            // Find adjacent entree input
            var entree = $(el).next('input');

            // If entree is empty, don't submit form
            if ( ! entree.val()) {
                alert('Please select an entree');
                entree.focus();
                submitAllow = false;
                return false;
            }
        }
    });

    return submitAllow;

});
6
falinsky

実際、これは正しい方法のようです:

$('form').submit(function(e){

    //prevent default
    e.preventDefault();

    //do something here

    //continue submitting
    e.currentTarget.submit();

});
5
Mike Cottier

遅れてすみませんが、完璧な形を作ろうとします:)

Count検証手順を追加し、.val()ではなく毎回確認します。 .lengthを確認してください。あなたの場合、より良いパターンだと思います。もちろんunbind関数を削除します。

私のjsFiddle

もちろんソースコード:

// Prevent form submit if any entrees are missing
$('form').submit(function(e){

    e.preventDefault();

    var formIsValid = true;

    // Count validation steps
    var validationLoop = 0;

    // Cycle through each Attendee Name
    $('[name="atendeename[]"]', this).each(function(index, el){

        // If there is a value
        if ($(el).val().length > 0) {
            validationLoop++;

            // Find adjacent entree input
            var entree = $(el).next('input');

            var entreeValue = entree.val();

            // If entree is empty, don't submit form
            if (entreeValue.length === 0) {
                alert('Please select an entree');
                entree.focus();
                formIsValid = false;
                return false;
            }

        }

    });

    if (formIsValid && validationLoop > 0) {
        alert("Correct Form");
        return true;
    } else {
        return false;
    }

});
2
d.danailov

フォーム自体よりも送信ボタンイベントをバインドしないのはなぜですか?フォーム自体よりもボタンをバインドすると、preventDefault()を使用しない限りフォームはほとんど送信されるため、本当に簡単で安全です。

$("#btn-submit").on("click", function (e) {
    var submitAllow = true;
    $('[name="atendeename[]"]', this).each(function(index, el){
        // If there is a value
        if ($(el).val()) {
            // Find adjacent entree input
            var entree = $(el).next('input');

            // If entree is empty, don't submit form
            if ( ! entree.val()) {
                alert('Please select an entree');
                entree.focus();
                submitAllow = false;
                return false;
            }
        }
    });
    if (submitAllow) {
        $("#form-attendee").submit();
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form-attendee">
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    Name: <input name="atendeename[]">
    Entree: <input name="entree[]"><br>
    <button type="button" id="btn-submit">Submit<button>
</form>
0