Parsley.js - Display errors near fields AND in a combined list above form

試著忘記壹切 提交于 2019-12-04 13:35:02

问题


  1. Is it possible to configure Parsley.js to display its error messages both... a) next to individual fields, AND b) in a combined list elsewhere on the page ...at the same time?

  2. Also, is it possible to render error messages with a hyperlink back to the field that generated the error?

Thanks.


UPDATE:

The accepted answer is a fantastic example (thanks milz!) but it needed a bit more refining.

For the benefit of other readers, here's my updated code in which...

  1. Error messages no longer duplicate after failing first validation (in original example, try generating an error then repeatedly pressing backspace in a field - a new message is added to the list for every keystroke)

  2. Error message take the text of the LABEL in the same form-group (handy for radios and checkboxes which don't have individual labels that are meaningful)

  3. Error messages are removed from the list on the fly when they're fixed by the user.

  4. Entire error panel has a title, and is hidden/shown depending on whether it has content or not.

  5. Bootstrap styling, layout & parsley config provided.

In response to Adrian Rodriguez' question about displaying the messages ABOVE the fields, you can change the location of Parsley's default error messages with the following 2 steps:

// A. CHANGE the 'errorsContainer' callback to...

    errorsContainer: function(el) {
      return el.$element.closest(".control").find(".top"); // Errors will be placed inside the 'div.control > div.top' elements.
    }

// B. Additionally, you will either need to manually add '<div class='top'></div>'
//    wherever you want the errors to appear. Alternatively, use a little
//    JQuery to add these elements to the whole form, as follows...

    // 1.5 PREPEND each .control div with a new container for errors
    $(".control").prepend("<div class='top'></div>");

    // 2. Parslify the form...
    etc.

// 1. Configure Parsley for Bootstrap 3 Forms
//
window.ParsleyConfig = {
  successClass: "has-success",
  errorClass: "has-error",
  classHandler: function(el) {
    return el.$element.closest(".form-group");
  },
  errorsContainer: function(el) {
    return el.$element.closest(".control");
  },
  errorsWrapper: "<span class='help-block parsley-messages'></span>",
  errorTemplate: "<span></span>"
};


// 2. Parslify the form...
$("#theForm").parsley();


// 3. Configure Parsley to display combined validation-errors-list
//
$(function() {


  // Convenience members
  $.validationErrors = {

    container: $('div.validation-errors-container'),

    list: $('div.validation-errors-container ul.validation-errors-list'),

    updateContainer: function() {
      // Hide/show container if list is empty/full
      $.validationErrors.container.toggleClass("filled", $.validationErrors.list.find("li:first").length > 0);
    },

    removeItem: function(sFieldName) {
      // Remove related error messages from list
      $.validationErrors.list.find('li[data-related-field-name="' + sFieldName + '"]').remove();
    }

  };



  // NB: Event names pertain to Parsley V2.0  


  // Before each validation, clear the validation-errors of the div
  $.listen('parsley:form:validate', function() {
    $.validationErrors.list.html();
  });

  // When a field has an error
  $.listen('parsley:field:error', function(fieldInstance) {

    var fieldName = fieldInstance.$element.attr('name');

    $.validationErrors.removeItem(fieldName);

    // Get the error messages
    var messages = ParsleyUI.getErrorsMessages(fieldInstance);

    // Loop through all the messages
    for (var i in messages) {
      // Create a message for each error
      var fieldLabel = fieldInstance.$element.closest(".form-group").find("label:first");
      var fieldLabelText = fieldLabel.clone().children().remove().end().text().trim();
      var fieldName = fieldInstance.$element.attr("name");
      var $m = $('<li data-related-field-name="' + fieldName + '"><a data-related-field-name="' + fieldName + '" href="#na"><strong>' + fieldLabelText + '</strong> - ' + messages[i] + '</a></li>');
      $.validationErrors.list.append($m);
    }
    $.validationErrors.updateContainer();

  });

  $.listen('parsley:field:success', function(fieldInstance) {
    $.validationErrors.removeItem(fieldInstance.$element.attr('name'));
    $.validationErrors.updateContainer();
  });

  // When there's a click on a error message from the div
  $(document).on('click', 'a[data-related-field-name]', function() {

    // take the field's name from the attribute
    var name = $(this).attr('data-related-field-name');
    $("[name=" + name + "]:first").focus();

  });

});
body {
  padding: 10px;
}
/* PARSLEY FORM VALIDATION */

/* ensure field-spans injected by parsley don't take up space when empty... */

.parsley-messages {
  display: none;
}
.parsley-messages.filled {
  display: block;
}
/* aggregated parsley error message display... */

div.validation-errors-container {
  display: none;
}
div.validation-errors-container.filled {
  display: block;
}
div.validation-errors-container ul.validation-errors-list {
  margin: 0;
  padding: 0;
}
div.validation-errors-container ul.validation-errors-list li {
  color: rgb(169, 68, 66);
  list-style: outside none disc;
  margin-left: 16px;
  padding-left: 1em;
  text-indent: -0.7em;
}
div.validation-errors-container ul.validation-errors-list li a {
  color: inherit;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parsley.js/2.0.7/parsley.min.js"></script>

<!-- VALIDATION ERRORS CONTAINER -->

<div class="validation-errors-container panel panel-danger" role="alert" aria-labelledby="validation-errors-heading" aria-live="assertive">
  <div class="panel-heading" id="validation-errors-heading"><strong>Alert!</strong> Please correct the following errors...</div>
  <div class="panel-body">
    <ul class="validation-errors-list"></ul>
  </div>
</div>


<!-- BOOTSTRAP 3 FORM -->
<form class="form-horizontal" id="theForm">

  <div class="form-group">
    <label class="control-label col-xs-2">
      Name <span class="required-indicator" title="Required">*</span>
    </label>
    <div class="control col-xs-10">
      <input type="text" name="userName" class="form-control" data-parsley-required="true">
    </div>
  </div>

  <div class="form-group">
    <label class="control-label col-xs-2">
      Gender <span class="required-indicator" title="Required">*</span>
    </label>
    <div class="control col-xs-10">
      <label class="checkbox-inline">
        <input type="radio" data-parsley-required="true" name="gender" value="F" />Girl
      </label>
      <label class="checkbox-inline">
        <input type="radio" name="gender" value="M" />Boy
      </label>
    </div>
  </div>

  <div class="form-group">
    <label class="control-label col-xs-2">
      Email <span class="required-indicator" title="Required">*</span>
    </label>
    <div class="control col-xs-10">
      <input type="text" name="userEmail" class="form-control" data-parsley-type="email" data-parsley-required="true">
    </div>
  </div>


  <button type="submit" class="btn btn-primary">Submit</button>

</form>

回答1:


To accomplish what you want, you need to use Parsley's events. Take a look at the event's description and the comments on the below code.

<div class="validation-errors"></div>
<form>
    <input type="text" name="field1" required />
    <input type="text" name="field2" required />
    <input type="submit" />
</form>

<script>
    $(document).ready(function() {
        // validate form
        $("form").parsley();

        // Before each validation, clear the validation-errors of the div
        $.listen('parsley:form:validate', function() {
            $('.validation-errors').html('');
        });

        // When a field has an error
        $.listen('parsley:field:error', function(fieldInstance){
            // Get the error messages
            var messages = ParsleyUI.getErrorsMessages(fieldInstance);

            // Get the field's name
            var fieldName = fieldInstance.$element.attr('name');

            // Loop through all the messages
            for (var i in messages) {
                // Create a message for each error
                var $m = $('<p><a class="focus-' + fieldName + '" href="#">' + fieldName + ': ' + messages[i] + '</a><p>');

                // Append the errors to the div
                $('.validation-errors').append($m);
            }
        });        
    });

    // When there's a click on a error message from the div
    $(document).on('click', 'a[class^="focus-"]', function(){
        // take the field's name from the class
        var parts = $(this).attr('class').split('-');

        $("[name=" + parts[1] + "]").focus();
    });
</script>

Here's a demo in Jsfiddle.

Important note: the code I'm providing uses the events available in Parsley 2.0.* . If you're using the newly Parsley 2.1.*, you should use the correct events. Instead of parsley:form:validate use form:validate and replace parsley:field:error by field:error.



来源:https://stackoverflow.com/questions/31173916/parsley-js-display-errors-near-fields-and-in-a-combined-list-above-form

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