1

I have a front end reg form saving profiles via ajax. All user and profile data is getting stored ok. The problem comes with validation.

It seems Craft likes to load the errors for certain fields first:

{% macro errorList(errors) %}

So the above fills the error array with username, title and email before processing the others. In ajax am getting the errors like:

function appendErrors(errors) {

$.each(errors, function(field, errors) {
    appendError(field, errors);
});
}

function appendError(field, errors) {
var $errorList = $( '<ul class="errors" />' );

$.each(errors, function(index, error) {
    $errorList.append($('<li>').html(error));
    console.log(error);
});

$("input[name=" + field + "]").after($errorList);
}

I'd like to show all the errors to the user at once on page for sensible UX reasons. So quick brain check - is Craft really doing this? If so, then I see my options like:

  1. Could switch to a pure jQuery/js validation
  2. Could try and manipulate the error array and reindex based on tabindex?
  3. Could try overriding Craft's validation thru plugin

Has anyone else come at this in earnest?

  • Is your form calling UsersController->actionSaveUser()? Are you running Craft Pro and the latest version of Craft? UsersService->saveUser() validates the UserRecord first, then any custom fields/content and only then will return false with all errors attached to the UserModel. github.com/pixelandtonic/Craft-Release/blob/master/app/services/… – Brad Bell Apr 12 '17 at 18:13
  • Craft Pro latest on local dev machine, calling <input type="hidden" name="action" value="users/saveUser"> The on screen errors always come for the core user fields first which i understand - makes sure we have a user first right:) But the other errors won't display onscreen. In the console i am spitting out the error append & can see all the extra userfields set to required with error messages. Two issues here a) nothing hits the screen b) there is no rational order to the errors array - ie they don't reflect the order of required fields when looped thru - so can't smooth scroll to them – joomkit Apr 13 '17 at 7:57
  • I changed my error javascript to use field names as classes too and targeted the error output at them. Bingo $('input[name='+ field +']').after($errorList); doesnt seem to work consistently - possible jquery /browser quirk. So used $("." + field).after($errorList); and now all errors are on page at once - apart from – joomkit Apr 13 '17 at 10:34
  • Ahh, sounds like you're sorted, then? If so, would you mind adding what worked for you as an official answer? – Brad Bell Apr 13 '17 at 18:13
0

So the solution for me in the end was to add the profile field name as a class name eg 'address1';

 <input id="address1" name="fields[address1]" type="text" 
placeholder="address line 1" class="form-control input-md address1" req="">

Then in my ajax post when looping through the errors looking for the element class name

$("." + field).after($errorList);

as opposed to the input field name.

$.post('/', data, function(response) {

    //reset error messages
    $(this).find( '.errors' ).remove();

    if (response.success) {
        console.log("success")
    } else {
        event.preventDefault();
        console.log(response.errors);
        //reset errors
        $('.submit').append('<span class="err">Please check the form for errors</span>');
        appendErrors(response.errors);
    }

});

function appendErrors(errors) {

$.each(errors, function(field, errors) {
    appendError(field, errors);
});
}

function appendError(field, errors) {
   var $errorList = $( '<ul class="errors">' );
   $.each(errors, function(index, error) {
     $errorList.append($('<li>').html(error));
   });
   $("." + field).after($errorList);
   // $('input[name='+ field +']').after($errorList);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.