0

I have used jQuery Validate's handy addClassRules function to apply a rule to all elements of a given class rather than relying on the elements' name attribute values. In using the Angular wrapper of jQuery Validate, I've found that the addClassRules function is not supported out of the box. I tried modifying angular-validate.js to bring in this functionality, but no luck. The file is small, so I'll paste the whole thing, with my modification, below. Skip to the TL;DR at the end if you prefer.

angular-validate.js (with one modification)

(function (angular, $) {
    angular.module('ngValidate', [])

        .directive('ngValidate', function () {
            return {
                require: 'form',
                restrict: 'A',
                scope: {
                    ngValidate: '='
                },
                link: function (scope, element, attrs, form) {
                    var validator = element.validate(scope.ngValidate);
                    form.validate = function (options) {
                        var oldSettings = validator.settings;
                        validator.settings = $.extend(true, {}, validator.settings, options);
                        var valid = validator.form();
                        validator.settings = oldSettings; // Reset to old settings
                        return valid;
                    };
                    form.numberOfInvalids = function () {
                        return validator.numberOfInvalids();
                    };
                }
            };
        })

    .provider('$validator', function () {
        $.validator.setDefaults({
            onsubmit: false // to prevent validating twice
        });

        return {
            setDefaults: $.validator.setDefaults,
            addMethod: $.validator.addMethod,
            addClassRules: $.validator.addClassRules, /*<< this is the line I added >>*/
            setDefaultMessages: function (messages) {
                angular.extend($.validator.messages, messages);
            },
            format: $.validator.format,
            $get: function () {
                return {};
            }
        };
    });
}(angular, jQuery));

I only get an error if I actually try to invoke the addClassRules function in code. For example:

angular.module("PageModule", ['ngValidate'])
    .config(function($validatorProvider) {
        $validatorProvider.setDefaults({
            errorClass: "error custom-error-class" // this works fine
        })
        $validatorProvider.addMethod("customValidationMethod", function (value) {
                var isValid = false;
                // do stuff
                return isValid;
            }, "Bleh"
        ); // this works fine too
        $validatorProvider.addClassRules("emailField", {
            email: true
        }); // this crashes :(
    });

And the error is as follows:

Angular Validate error in Chrome JS console

Is there a way for me to use jQuery Validate's addClassRules function within its Angular implementation? What modification might I need to make? Or, is there a better way to apply validation rules to multiple elements on something other than the name attribute?

1 Answer 1

1

I have used jQuery Validate's handy addClassRules function to apply a rule to all elements of a given class ...

That's not the issue the .addClassRules() method was meant to solve. It's used for combining multiple standard rules into a single "compound" rule that can be applied using one class name.


Or, is there a better way to apply validation rules to multiple elements on something other than the name attribute?

If you simply want to apply individual rules using class names, the plugin is smart enough to pick those up and no special techniques or methods are needed.

<input type="text" class="required email" name="foo" ...

By simply using the required and email classes, you have automatically applied the required and email rules to this field.

DEMO: jsfiddle.net/70g6brcf/


Alternatively, you can use HTML5 attributes and the plugin will apply rules accordingly.

<input type="email" required="required" name="foo" ...

DEMO: jsfiddle.net/70g6brcf/1/


NOTE: These are only alternative ways to apply rules. These methods do not negate the requirement to have a name attribute, which is mandatory when using jQuery Validate.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the info, you've given me a bit to look into. As for having to have a name attribute, why do you say that? In my case, I have dozens of input elements in the same form that need the same validation. I have no need of name attributes, and I certainly don't want to duplicate names. Besides, I'm posting the form using $scope model properties, not traditional posting. I've had no problem omitting name attributes in the past, even with jQuery Validate. As for applying individual rules using class names, I'll give that a go, but I don't like how invasive that is of the CSS.
@JacobStamm, I don't recall saying it was ok to duplicate a name attribute. However, if you think you can use jQuery Validate without name attributes, try it: jsfiddle.net/zxhu17ja ~ Or just read the documentation: "Mandated: A 'name' attribute is required for all input elements needing validation, and the plugin will not work without this."
I know that I've gotten jQuery Validate to work fine without name attributes before, but you're right, the documentation is clear. I probably just got lucky in my implementation :) . About the resolution: I know the CSS classes would work fine, but I don't want accidental styles to get applied at some point, so I'm going with the data- attributes. I also got rid of my addClassRules stuff and am using my custom method, named "hours", directly, by putting data-rule-hours="true" on the elements. I also filled in some bs name values that are unique. Everything's working great :)
@JacobStamm, you're welcome and I'm glad everything is resolved for now. However, lucky or not, it's impossible that you got this plugin working without name attributes. There are over 6000 SO questions tagged with jQuery Validate and I've personally answered 25% of them... the issue has been beaten to death. Otherwise, myself and others would be very interested in how you accomplished this.
I'll take your word on that one. For all I know, my server-side HTML preprocessing was adding name attributes without me noticing on the client-side.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.