jQueryvalidation с Bootstrap 4 - правильное размещение значков для флажков / групп радио - PullRequest
0 голосов
/ 02 ноября 2018

Я создаю пример формы, используя bootstrap 4 и jqueryvalidation.js.

Я использую font-awesome 5 free icon "fas fa-exclamation-triangle" рядом с сообщениями об ошибках под каждым входом. Я изменил errorElement на span.

когда вход действителен, родительский класс div изменяется с "недопустим" на "верен" и значок "fa-check" заменяет "fa-exclamation-triangle" , за исключением того, что с флажками и радиовходами класс остается как "is-invalid" . Это приводит к тому, что значок «fa-exclamation-point» продолжает отображаться, когда я хочу, чтобы значок «fa-check» отображался.

Пожалуйста, сообщите ...

Вот мой HTML

<form id="form2" method="post" action="" novalidate="nonvalidate">
    <div class="row">
        <div class="col-md-4 mb-3">
            <div class="form-group">
                <label for="textField">Text field</label>
                <input type="text" id="textField" class="form-control" name="textField" placeholder="Can use any characters">
            </div>
        </div>
        <div class="col-md-4 offset-md-2">
            <div class="form-group">
                <label for="numberField">Number field (+/-)</label>
                <input type="number" id="numberField" class="form-control" name="numberField" placeholder="Numbers only">
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-4 mb-3">
            <div class="form-group">
                <label for="emailField">Email field</label>
                <input type="email" id="emailField" class="form-control" name="emailField" placeholder="Valid email address">
            </div>
        </div>
        <div class="col-md-4 offset-md-2">
            <div class="form-group">
                <label for="passwordField">Password field</label>
                <input type="password" id="passwordField" class="form-control" name="passwordField">
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-4 mb-3">
            <div class="form-group">
                <label for="dateField">Date field (uses the HTML5 datepicker by default)</label>
                <input type="date" id="dateField" class="form-control" name="dateField">
            </div>
        </div>
        <div class="col-md-4 offset-md-2">
            <div class="form-group">
                <label for="urlField">URL field</label>
                <input type="url" id="urlField" class="form-control" name="urlField" value="http://">
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-4 mb-3">
            <div class="form-group">
                <label for="selectField">Select field</label>
                <select id="selectField" class="form-control" name="selectField">
                    <option value="">Choose...</option>
                    <option value="1">One</option>
                    <option value="2">Two</option>
                    <option value="3">Three</option>
                </select>
            </div>
        </div>
        <div class="col-md-4 offset-md-2">
            <div class="form-group">
                <label for="selectMultipleField">Select multiple field</label>
                <select id="selectMultipleField" class="form-control" name="selectMultipleField" size="3" multiple>
                    <option value="1">One</option>
                    <option value="2">Two</option>
                    <option value="3">Three</option>
                    <option value="4">Four</option>
                    <option value="5">Five</option>
                </select>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-4 mb-3">
            <div class="form-group">
                <label for="textareaField">Textarea</label>
                <textarea id="textareaField" class="form-control" name="textareaField" rows="3" placeholder="Type here..."></textarea>
            </div>
        </div>
        <div class="col-md-4 offset-md-2">
            <div class="form-group">
                <label for="fileUploadField">File</label>
                <div class="custom-file">
                    <input type="file" id="fileUploadField" class="custom-file-input" name="fileUploadField">
                    <label class="custom-file-label">Choose file</label>
                </div>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-2 mb-3">
            <label class="checkboxSingle">Checkbox (single)</label>
            <div class="form-group">
                <div class="form-check">
                    <input type="checkbox" id="checkboxSingle" class="form-check-input" name="checkboxSingle">
                    <label class="form-check-label" for="checkbox">Checkbox</label>
                </div>
            </div>
        </div>
        <div class="col-md-2 mb-3">
            <fieldset>
                <legend>Checkbox group</legend>
                <div class="form-group">
                    <div class="form-check">
                        <input type="checkbox" id="checkboxGroup1" class="form-check-input" name="checkboxGroup">
                        <label class="form-check-label" for="checkboxGroup1">Checkbox</label>
                    </div>
                    <div class="form-check">
                        <input type="checkbox" id="checkboxGroup2" class="form-check-input" name="checkboxGroup">
                        <label class="form-check-label" for="checkboxGroup2">Checkbox</label>
                    </div>
                    <div class="form-check">
                        <input type="checkbox" id="checkboxGroup3" class="form-check-input" name="checkboxGroup">
                        <label class="form-check-label" for="checkboxGroup3">Checkbox</label>
                    </div>
                </div>
            </fieldset>
        </div>
        <div class="col-md-2 offset-md-2">
            <fieldset>
                <legend>Radio group</legend>
                <div class="form-group">
                    <div class="form-check">
                        <input type="radio" id="radioGroup1" class="form-check-input" name="radioGroup">
                        <label class="form-check-label" for="radio1">Radio 1</label>
                    </div>
                    <div class="form-check">
                        <input type="radio" id="radioGroup2" class="form-check-input" name="radioGroup">
                        <label class="form-check-label" for="radio2">Radio 2</label>
                    </div>
                    <div class="form-check">
                        <input type="radio" id="radioGroup3" class="form-check-input" name="radioGroup">
                        <label class="form-check-label" for="radio3">Radio 3</label>
                    </div>
                </div>
            </fieldset>
        </div>
    </div>
    <hr />
    <div class="row">
        <div class="col-md-4 offset-md-4 mb-3 text-center">
            <button type="submit" class="btn btn-primary" name="form2Submit" value="Submit form">Submit form</button>
            <button type="reset" class="btn btn-light">Reset form</button>
        </div>
    </div>
</form>

CSS

form {
    legend {
        font-size: initial;
    }

    .is-invalid {

        .form-control {
            border-color: $red !important;
        }

        .form-control:focus {
            box-shadow: 0 0 0 0.2rem rgba(220,53,69,.25), 0 0 6px $red;
            -webkit-box-shadow: 0 0 0 0.2rem rgba(220,53,69,.25), 0 0 6px $red;
        }

        .form-control-feedback {
            margin-right: 0.25rem;
        }

        .fa-exclamation-triangle:before {
            color: $red;
        }

        .form-control-feedback { // Default position of success icon inside input element.
            // position: absolute;
            // top: 2.75rem;
            // right: 1.5rem;
        }

        .help-block {
            color: $red;
            font-style: italic;
        }
    }

    .is-valid {
        .form-control {
            border-color: $green;
        }

        .form-control:focus {
            box-shadow: 0 0 0 0.2rem rgba(40,167,69,.25), 0 0 6px $green;
            -webkit-box-shadow: 0 0 0 0.2rem rgba(40,167,69,.25), 0 0 6px $green;
        }

        .fa-check:before {
            color: $green;
        }

        .form-control-feedback { // Default position of success icon inside input element.
            position: absolute;
            top: 2.75rem;
            right: 1.5rem;
        }
    }
}

Javascript

jQuery.validator.setDefaults({
    debug: true,
    submitHandler: function() {
        alert("Success!  The form has been submitted.");
    }
});

$(document).ready(function() {
    $("#form2").validate({
        rules: {
            textField: "required",
            numberField: "required",
            emailField: {
                required: true,
                email: true
            },
            passwordField: {
                required: true,
                minlength: 8
            },
            dateField: "required",
            urlField: {
                required: true,
                url: true,
                normalizer: function(value) {
                    var url = value;

                    // Check if it doesn't start with http:// or https:// or ftp://
                    if (url && url.substr(0, 7) !== "http://" &&
                        url.substr(0, 8) !== "https://" &&
                        url.substr(0, 6) !== "ftp://") {
                        // then prefix with http://
                        url = "http://" + url;
                    }

                    // Return the new url
                    return url;
                }
            },
            selectField: "required",
            selectMultipleField: "required",
            textareaField: "required",
            fileUploadField: "required",
            checkboxSingle: "required",
            checkboxGroup: "required",
            radioGroup: "required"
        },
        messages: {
            textField: "Please add some text.",
            numberField: "Please enter a number.",
            emailField: "Please enter a valid email.",
            passwordField: {
                required: "Please provide a password.",
                minlength: "Password must be at least 8 characters."
            },
            dateField: "Please select a date.",
            urlField: "Please enter a valid URL.",
            selectField: "Please select an option",
            selectMultipleField: "Please select at least one option.",
            textareaField: "Please enter some text.",
            fileUploadField: "Please select a file to upload.",
            checkboxSingle: "Please check the box.",
            checkboxGroup: "Please check at least one box.",
            radioGroup: "Please select one."
        },
        errorElement: "em",

        // Replaces default .has-error class with Bootstrap 4 .is-valid class
        errorClass: "is-invalid",
        // Replaces default .has-succes class with Bootstrap 4 .is-valid class
        validClass: "is-valid",

        errorPlacement: function(error, element) {
            //Add the `help-block` class to the error element
            error.addClass("help-block");
            //
            // Add `has-feedback` class to the parent div.form-group
            // in order to add icons to inputs
            element.parents(".form-group").addClass("has-feedback");

            // Add error
            if (element.prop("type") === "checkbox" || element.prop("type") === "radio") {
                // If checkbox/radio append after parent div.
                //This prevents error from displaying after first element of checkbox/radio group.
                $("<span class='form-control-feedback fas fa-exclamation-triangle'></span>").appendTo(element.parents(".form-group"));
                error.appendTo(element.parents(".form-group"));
            } else {
                $("<span class='form-control-feedback fas fa-exclamation-triangle'></span>").insertAfter(element);
                error.insertAfter(element.next("span"));
            }
        },
        success: function(element) {
            // if ($(element).closest(".is-valid")) {
            //     $(".form-control-feedback").removeClass(errorClass).addClass(validClass);
            // }
        },
        highlight: function(element, errorClass, validClass) {
            $(element).closest(".form-group").addClass(errorClass).removeClass(validClass);

        },
        unhighlight: function(element, errorClass, validClass) {
            $(element).closest(".form-group").removeClass(errorClass).addClass(validClass);
            $(element).next("span").addClass("fa-check").removeClass("fa-exclamation-triangle");
        }
    });
});
...