Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Validate #198

Merged
merged 8 commits into from

3 participants

@ProLoser
Owner

WIP! Do not merge yet!

Yes I know I'm doing a lot of these. I'm thinking we should use this version instead of validexp

ProLoser added some commits
@ProLoser ProLoser Rewrote ui-validate to have support for ui-validate-watch
The tests have not been updated yet to reflect the new syntax
0fd2b9c
@ProLoser ProLoser Updated syntax on old specs and stubbed new ones
I'm starting to wonder if perhaps we should make uiValidateWatch a separate directive with lower priority?
9cd1f5e
@ProLoser
Owner

For some reason attrs.uiValidateWatch is undefined. Any ideas? I'm guessing that either the syntax for ui-item-whatever doesn't work like we'd expect OR it matches ui-validate-watch AS ui-validate. Plunker will soon follow...

@ProLoser
Owner

http://plnkr.co/edit/OZqGmo?p=preview
So first set min to 2 and max to 4. This works fine, adjusting max also works fine. However the ui-validate-watch is not being set.

If you debug inside of app.js you will see that attrs.uiValidateWatch is undefined even if the element contains the necessary attribute. Any ideas what's going on?

@petebacondarwin
@ProLoser
Owner
@ProLoser
Owner
@petebacondarwin
@ProLoser ProLoser Fixed uiValidateWatch
For some reason I can't checkout this branch locally.

Everything seems to work now, just need unit tests and peer review.

This has a breaking API change, you now must wrap expressions in strings.
This is to allow 2-step parsing. Once for the object of validators, and again to validate.
93d5400
@ProLoser
Owner
@ProLoser
Owner

Correction, this was a bug on my part. I had 2 inputs with the same model. I just identified a strange behavior with angularjs validation. So all that's left is fleshing out the demo and the unit tests.

@petebacondarwin

Hi Dean
I am still not happy with forcing people to use strings in the simple case. Can't we ditch scope.$eval and use something like $parse instead?
Pete

Owner
Owner
ProLoser added some commits
@ProLoser ProLoser Merge branch 'master' into validate
* master: (59 commits)
  Changed select2 directive to use $.trim()
  v0.3.1 polkadot-thunderstorm-sexypants
  Update package.json
  Rebuilding for fixes to the improper merge
  Removed bootstrap code that accidentally weasled it's way into the codebase
  Pushing v0.3.0
  Prevented scope bleeding on ui-reset
  Modified @blackbarn changes to uiReset
  Removed mask dependencies path temporarily
  Trying to get async unit tests working for tinymce
  Fixed keypress ability to handle multiple alternative combinations
  Added build versions of new shiv
  added doc to top
  first iteration of new statically defined tags for ieshiv:q:qs
  Stubbed out some more of select2 unit tests
  modal: sets focus on element with autofocus attribute when modal is shown
  Added a check to prevent recursive $digest in TinyMCE
  Fixed up the date (and tests) to deal with invalid dates
  Adding tests for false and undefined
  Added graceful degredation to uiDateFormat when the values are falsy
  ...
8377f18
@ProLoser ProLoser Trying to flesh out validate specs (need help) 4a36147
@ProLoser ProLoser Merge branch 'validate' of git://github.com/angular-ui/angular-ui int…
…o validate

* 'validate' of git://github.com/angular-ui/angular-ui:
  Fixed uiValidateWatch
e043464
@ProLoser
Owner

Can anyone help me with these unit tests? I'm not sure about how to go about doing em. If you even comment on the commits I can make the changes myself.

@ProLoser
Owner

FINALLY ready for review/merging. Can someone give me the OK to merge this?

@ProLoser ProLoser Update modules/directives/validate/validate.js
Using $modelValue instead of $viewValue for ui-validate-watch
6156a90
@ProLoser
Owner

@joseym can you review this PR for me?

@ProLoser ProLoser merged commit 2bcfc57 into from
@ProLoser ProLoser deleted the branch
@joseym
Owner

@ProLoser Sorry, spent the last few days handling a data disaster... I'm good now

@ProLoser
Owner

@joseym HE LIVES!!!

@joseym
Owner

I'm not sure I'd go that far but I am here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 12, 2012
  1. @ProLoser

    Rewrote ui-validate to have support for ui-validate-watch

    ProLoser authored
    The tests have not been updated yet to reflect the new syntax
  2. @ProLoser

    Updated syntax on old specs and stubbed new ones

    ProLoser authored
    I'm starting to wonder if perhaps we should make uiValidateWatch a separate directive with lower priority?
Commits on Nov 3, 2012
  1. @ProLoser

    Fixed uiValidateWatch

    ProLoser authored
    For some reason I can't checkout this branch locally.
    
    Everything seems to work now, just need unit tests and peer review.
    
    This has a breaking API change, you now must wrap expressions in strings.
    This is to allow 2-step parsing. Once for the object of validators, and again to validate.
Commits on Nov 5, 2012
  1. @ProLoser

    Merge branch 'master' into validate

    ProLoser authored
    * master: (59 commits)
      Changed select2 directive to use $.trim()
      v0.3.1 polkadot-thunderstorm-sexypants
      Update package.json
      Rebuilding for fixes to the improper merge
      Removed bootstrap code that accidentally weasled it's way into the codebase
      Pushing v0.3.0
      Prevented scope bleeding on ui-reset
      Modified @blackbarn changes to uiReset
      Removed mask dependencies path temporarily
      Trying to get async unit tests working for tinymce
      Fixed keypress ability to handle multiple alternative combinations
      Added build versions of new shiv
      added doc to top
      first iteration of new statically defined tags for ieshiv:q:qs
      Stubbed out some more of select2 unit tests
      modal: sets focus on element with autofocus attribute when modal is shown
      Added a check to prevent recursive $digest in TinyMCE
      Fixed up the date (and tests) to deal with invalid dates
      Adding tests for false and undefined
      Added graceful degredation to uiDateFormat when the values are falsy
      ...
Commits on Nov 8, 2012
  1. @ProLoser
  2. @ProLoser

    Merge branch 'validate' of git://github.com/angular-ui/angular-ui int…

    ProLoser authored
    …o validate
    
    * 'validate' of git://github.com/angular-ui/angular-ui:
      Fixed uiValidateWatch
Commits on Nov 13, 2012
  1. @ProLoser

    Fixed the unit tests

    ProLoser authored
Commits on Jan 8, 2013
  1. @ProLoser

    Update modules/directives/validate/validate.js

    ProLoser authored
    Using $modelValue instead of $viewValue for ui-validate-watch
This page is out of date. Refresh to see the latest.
View
67 modules/directives/validate/test/validateSpec.js
@@ -33,7 +33,7 @@ describe('uiValidate', function ($compile) {
it('should mark input as valid if initial model is valid', inject(function () {
scope.validate = trueValidator;
- compileAndDigest('<input name="input" ng-model="value" ui-validate="validate">', scope);
+ compileAndDigest('<input name="input" ng-model="value" ui-validate="\'validate($value)\'">', scope);
expect(scope.form.input.$valid).toBeTruthy();
expect(scope.form.input.$error).toEqual({validator: false});
}));
@@ -41,7 +41,7 @@ describe('uiValidate', function ($compile) {
it('should mark input as invalid if initial model is invalid', inject(function () {
scope.validate = falseValidator;
- compileAndDigest('<input name="input" ng-model="value" ui-validate="validate">', scope);
+ compileAndDigest('<input name="input" ng-model="value" ui-validate="\'validate($value)\'">', scope);
expect(scope.form.input.$valid).toBeFalsy();
expect(scope.form.input.$error).toEqual({ validator: true });
}));
@@ -53,7 +53,7 @@ describe('uiValidate', function ($compile) {
scope.value = false;
scope.validate = passedValueValidator;
- compileAndDigest('<input name="input" ng-model="value" ui-validate="validate">', scope);
+ compileAndDigest('<input name="input" ng-model="value" ui-validate="\'validate($value)\'">', scope);
expect(scope.form.input.$valid).toBeFalsy();
scope.$apply('value = true');
@@ -72,7 +72,7 @@ describe('uiValidate', function ($compile) {
scope.value = false;
scope.validate = passedValueValidator;
- var inputElm = compileAndDigest('<input name="input" ng-model="value" ui-validate="validate">', scope);
+ var inputElm = compileAndDigest('<input name="input" ng-model="value" ui-validate="\'validate($value)\'">', scope);
expect(scope.form.input.$valid).toBeFalsy();
inputElm.val('true');
@@ -89,17 +89,72 @@ describe('uiValidate', function ($compile) {
scope.validate1 = trueValidator;
scope.validate2 = falseValidator;
- compileAndDigest('<input name="input" ng-model="value" ui-validate="{key1 : validate1, key2 : validate2}">', scope);
+ compileAndDigest('<input name="input" ng-model="value" ui-validate="{key1 : \'validate1($value)\', key2 : \'validate2($value)\'}">', scope);
expect(scope.form.input.$valid).toBeFalsy();
expect(scope.form.input.$error.key1).toBeFalsy();
expect(scope.form.input.$error.key2).toBeTruthy();
});
});
+ describe('uiValidateWatch', function(){
+ function validateWatch(watchMe) {
+ return watchMe;
+ };
+
+ beforeEach(function(){
+ scope.validateWatch = validateWatch;
+ });
+
+ it('should watch the string and refire the single validator', function () {
+ scope.watchMe = false;
+ compileAndDigest('<input name="input" ng-model="value" ui-validate="\'validateWatch(watchMe)\'" ui-validate-watch="\'watchMe\'">', scope);
+ expect(scope.form.input.$valid).toBe(false);
+ expect(scope.form.input.$error.validator).toBe(true);
+ scope.$apply('watchMe=true');
+ expect(scope.form.input.$valid).toBe(true);
+ expect(scope.form.input.$error.validator).toBe(false);
+ });
+
+ it('should watch the string and refire all validators', function () {
+ scope.watchMe = false;
+ compileAndDigest('<input name="input" ng-model="value" ui-validate="{foo:\'validateWatch(watchMe)\',bar:\'validateWatch(watchMe)\'}" ui-validate-watch="\'watchMe\'">', scope);
+ expect(scope.form.input.$valid).toBe(false);
+ expect(scope.form.input.$error.foo).toBe(true);
+ expect(scope.form.input.$error.bar).toBe(true);
+ scope.$apply('watchMe=true');
+ expect(scope.form.input.$valid).toBe(true);
+ expect(scope.form.input.$error.foo).toBe(false);
+ expect(scope.form.input.$error.bar).toBe(false);
+ });
+
+ it('should watch the all object attributes and each respective validator', function () {
+ scope.watchFoo = false;
+ scope.watchBar = false;
+ compileAndDigest('<input name="input" ng-model="value" ui-validate="{foo:\'validateWatch(watchFoo)\',bar:\'validateWatch(watchBar)\'}" ui-validate-watch="{foo:\'watchFoo\',bar:\'watchBar\'}">', scope);
+ expect(scope.form.input.$valid).toBe(false);
+ expect(scope.form.input.$error.foo).toBe(true);
+ expect(scope.form.input.$error.bar).toBe(true);
+ scope.$apply('watchFoo=true');
+ expect(scope.form.input.$valid).toBe(false);
+ expect(scope.form.input.$error.foo).toBe(false);
+ expect(scope.form.input.$error.bar).toBe(true);
+ scope.$apply('watchBar=true');
+ scope.$apply('watchFoo=false');
+ expect(scope.form.input.$valid).toBe(false);
+ expect(scope.form.input.$error.foo).toBe(true);
+ expect(scope.form.input.$error.bar).toBe(false);
+ scope.$apply('watchFoo=true');
+ expect(scope.form.input.$valid).toBe(true);
+ expect(scope.form.input.$error.foo).toBe(false);
+ expect(scope.form.input.$error.bar).toBe(false);
+ });
+
+ });
+
describe('error cases', function () {
it('should fail if ngModel not present', inject(function () {
expect(function () {
- compileAndDigest('<input name="input" ui-validate="validate">', scope);
+ compileAndDigest('<input name="input" ui-validate="\'validate($value)\'">', scope);
}).toThrow(new Error('No controller: ngModel'));
}));
it('should have no effect if validate expression is empty', inject(function () {
View
42 modules/directives/validate/validate.js
@@ -5,8 +5,10 @@
* The ui-validate directive makes it easy to use any function(s) defined in scope as a validator function(s).
* A validator function will trigger validation on both model and input changes.
*
- * @example <input ui-validate="myValidatorFunction">
- * @example <input ui-validate="{foo : validateFoo, bar : validateBar}">
+ * @example <input ui-validate=" 'myValidatorFunction($value)' ">
+ * @example <input ui-validate="{ foo : '$value > anotherModel', bar : 'validateFoo($value)' }">
+ * @example <input ui-validate="{ foo : '$value > anotherModel' }" ui-validate-watch=" 'anotherModel' ">
+ * @example <input ui-validate="{ foo : '$value > anotherModel', bar : 'validateFoo($value)' }" ui-validate-watch=" { foo : 'anotherModel' } ">
*
* @param ui-validate {string|object literal} If strings is passed it should be a scope's function to be used as a validator.
* If an object literal is passed a key denotes a validation error key while a value should be a validator function.
@@ -18,21 +20,18 @@ angular.module('ui.directives').directive('uiValidate', function () {
restrict: 'A',
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
+ var validateFn, watch, validators = {},
+ validateExpr = scope.$eval(attrs.uiValidate);
- var validateFn, validateExpr = attrs.uiValidate;
+ if (!validateExpr) return;
- validateExpr = scope.$eval(validateExpr);
- if (!validateExpr) {
- return;
- }
-
- if (angular.isFunction(validateExpr)) {
+ if (angular.isString(validateExpr)) {
validateExpr = { validator: validateExpr };
}
- angular.forEach(validateExpr, function (validatorFn, key) {
+ angular.forEach(validateExpr, function (expression, key) {
validateFn = function (valueToValidate) {
- if (validatorFn(valueToValidate)) {
+ if (scope.$eval(expression, { '$value' : valueToValidate })) {
ctrl.$setValidity(key, true);
return valueToValidate;
} else {
@@ -40,9 +39,28 @@ angular.module('ui.directives').directive('uiValidate', function () {
return undefined;
}
};
+ validators[key] = validateFn;
ctrl.$formatters.push(validateFn);
ctrl.$parsers.push(validateFn);
});
+
+ // Support for ui-validate-watch
+ if (attrs.uiValidateWatch) {
+ watch = scope.$eval(attrs.uiValidateWatch);
+ if (angular.isString(watch)) {
+ scope.$watch(watch, function(){
+ angular.forEach(validators, function(validatorFn, key){
+ validatorFn(ctrl.$modelValue);
+ });
+ });
+ } else {
+ angular.forEach(watch, function(expression, key){
+ scope.$watch(expression, function(){
+ validators[key](ctrl.$modelValue);
+ });
+ });
+ }
+ }
}
};
-});
+});
Something went wrong with that request. Please try again.