Bootstrap 3 validation states with JQuery-validated form that uses Chosen plugin

∥☆過路亽.° 提交于 2019-12-11 03:06:37

问题


The context

  • I have a form that I'm validating using JQuery Validate Plugin.
  • All form controls are required except for the textarea.
  • I'm using Bootstrap 3 validation states to style the form controls being validated.
  • For the select control, I'm using the Chosen Select Plugin

The problem

I'm having trouble figuring out how to address the following:

1- Prevent the textarea control from being applied the success validation state since this form control is not being validated as it is optional.

(To reproduce the problem in the JSFiddle below, click the Submit button with the empty form)

2- Apply the error validation state to the border of the dropdown list. Right now only the label gets the error validation state applied.

3 - Remove the error validation state and error message, and apply the success class when the user chooses an option from the dropdown list. Right now the error message and error class remain.

A JSFiddle

I created a JSFiddle to illustrate the problems.

The HTML

<div class="container" role="main">
    <!-- Contents of the popover associated with the task name text input -->
    <div id="namePopoverContent" class="hide">
        <ul>
            <li><small>...</small></li>
            <li><small>...</small></li>
        </ul>
    </div>

    <form class="form-horizontal" method="post" action="" id="taskForm">
        <div class="row">
            <div class="col-md-9">
                <div class="form-group">
                    <label for="taskName" class="control-label col-md-1">Name</label>
                    <div class="col-md-11">
                        <input type="text" class="form-control taskNameValidation" id="taskName" name="taskName" autofocus required data-toggle="popover">
                    </div>
                </div>
            </div>
            <div class="col-md-3"></div>
        </div>

        <div class="row">
            <div class="col-md-9">
                <div class="form-group">
                    <label for="taskDataset" class="col-md-1 control-label">Dataset</label>
                    <div class="col-md-11">
                        <select class="form-control chosen-select taskDatasetValidation" data-placeholder="Choose a dataset" name="taskDataset" id="taskDataset" required>
                            <option value=""></option>
                            <option value="runnableDataset_Id1">Dataset 1</option>
                            <option value="runnableDataset_Id2">Dataset 2</option>
                            <option value="runnableDataset_Id3">Dataset 3</option>
                            <option value="runnableDataset_Id4">Dataset 4</option>
                        </select>
                    </div>
                </div>
            </div>
            <div class="col-md-3"></div>
        </div>
        <div class="row">
            <div class="col-md-9">
                <div class="form-group">
                    <label for="taskDescription" class="col-md-1 control-label">Description</label>
                    <div class="col-md-11">
                        <textarea class="form-control" name="taskDescription" id="taskDescription" maxlength="1000" rows="4"></textarea>
                    </div>
                </div>
            </div>
            <div class="col-md-3"></div>
        </div>
        <div class="row">
            <div class="col-md-9">
                <div class="pull-right top-margin">
                    <input type="submit" class="btn btn-primary btn-sm" value="Submit" name="taskSetUpSubmit">
                </div>
            </div>
            <div class="col-md-3"></div>
        </div>
    </form>

The JS

//Bootstrap popover
$('[data-toggle="popover"]').popover({ 
    trigger: "hover focus",
    container: "body",
    placement: "bottom",
    html: true,
    title: "Name Tips",
    content: function() { return $('#namePopoverContent').html();}
});

//Chosen select plugin
$(function() {
    $('.chosen-select').chosen();
    $('.chosen-select-deselect').chosen({ allow_single_deselect: true });
});

//JQuery validate plugin
$(function() {
    $.validator.setDefaults({
        errorClass: 'text-danger',
        ignore: ':hidden:not(.chosen-select)',
        errorPlacement: function (error, element) {
            if (element.hasClass('chosen-select'))
                error.insertAfter(element.siblings(".chosen-container"));
            else {
                error.insertAfter(element);
            }
        }
    });

    //rules and messages objects
    $("#taskForm").validate({
        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');
        }
    });

    $('.taskNameValidation').each(function() {
        $(this).rules('add', {
            required: true,
            messages: {
                required: "Provide a space-separated name"
            }
        });
    });

    $('.taskDatasetValidation').each(function() {
        $(this).rules('add', {
            required: true,
            messages: {
                required: "Choose a dataset"
            }
        });
    });
});

I've been struggling with this without any luck. Any help will be greatly appreciated.


回答1:


  1. Prevent the textarea control from being applied the success validation state since this form control is not being validated as it is optional.

    The empty textarea is "valid" because your validation says an empty field is valid, therefore it's green. You could conditionally use highlight and unhighlight so that it will not be applied to your textarea. However, then it will not work when your maxlength rule is evaluated. I know of no workaround that will cause unhighlight to get ignored when the field is technically "valid" and yet still empty. There is no "optional" condition/state provided in this plugin... once the form is evaluated, fields are either "valid" or "invalid", nothing in between.

    EDIT: You can conditionally apply highlight and unhighlight on the textarea using the custom :blank selector and applying a class to this "optional" element. Then you'll still get the red & green outlines, but only when this "optional" field is filled out and/or your rules are evaluated.

    highlight: function (element) {
        if (! ($(element).hasClass('optional') && $(element).is(':blank'))) {
            $(element).closest('.form-group').removeClass('has-success').addClass('has-error');
        }
    },
    unhighlight: function (element) {
        if (! ($(element).hasClass('optional') && $(element).is(':blank'))) {
            $(element).closest('.form-group').removeClass('has-error').addClass('has-success');
        }
    }
    
  2. Apply the error validation state to the border of the dropdown list. Right now only the label gets the error validation state applied.

    You need to look at the rendered DOM and find the dynamically created Chosen element. Then you need to write jQuery to traverse over to this element and conditionally apply the appropriate classes via highlight and unhighlight.

    highlight: function (element) {
        if ($(element).hasClass('chosen-select')) {
            $(element).siblings('.chosen-container').removeClass('has-success').addClass('has-error');
        }
        $(element).closest('.form-group').removeClass('has-success').addClass('has-error');
    },
    unhighlight: function (element) {
       if ($(element).hasClass('chosen-select')) {
           $(element).siblings('.chosen-container').removeClass('has-error').addClass('has-success');
       } 
       $(element).closest('.form-group').removeClass('has-error').addClass('has-success');
    }
    

    This code above is applying the has-error and has-success classes to the rendered Chosen div element; you just need to adjust your CSS so that there is a red border. Otherwise, write your own CSS classes for this like I did in the demo below. Adjust accordingly.

  3. Remove the error validation state and error message, and apply the success class when the user chooses an option from the dropdown list.

    You must write a change handler that calls the .valid() method on the select element every time it changes. This is because you are interacting with the rendered select list and not the actual select element. Otherwise, the jQuery Validate plugin is not properly triggered.

    $('.chosen-select').on('change', function () {
        $(this).valid();
    });
    

DEMO: https://jsfiddle.net/jxvqsodz/7/



来源:https://stackoverflow.com/questions/30548059/bootstrap-3-validation-states-with-jquery-validated-form-that-uses-chosen-plugin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!