If an element is valid, I want its label to be hidden, so that it doesn't take up space. Currently, this seems to be impossible.
My first attempt was to use the success option to set a CSS class with display: none;. My second was, within the success callback, to explicitly call hide().
Both of those fail because the success callback is called in the middle of defaultShowErrors, which ends by doing this: this.addWrapper( this.toShow ).show();. So in all cases, the label is shown.
My final attempt was to use the showErrors callback to do something like this:
showErrors: function(errorMap, errorList) {
this.defaultShowErrors();
// after the label is shown, hide it again
But this won't work, because if the element is valid, neither errorMap nor errorList contains a reference to find the element and the label again.
As a workaround, I modified the plugin myself as follows: at the end of defaultShowErrors, I checked a custom setting and re-hid the error.
var error = this.addWrapper( this.toShow ).show();
if( !this.errorList.length && this.settings.hideLabelOnSuccess) {
error.hide();
}
_Is there a better way to do this?_ If not, is this a sensible modification to contribute back? It doesn't seem ideal to add another setting, but this is the best solution I have so far.
(The "shouldn't take up space requirement is my input is inside a table cell as part of a grid of calculations, and I'm putting the error message directly underneat the input inside the cell.)
On the one hand its sounds like you're talking about the regular label, on the other, based on the code, it sounds like you're talking about the error-label. Both don't make a lot of sense to me: There shouldn't be a reason to hide the regular label, while the error-label gets hidden once the field is valid.
Therefore, without seeing your actual code, I suspect that you've got something going wrong, causing the error-labels not to get hidden.
J枚rn,
Sorry for any confusion, and thanks for responding. I'm trying to ensure that, after an invalid input is corrected, the error label gets hidden. This is the default behavior, but I'm trying to use a success callback, which breaks that.
If I use no custom callbacks, each input's error label is hidden when the input becomes valid, just like I wanted.
However, if I use any success callback, even an empty one:
success: function(label) {
// do nothing
}
... it prevents the label from being hidden. (The same thing happens if I provide a label class, like success: "foo".)
If my success callback explicitly calls label.hide(), that doesn't matter, because it will be shown again.
If it calls label.remove(), that works fine; it just seems a little bit wrong, since that's not how you do it by default. Is there a better way?
My reason for using the callback at all is that my form has fieldsets which are collapsible, so each fieldset has a graphical indicator to show whether it contains errors or not, so the user can open it up and find them. To update that indicator, I use a custom event trigger.
I want to fire this event after any input is validated, whether it passes or fails. The fieldset will then count how many errors there are within it and set its indicator. The only way I can see to do this is to fire the event both in showErrors and in my success callback. If you know a better way to do that, too, I'd love to hear about it.
Here is my actual rule set, currently:
validationRules = {
errorPlacement: function(error, element) {
error.appendTo(element.closest('li,td')); // parent could be either
},
onsubmit: false,
ignoreTitle: true,
// Runs when an input is valid
success: function(label) {
label.addClass('valid').closest('fieldset').trigger('inputRevalidated');
label.remove();
},
// Actually runs on each validation, whether or not there are errors. However,
// if there are none, we have no element from which to find the closest fieldset.
// See success callback for that case.
// Note: if success runs, it runs BEFORE showErrors.
showErrors: function(errorMap, errorList) {
this.defaultShowErrors();
if (errorList.length > 0) {
$(errorList[0].element).closest('fieldset').trigger('inputRevalidated');
}
}
};
Thanks for looking into this with me.
--Nathan
The success-option is a poor mess. I guess at the very least it needs to check if options.success is a string, before calling showLabel(successList). Seems like that could fix your usecase. If so, could you provide a patch for that? If possible along with a test.
In the long run, the whole thing needs to be redesigned.
I've read through this ticket again. Looks like removing the label, as wrong as that may be, works for you. I don't see a way to bugfix this. What's really needed is a better API for handling the error display. I'm tracking that in #657.
Just wanted to point out 6 years later and now I am also trying to solve this problem.
i think this will help for you.
success: function (element) {
$(element).closest('.form-group').removeClass('has-error');
element.remove();
}
Most helpful comment
Just wanted to point out 6 years later and now I am also trying to solve this problem.