Bootstrap com o plug-in de validação jQuery

154

Estou tentando adicionar validação ao meu formulário com o plug-in de validação jQuery, mas estou tendo um problema em que o plug-in coloca as mensagens de erro quando estou usando grupos de entrada.

o problema

$('form').validate({
    rules: {
        firstname: {
            minlength: 3,
            maxlength: 15,
            required: true
        },
        lastname: {
            minlength: 3,
            maxlength: 15,
            required: true
        }
    },
    highlight: function(element) {
        $(element).closest('.form-group').addClass('has-error');
    },
    unhighlight: function(element) {
        $(element).closest('.form-group').removeClass('has-error');
    }
});

Meu código: http://jsfiddle.net/hTPY7/4/

Miguel Borges
fonte
Herdou um aplicativo com o Bootstrap 3, riu que eu tinha encontrado isso e o havia marcado há alguns anos atrás quando herdei um aplicativo com o Bootstrap 3.
Adrian J. Moreno

Respostas:

347

para total compatibilidade com o twitter bootstrap 3, preciso substituir alguns métodos de plugins:

// override jquery validate plugin defaults
$.validator.setDefaults({
    highlight: function(element) {
        $(element).closest('.form-group').addClass('has-error');
    },
    unhighlight: function(element) {
        $(element).closest('.form-group').removeClass('has-error');
    },
    errorElement: 'span',
    errorClass: 'help-block',
    errorPlacement: function(error, element) {
        if(element.parent('.input-group').length) {
            error.insertAfter(element.parent());
        } else {
            error.insertAfter(element);
        }
    }
});

Veja o exemplo: http://jsfiddle.net/mapb_1990/hTPY7/7/

Miguel Borges
fonte
1
Muito bom, só queria mencionar para adicionar $ (elemento) .removeClass (errorClass); destacar e $ (elemento) .addClass (errorClass); de destaque se você deseja sucesso a não usar a classe de bootstrap ajuda-block
Jay Rizzi
3
Isso funciona bem, exceto por uma coisa: Testar o jQuery Validate 1.11.1 e chamar resetForm()o validador de um formulário não unhighlightinvocará elementos inválidos, tornando necessário remover a has-errorclasse manualmente ao redefinir um formulário. O que faço é chamar a seguinte função, em vez de chamar resetForm()diretamente o validador :function resetForm(form_id) { $(form_id).find(".form-group").removeClass("has-error"); $(form_id).data('validator').resetForm(); }
Adrian Lopez
Eu não sei por que o código não está funcionando no meu formulário :(
Alyssa Reyes
Por golly funciona como um encanto! Muito obrigado !!! Você me salvou potencialmente uma ou duas horas de pesquisa.
racl101
1
Se você tiver botões de opção como o Bootstrap sugere (entradas de rádio colocadas dentro de etiquetas), convém adicionar algo assim ao bloco se:else if (element.prop('type') === 'radio') { error.insertBefore(element.parent().parent()); }
Elliot Cameron
86

Para total compatibilidade com o Bootstrap 3, adicionei suporte ao grupo de entrada , rádio e caixa de seleção que estavam faltando nas outras soluções.

Atualização 20/10/2017 : sugestões inspecionadas das outras respostas e suporte adicional adicionado para marcação especial de rádio em linha , melhor posicionamento de erro para um grupo de rádios ou caixas de seleção e suporte adicional para uma classe .novalidation personalizada para impedir a validação de controles. Espero que isso ajude e obrigado pelas sugestões.

Após incluir o plug-in de validação, adicione a seguinte chamada:

$.validator.setDefaults({
    errorElement: "span",
    errorClass: "help-block",
    highlight: function (element, errorClass, validClass) {
        // Only validation controls
        if (!$(element).hasClass('novalidation')) {
            $(element).closest('.form-group').removeClass('has-success').addClass('has-error');
        }
    },
    unhighlight: function (element, errorClass, validClass) {
        // Only validation controls
        if (!$(element).hasClass('novalidation')) {
            $(element).closest('.form-group').removeClass('has-error').addClass('has-success');
        }
    },
    errorPlacement: function (error, element) {
        if (element.parent('.input-group').length) {
            error.insertAfter(element.parent());
        }
        else if (element.prop('type') === 'radio' && element.parent('.radio-inline').length) {
            error.insertAfter(element.parent().parent());
        }
        else if (element.prop('type') === 'checkbox' || element.prop('type') === 'radio') {
            error.appendTo(element.parent().parent());
        }
        else {
            error.insertAfter(element);
        }
    }
});

Isso funciona para todas as classes de formulário do Bootstrap 3. Se você usar um formulário horizontal, precisará usar a seguinte marcação. Isso garante que o texto do bloco de ajuda respeite os estados de validação ("has-error", ...) do grupo de formulários .

<div class="form-group">
    <div class="col-lg-12">
        <div class="checkbox">
            <label id="LabelConfirm" for="CheckBoxConfirm">
                <input type="checkbox" name="CheckBoxConfirm" id="CheckBoxConfirm" required="required" />
                I have read all the information 
            </label>
        </div>
    </div>
</div>
Andreas Krohn
fonte
1
Eu agitei errorClass: "help-block error-help-block". Eu já estava usando o .help-block para obter informações regulares de ajuda, e isso foi substituído por mensagens de validação de formulário. A adição de uma segunda classe a tornou única e, agora, ela acrescenta e não sobrescreve minha mensagem de ajuda "real".
23915 Scott Stafford
Método Hilight não chamado
Vlado Pandžić
Olá Vlado, você poderia dar mais informações sobre por que isso não funciona para você?
Andreas Krohn
Para um grupo de botões de opção, isso adicionará a mensagem de erro abaixo da primeira opção que parece estranha. Você provavelmente deseja ajustar isso para tratar os botões de opção de maneira diferente.
Elliot Cameron
Muito obrigado Senhor @AndreasKrohn ^ _ ^ #
Jeancarlo Fontalvo
23

Uso formulários projetados apenas com o Twitter Bootstrap 3. Defino funções padrão para o validor e executo apenas o método de validação com regras. Eu uso ícones do FontAweSome, mas você pode usar Glyphicons como no exemplo do documento.

insira a descrição da imagem aqui

jQuery.validator.setDefaults({
    highlight: function (element, errorClass, validClass) {
        if (element.type === "radio") {
            this.findByName(element.name).addClass(errorClass).removeClass(validClass);
        } else {
            $(element).closest('.form-group').removeClass('has-success has-feedback').addClass('has-error has-feedback');
            $(element).closest('.form-group').find('i.fa').remove();
            $(element).closest('.form-group').append('<i class="fa fa-exclamation fa-lg form-control-feedback"></i>');
        }
    },
    unhighlight: function (element, errorClass, validClass) {
        if (element.type === "radio") {
            this.findByName(element.name).removeClass(errorClass).addClass(validClass);
        } else {
            $(element).closest('.form-group').removeClass('has-error has-feedback').addClass('has-success has-feedback');
            $(element).closest('.form-group').find('i.fa').remove();
            $(element).closest('.form-group').append('<i class="fa fa-check fa-lg form-control-feedback"></i>');
        }
    }
});

Feito. Após a execução, valide a função:

$("#default-register-user").validate({
    rules: {
        'login': {
            required: true,
            minlength: 5,
            maxlength: 20
        },
        'email': {
            required: true,
            email: true,
            minlength: 5,
            maxlength: 100
        },
        'password': {
            required: true,
            minlength: 6,
            maxlength: 25
        },
        'confirmpassword': {
            required: true,
            minlength: 5,
            maxlength: 25,
            equalTo: "#password"
        }
    }
});

Exemplo JSFiddle

DARK_DIESEL
fonte
1
Seria ótimo ter um jsFiddle para este
kofifus
Você poderia postar o HTML usado para a captura de tela, por favor? O exemplo do violino não tem a mensagem de erro em estilo vermelho nem os ícones. Obrigado!
Christopher Francisco
Christopher Francisco, atualizei o exemplo do JSFiddle e adicionei a fonte awesome css.
DARK_DIESEL
Oi ótima solução! Como você editaria isso para que apenas os campos que possuem regras mostrem mensagens de sucesso ou falha? Direita seu código faz todos os campos exibir o css, independentemente se existem regras ou não
Michael Smith
A solução é adicionar: 'ignore: ".ignore,: hidden"' logo acima das regras. Em seguida, basta adicionar uma classe de 'ignorar' para todos os campos que você não quer validado
Michael Smith
10

Ao adicionar a resposta de Miguel Borges acima, você pode dar ao usuário esse feedback de sucesso, adicionando a seguinte linha no bloco de código de destaque / falta de destaque.

    highlight: function(element) {
        $(element).closest('.form-group').removeClass('has-success').addClass('has-error');
    },
    unhighlight: function(element) {
        $(element).closest('.form-group').removeClass('has-error').addClass('has-success');
    }
Jose Apollo
fonte
8

esta é a solução que você precisa, você pode usar o errorPlacementmétodo para substituir onde colocar a mensagem de erro

$('form').validate({
    rules: {
        firstname: {
            minlength: 3,
            maxlength: 15,
            required: true
        },
        lastname: {
            minlength: 3,
            maxlength: 15,
            required: true
        }
    },
    errorPlacement: function(error, element) {
        error.insertAfter('.form-group'); //So i putted it after the .form-group so it will not include to your append/prepend group.
    }, 
    highlight: function(element) {
        $(element).closest('.form-group').addClass('has-error');
    },
    unhighlight: function(element) {
        $(element).closest('.form-group').removeClass('has-error');
    }
});

funciona para mim como mágica. Felicidades

Drixson Oseña
fonte
error.insertAfter('.form-group');coloque erros em todos os .form-group. mas me mostrou a ideia. obrigado
Miguel Borges
5

para bootstrap 4 este trabalho comigo bom

    $.validator.setDefaults({
    highlight: function(element) {
        $(element).closest('.form-group').find(".form-control:first").addClass('is-invalid');
    },
    unhighlight: function(element) {
        $(element).closest('.form-group').find(".form-control:first").removeClass('is-invalid');
        $(element).closest('.form-group').find(".form-control:first").addClass('is-valid');

    },
    errorElement: 'span',
    errorClass: 'invalid-feedback',
    errorPlacement: function(error, element) {
        if(element.parent('.input-group').length) {
            error.insertAfter(element.parent());
        } else {
            error.insertAfter(element);
        }
    }
});

espero que ajude!

Jehad Ahmad Jaghoub
fonte
Isso funciona muito bem! A única coisa que adicionei foivalidClass: 'valid-feedback'
Simon Zyx 21/10/19
Obrigado, isso funcionou para mim no Bootstrap 4 com validClass: 'valid-feedback'.
Zaki Mohammed
4

Aqui está o que eu uso ao adicionar validação ao formulário:

// Adding validation to form.
        $(form).validate({
            rules: {
                title: {
                    required: true,
                    minlength: 3,
                },
                server: {
                    ipAddress: true,
                    required: true
                }   
            },
            highlight: function(element) {
                $(element).closest('.form-group').removeClass('has-success').addClass('has-error');
            },
            success: function(element) {
                $(element).closest('.form-group').removeClass('has-error').addClass('has-success');
            },
            errorClass: 'help-block'
        });

Isso funcionou para mim no estilo do Bootstrap 3 ao usar a biblioteca de validação jquery.

Edwin Perez
fonte
3

Eu usei isso para o rádio:

    if (element.prop("type") === "checkbox" || element.prop("type") === "radio") {
        error.appendTo(element.parent().parent());
    }
    else if (element.parent(".input-group").length) {
        error.insertAfter(element.parent());
    }
    else {
        error.insertAfter(element);
    }

desta forma, o erro é exibido na última opção de rádio.

Marcel Overdijk
fonte
Resposta brilhantemente simples, obrigado - apenas inseri a cláusula de tipo extra na minha lógica errorPlacement existente
theotherdy
3

Eu sei que esta pergunta é para o Bootstrap 3, mas como algumas perguntas relacionadas ao Bootstrap 4 são redirecionadas para esta como duplicatas, aqui está o snippet compatível com o Bootstrap 4:

$.validator.setDefaults({
    highlight: function(element) {
        $(element).closest('.form-group').addClass('has-danger');
    },
    unhighlight: function(element) {
        $(element).closest('.form-group').removeClass('has-danger');
    },
    errorElement: 'small',
    errorClass: 'form-control-feedback d-block',
    errorPlacement: function(error, element) {
        if(element.parent('.input-group').length) {
            error.insertAfter(element.parent());
        } else if(element.prop('type') === 'checkbox') {
            error.appendTo(element.parent().parent().parent());
        } else if(element.prop('type') === 'radio') {
            error.appendTo(element.parent().parent().parent());
        } else {
            error.insertAfter(element);
        }
    },
});

As poucas diferenças são:

  • O uso da classe em has-dangervez dehas-error
  • Melhores rádios e caixas de seleção para posicionamento de erros
martpie
fonte
O Bootstrap 4 não possui mais as .has-*classes. getbootstrap.com/docs/4.3/migration/#forms-1
Fred
2

Para o bootstrap 4 beta houve algumas grandes mudanças entre as versões alfa e beta do bootstrap (e também o bootstrap 3), esp. em relação à validação de formulário.

Primeiro, para colocar os ícones corretamente, você precisará adicionar um estilo que equivale ao que estava no bootstrap 3 e não no bootstrap 4 beta ... aqui está o que estou usando

.fa.valid-feedback,
.fa.invalid-feedback {
    position: absolute;
    right: 25px;
    margin-top: -50px;
    z-index: 2;
    display: block;
    pointer-events: none;
}

.fa.valid-feedback {
    margin-top: -28px;
}

As classes também foram alteradas, pois a versão beta usa o 'estado' do controle em vez das classes que o seu código postado não reflete, portanto, o código acima pode não funcionar. De qualquer forma, você precisará adicionar a classe 'foi validada' ao formulário nos retornos bem-sucedidos ou realçados / não realçados

$(element).closest('form').addClass('was-validated');

Eu também recomendaria usar o novo elemento e classes para o texto de ajuda do controle de formulário

errorElement: 'small',
errorClass: 'form-text invalid-feedback',
user2030404
fonte
1

Isso compõe os campos

 $("#form_questionario").validate({
                debug: false,
                errorElement: "span",
                errorClass: "help-block",
                highlight: function (element, errorClass, validClass) {
                    $(element).closest('.form-group').addClass('has-error');
                },
                unhighlight: function (element, errorClass, validClass) {
                    $(element).closest('.form-group').removeClass('has-error');
                },
                errorPlacement: function (error, element) {
                    if (element.parent('.input-group').length || element.prop('type') === 'checkbox' || element.prop('type') === 'radio') {
                        error.insertBefore(element.parent());
                    } else {
                        error.insertAfter(element);
                    }
                },
                // Specify the validation rules
                rules: {
                        'campo1[]': 'required',
                        'campo2[]': 'required',
                        'campo3[]': 'required',
                        'campo4[]': 'required',
                        'campo5[]': 'required'
                        },

                submitHandler: function (form) {
                    form.submit();
                }
            });
gilcierweb
fonte
1

adicione a correção radio-inline a este https://stackoverflow.com/a/18754780/966181

$.validator.setDefaults({
    highlight: function(element) {
        $(element).closest('.form-group').addClass('has-error');
    },
    unhighlight: function(element) {
        $(element).closest('.form-group').removeClass('has-error');
    },
    errorElement: 'span',
    errorClass: 'help-block',
    errorPlacement: function(error, element) {
        if(element.parent('.input-group').length) {
            error.insertAfter(element.parent());
        } else if (element.parent('.radio-inline').length) {
            error.insertAfter(element.parent().parent());
        } else {
            error.insertAfter(element);
        }
    }
});
bl4ckb1rd
fonte
É simples, é muito útil. Obrigado.
Chofoteddy
0

A resposta de DARK_DIESEL funcionou muito bem para mim; aqui está o código para quem quer o equivalente usando glyphicons:

jQuery.validator.setDefaults({
    highlight: function (element, errorClass, validClass) {
        if (element.type === "radio") {
            this.findByName(element.name).addClass(errorClass).removeClass(validClass);
        } else {
            $(element).closest('.form-group').removeClass('has-success has-feedback').addClass('has-error has-feedback');
            $(element).closest('.form-group').find('span.glyphicon').remove();
            $(element).closest('.form-group').append('<span class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>');
        }
    },
    unhighlight: function (element, errorClass, validClass) {
        if (element.type === "radio") {
            this.findByName(element.name).removeClass(errorClass).addClass(validClass);
        } else {
            $(element).closest('.form-group').removeClass('has-error has-feedback').addClass('has-success has-feedback');
            $(element).closest('.form-group').find('span.glyphicon').remove();
            $(element).closest('.form-group').append('<span class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>');
        }
    }
});
jamshehan
fonte
0

Tente usar este código de exemplo. Usando o plug-in de validação do Jquery e métodos adicionais. Este é o código de trabalho para o meu projeto. Espero que isso ajude você

//jquery validation booking page
	
	// Wait for the DOM to be ready
$(function() {
  // Initialize form validation on the registration form.
  // It has the name attribute "registration"
  $("form[name='book']").validate({
	  //on key up validation
	  onkeyup: function(element) {
      $(element).valid(); 
    },  
    // Specify validation rules
    rules: {
      // The key name on the left side is the name attribute
      // of an input field. Validation rules are defined
      // on the right side
      fname: {
        required: true,
        lettersonly: true
        },
      lname:{
        required: true,
        lettersonly: true
        },
      email: {
        required: true,
        // Specify that email should be validated
        // by the built-in "email" rule
        email: true
      },
      password: {
        required: true,
        minlength: 5
      }
    },
    // Specify validation error messages
    messages: {
      fname: {
      required:"Please enter your firstname",
      lettersonly:"Letters allowed only"
      },
      lname: {
      required:"Please enter your lastname",
      lettersonly:"Letters allowed only"
      },
      email: "Please enter a valid email address"
    },
    // Make sure the form is submitted to the destination defined
    // in the "action" attribute of the form when valid
    submitHandler: function(form) {
      form.submit();
    }
  });
});
.error {
  color: red;
  margin-left: 5px;
  font-size:15px;
}
<script src="design/bootstrap-3.3.7-dist/js/jquery.validate.js"></script>
<script src="design/bootstrap-3.3.7-dist/js/additional-methods.js"></script>

<form name="book" id="book" action="" method="post">

    <div class="row form-group">
        <div class="col-md-6 ">
            <label class="" for="fname">First Name</label>
            <input type="text" name="fname" id="fname" class="form-control" placeholder="First Name">
        </div>
        <div class="col-md-6">
            <label class="" for="lname">Last Name</label>
            <input type="text" name="lname" id="lname" class="form-control" placeholder="Last Name">
        </div>
    </div>

    <div class="row form-group">
        <div class="col-md-6 ">
            <label class="" for="date">Date</label>
            <input type="text" id="date" class="form-control datepicker px-2" placeholder="Date of visit">
        </div>
        <div class="col-md-6">
            <label class="" for="email">Email</label>
            <input type="email" name="email" id="email" class="form-control" placeholder="Email">
        </div>
    </div>

    <div class="row form-group">
        <div class="col-md-12">
            <label class="" for="treatment">Service You Want</label>
            <select name="treatment" id="treatment" class="form-control">
                <option value="">Hair Cut</option>
                <option value="">Hair Coloring</option>
                <option value="">Perms and Curls</option>
                <option value="">Hair Conditioning</option>
                <option value="">Manicure</option>
                <option value="">Pedicure</option>
                <option value="">Nails Extension</option>
                <option value="">Nail Design</option>
                <option value="">Waxing Eyebrows</option>
                <option value="">Waxing Hands/Legs</option>
                <option value="">Full Face Waxing</option>
                <option value="">Full Body/Body Parts Wax</option>
            </select>
        </div>
    </div>

    <div class="row form-group">
        <div class="col-md-12">
            <label class="" for="note">Notes</label>
            <textarea name="note" id="note" cols="30" rows="5" class="form-control" placeholder="Write your notes or questions here..."></textarea>
        </div>
    </div>

    <div class="row form-group">
        <div class="col-md-12">
            <center><input type="submit" value="Book Now" class="btn btn-primary btn-lg"></center>
        </div>
    </div>

</form>

Abhishek Yadav
fonte
-1

Outra opção é colocar um contêiner de erro fora do seu grupo de formulários antes do tempo. O validador irá usá-lo, se necessário.

<div class="form-group">
  <label class="control-label" for="new-task-due-date">When is the task due?</label>
  <div class="input-group date datepicker">
    <input type="text" id="new-task-due-date" class="required form-control date" name="dueDate" />
    <span class="input-group-addon">
      <span class="glyphicon glyphicon-calendar"></span>
    </span>                          
  </div>
  <label for="new-task-due-date" class="has-error control-label" style="display: none;"></label>
</div>
Neve12ende12
fonte