Parsley.js - display errors next to AND fields in the combined list above the form

  1. Can Parsley.js be configured to display its error messages as ... a) next to individual fields, AND b) in a combo box elsewhere on the page ... at the same time?

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

Thank you.


UPDATE:

The accepted answer is a fantastic example (thanks milz!) But needs a bit of work.

For the convenience of other readers, here is my updated code where ...

  1. Error messages are no longer duplicated after a failed first check (in the original example, try to generate an error and then press the Backspace key in the field again - a new message is added to the list for each key press)

  2. The error message takes LABEL text in the same form group (handy for radios and checkboxes that don't have separate meaningful labels)

  3. Error messages are removed from the list on the fly when corrected by the user.

  4. The entire error bar has a title and is hidden / shown depending on whether it has content or not.

  5. Bootstrap style, layout and parsley config are provided.

In response to Adrian Rodriguez's question about displaying messages above fields, you can change the default location of Parsley error messages by following these 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 a click on a error message from the div
  $(document).on('click', 'a[data-related-field-name]', function() {

    // take the field 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>
      

Run codeHide result


+4


source to share


1 answer


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

<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 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 a click on a error message from the div
    $(document).on('click', 'a[class^="focus-"]', function(){
        // take the field name from the class
        var parts = $(this).attr('class').split('-');

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

      



Here's a demo at Jsfiddle .

Important note : the code I provide uses events available in Parsley 2.0. *. If you are using the newer Parsley 2.1. *, You must use the correct events. parsley:form:validate

Use instead form:validate

and replace parsley:field:error

with field:error

.

+3


source







All Articles