Bootstrap JQuery Validate: error message between input and <span class="add-on">

11,969

Look at the errorPlacement option in here http://docs.jquery.com/Plugins/Validation/validate#toptions

$("#myform").validate({
    errorPlacement: function(error, element) {
        element.parent().append(error);
    }
});

You can also test if there is an add-on present, change the placement of the error message, style it similarly to add on and so forth:

$("#myform").validate({
    errorPlacement: function(error, element) {
        if (element.next().is('.add-on')) {
            error.addClass('add-on').insertAfter(element.next('.add-on'));
        } else {
            error.insertAfter(element);
        }
    }
});

It would look like this:

Error Placement with add-on class

Sorry, no icon for the calendar but it's the square after the input.

Share:
11,969
JK87
Author by

JK87

ASP.NET, ReactJs, Redux, PHP, Yii2, MySQL, JQuery

Updated on June 05, 2022

Comments

  • JK87
    JK87 almost 2 years

    When using Twitter Bootstrap and Jquery Validate in a combination everything goes right except when using a field with an (icon) add-on like:

    <label>Datum:</label>
    <div id="datum" class="input-append">
       <input data-format="dd-MM-yyyy" type="text" name="datum" placeholder="Kies een datum..." />
       <span class="add-on">
          <i data-date-icon="icon-calendar"></i>
       </span>
    </div>
    

    When there is an error the HTML looks like this:

    <label>Datum:</label>
    <div id="datum" class="input-append">
       <input data-format="dd-MM-yyyy" type="text" name="datum" placeholder="Kies een datum..." />
       <label for="datum" generated="true" class="error" style="">Datum is verplicht.</label>
       <span class="add-on">
          <i data-date-icon="icon-calendar"></i>
       </span>
    </div>
    

    And this is how it looks in the browser:

    Browser example

    How to fix this? Hope someone can help!

    EDIT

    (function($,W,D)
    {
        var JQUERY4U = {};
    
        JQUERY4U.UTIL =
        {
            setupFormValidation: function()
            { onkeyup: false
                //form validation rules
    
    
                // LOGIN FORM
                $("#loginform").validate({        
                    onkeyup: false,
                     rules: {
                        gebruikersnaam: {
                            required: true           
                        },
                        wachtwoord: {
                            onkeyup: false,
                            required: true,
                            minlength: 5,
                        }
                    },
                    messages: {
                        gebruikersnaam: {
                            required: "Vul aub een gebruikersnaam in."                      
                        },
                        wachtwoord: {
                            required: "Vul aub een wachtwoord in.",
                            minlength: "Wachtwoord moet minimaal 5 tekens langs zijn.",
                        },
                    },
                    submitHandler: function(form) {
                        form.submit();
                    }
                });
    
                // NIEUWE DISTRIBUTIE OPDRACHT
    
    
        $("#distributieopdracht").validate({  
    
            onkeyup: false,
             rules: {
                opdrachtgever: {
                    required: false                
                },
                datum: {
                    required: true
                },
                frequentie: {
                    required: true
                },
                actie: {
                    required: true
                },
                product: {
                    required: false
                },
                aantal: {
                    required: false,
                    digits: true
                },
                koeling: {
                    required: true
                },
                tarief: {
                    required: false,
                    decimal: true
                },
                naam: {
                    required: false,
                    naam: true
                },
                adres: {
                    required: false
                },
                plaats: {
                    required: false
                },
                telefoonnnummer: {
                    required: false,
                    telefoon: true
                },
                opmerkingen: {
                    required: false
                },
            },
            messages: {
                datum: {
                    required: "Datum is verplicht."
                },
                frequentie: {
                    required: "Frequentie is verplicht."
                },
                actie: {
                    required: "Keuze is verplicht."
                },
                aantal: {
                    digits: "Alleen getallen."
                },
                koeling: {
                    required: "Keuze is verplicht."
                },
                tarief: {
                    decimal: "Vul een geldig tarief in."
                },
                naam: {
                    naam: "Vul een geldige naam in."
                },
                telefoonnnummer: {
                    telefoon: "Vul een geldig telefoonnummer in."
                }
            },
            submitHandler: function(form) {
                form.submit();
            }
        });
            }
        }
    
        //when the dom has loaded setup form validation rules
        $(D).ready(function($) {
            JQUERY4U.UTIL.setupFormValidation();
        });
    
    })(jQuery, window, document);
    

    EDIT

    $(document).ready(function () {
    
           $("#loginform").validate({        
            onkeyup: false,
                rules: {
                   gebruikersnaam: {
                       required: true           
                   },
                   wachtwoord: {
                    onkeyup: false,
                       required: true,
                       minlength: 5,
                   }
               },
               messages: {
                   gebruikersnaam: {
                    required: "Vul aub een gebruikersnaam in."                      
                   },
                   wachtwoord: {
                       required: "Vul aub een wachtwoord in.",
                       minlength: "Wachtwoord moet minimaal 5 tekens langs zijn.",
                   },
               },
    
           });
    
    
          $("#distributieopdracht").validate({  
                onkeyup: false,
                 rules: {
                    opdrachtgever: {
                        required: false                
                    },
                    datum: {
                        required: true
                    },
                    frequentie: {
                        required: true
                    },
                    actie: {
                        required: true
                    },
                    product: {
                        required: false
                    },
                    aantal: {
                        required: false,
                        digits: true
                    },
                    koeling: {
                        required: true
                    },
                    tarief: {
                        required: false,
                        decimal: true
                    },
                    naam: {
                        required: false,
                        naam: true
                    },
                    adres: {
                        required: false
                    },
                    plaats: {
                        required: false
                    },
                    telefoonnnummer: {
                        required: false,
                        telefoon: true
                    },
                    opmerkingen: {
                        required: false
                    },
                },
                messages: {
                    datum: {
                        required: "Datum is verplicht."
                    },
                    frequentie: {
                        required: "Frequentie is verplicht."
                    },
                    actie: {
                        required: "Keuze is verplicht."
                    },
                    aantal: {
                        digits: "Alleen getallen."
                    },
                    koeling: {
                        required: "Keuze is verplicht."
                    },
                    tarief: {
                        decimal: "Vul een geldig tarief in."
                    },
                    naam: {
                        naam: "Vul een geldige naam in."
                    },
                    telefoonnnummer: {
                        telefoon: "Vul een geldig telefoonnummer in."
                    }
                },
                errorPlacement: function(error, element) {
                    if (element.next().is('.add-on')) {
                        error.addClass('add-on').insertAfter(element.next('.add-on'));
                    } else {
                        error.insertAfter(element);
                    }
                    error.append(element.parent());
               });
        });
    
    });
    

    FORM

    <div id="distributie" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="distributieLabel" aria-hidden="true">
        <form class="modal-form" action="submit.php" data-remote="true" method="post" id="distributieopdracht">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h3 id="distributieLabel">Nieuwe Distributie Opdracht</h3>
            </div>
            <div class="modal-body">
    
                <label>Opdrachtgever:</label> 
                    <input type="text" name="opdrachtgever" placeholder="Typ hier de opdrachtgever..." /><br /> 
    
                <label>Datum:</label>
                    <div id="datum" class="input-append">
                        <input data-format="dd-MM-yyyy" type="text" name="datum" placeholder="Kies een datum..." />
                        <span class="add-on"><i data-date-icon="icon-calendar"></i></span>
                    </div>
    
                <label>Frequentie:</label> 
                    <select name="frequentie">
                        <option value="">Kies een frequentie...</option>
                        <option value="eenmalig">Eenmalig</option>
                        <option value="dagelijks">Dagelijks</option>
                        <option value="wekelijks">Wekelijks</option>
                        <option value="tweewekelijks">Twee-wekelijks</option>
                        <option value="maandelijks">Maandelijks</option>
                        <option value="jaarlijks">Jaarlijks</option>
                    </select><br /> 
    
                <label>Actie:</label>
                    <select name="actie">
                        <option value="">Kies een actie...</option>
                        <option value="ophalen">Ophalen</option>
                        <option value="afleveren">Afleveren</option>
                    </select><br /> 
    
                <label>Product:</label> 
                    <input type="text" name="product" placeholder="Typ hier een product..." /><br /> 
    
                <label>Aantal colli:</label>
                    <input type="text" name="aantal" placeholder="Typ hier het aantal..." /><br />
    
                <label>Koeling:</label> 
                    <select name="koeling">
                        <option value="">Kies een optie...</option>
                        <option value="ja">Ja</option>
                        <option value="nee">Nee</option>
                        </select><br />
    
                <label>Tarief:</label>
                    <input type="text" name="tarief" placeholder="Typ hier een tarief..." /><br />
    
                <label>Naam:</label>
                     <input type="text" name="naam" placeholder="Typ hier een naam..." /><br /> 
    
                <label>Adres:</label>
                    <input type="text" name="adres" placeholder="Typ hier het adres..." /><br />
    
                <label>Plaats:</label>
                    <input type="text" name="plaats" placeholder="Typ hier de plaats..." /><br />
    
                <label>Telefoonnummer:</label>
                    <input type="text" name="telefoonnummer" placeholder="Typ hier het telefoonnummer..." /><br />
    
                <label>Opmerkingen:</label>
                    <textarea rows="3" name="opmerkingen" placeholder="Typ hier eventuele opmerkingen..."></textarea>
        </div>
        <div class="modal-footer">
            <input type="submit" value="Invoeren" class="btn btn-primary" /> 
            <a href="#" class="btn" data-dismiss="modal">Annuleren</a>
        </div>
      </form>
    </div>
    

    EDIT

    Current situation:

    example 2

    Goal:

    example 2

    EDIT

    errorPlacement: function (error, element) {
                    if (element.next().is('.add-on')) {
                        error.insertAfter(element.next('.add-on'));
                    } else {
                        error.insertAfter(element);
                    }
                    element.parent().insertAfter(error);
                }
    

    Working solution by @jani-hyytiainen:

    errorPlacement : function(error, element) {
            if (element.next().is('.add-on')) {
                 error.insertAfter(element.parent());
            } 
            else {
                 error.insertAfter(element);
            }
    }
    
  • Dr Blowhard
    Dr Blowhard about 11 years
    that should be appendTo - element.parent() will be the surrounding div, appendTo will place the error inside that div at the end.
  • JK87
    JK87 about 11 years
    This is useful but my 'Datum' field is combined with that span element and that two elements are together in a div. The rest of the input fields are not in a div and end like </input><br />. @jani-hyytiainen
  • Jani Hyytiäinen
    Jani Hyytiäinen about 11 years
    @politus, actually I was looking for element.parent().append(error); I have fixed it in my reply and added more details too.
  • JK87
    JK87 about 11 years
    Hmm where do I have to implement that? Between $("#distributieopdracht").validate({ and onkeyup: false, ? And if possible, I would like to keep my own layout.
  • Sparky
    Sparky about 11 years
    @user2131419, organize it something like this: jsfiddle.net/R7MSq/3 ~ The listing order of the plugin options does not matter.
  • JK87
    JK87 about 11 years
    @Sparky I've edited my question again and added an updated version of my jquery code. But the code isn't working with errorPlacement part from Jani. Without it works fine. I can't see what i'm doing wrong..
  • Jani Hyytiäinen
    Jani Hyytiäinen about 11 years
    @user2131419, You are also doing both error.insertAfter(element); and error.append(element.parent()); this adds 2 error messages, I suppose you want to remove the latter one.
  • Sparky
    Sparky about 11 years
    Jani: Both versions of your errorPlacement callback function are missing the closing brace, }. When you properly indent the code within the callback function, the error is obvious. See: jsfiddle.net/R7MSq/8
  • Sparky
    Sparky about 11 years
    @user2131419, that's because there is a syntax error in Jani's code. The closing brace, }, for the errorPlacement callback function is missing. See: jsfiddle.net/R7MSq/8 You can also use the jsHint button in jsFiddle to find any syntax errors.
  • Jani Hyytiäinen
    Jani Hyytiäinen about 11 years
    @Sparky so it seems. It is fixed now.
  • Sparky
    Sparky about 11 years
    Don't forget about your first version too.
  • Jani Hyytiäinen
    Jani Hyytiäinen about 11 years
    @Sparky, Ahh that's why the error slipped... I did that one in the bus with mobile on my way home from work. Then later copied over the error on the second example :) Thanks for the heads up.
  • JK87
    JK87 about 11 years
    I've changed my code like you guys said and now it looks like the newly added image. So it's almost fixed..! But is it possible to remove that gray background behind 'Datum is verplicht' and that it looks like the other validation errors @Sparky
  • Jani Hyytiäinen
    Jani Hyytiäinen about 11 years
    Just remove the .addClass('add-on'), I only provided it as an example as I just found out that you can have multiple .add-on one after another and bootstrap will style them together. This was new for me so I thought I'd share. But you can remove it and the error message will style normally.
  • JK87
    JK87 about 11 years
    Just did that and it looks much better now. The only thing is that the 'Datum' input is within a div (and the other input fields are not) and the error will also be inserted in that div as you can see in the code in my question. I would like to float the error messages right. As shown in the last image (Goal) of my question. So the line '<label for="datum" generated="true" class="error" style="">Datum is verplicht.</label>' has to be inserted after the div.. Is that possible?
  • JK87
    JK87 about 11 years
    Can you please tell me where to put that piece of code? Or instead of which part?
  • JK87
    JK87 about 11 years
    I've edit my post. It doesn't work like this.. I'm sorry but I'm an absolutely noob at javascript..
  • Jani Hyytiäinen
    Jani Hyytiäinen about 11 years
    Try this errorPlacement: function (error, element) { if (element.next().is('.add-on')) { error.insertAfter(element.parent()); } else { error.insertAfter(element); } }
  • JK87
    JK87 about 11 years
    That worked! Thanks so much for your patience and help Jani & @Sparky! I've also learned a lot!