Merge "Provide 'validatable-with' directive"
This commit is contained in:
commit
f0023b100f
@ -559,7 +559,12 @@
|
||||
'index': 0,
|
||||
'panelIndex': 0,
|
||||
'row': 0
|
||||
}
|
||||
},
|
||||
'@constraints': [
|
||||
function(value) {
|
||||
return value !== 'workbook1' ? true : 'The sample validation failure.';
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
'description': {
|
||||
|
@ -112,6 +112,36 @@
|
||||
}
|
||||
}
|
||||
})
|
||||
.directive('validatableWith', function($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: 'ngModel',
|
||||
link: function(scope, element, attrs, ctrl) {
|
||||
var model;
|
||||
if ( attrs.validatableWith ) {
|
||||
model = $parse(attrs.validatableWith)(scope);
|
||||
scope.error = '';
|
||||
model.setValidatable && model.setValidatable(true);
|
||||
model.on && model.on('validation', function(result) {
|
||||
var isValid = (result == 'succeeded'),
|
||||
baseMessage = '';
|
||||
// (FIXME): hack until Barricade supports validation of empty required entries
|
||||
if ( !model.get() && model.isRequired() ) {
|
||||
isValid = false;
|
||||
baseMessage = 'This field is required.'
|
||||
}
|
||||
ctrl.$setValidity('barricade', isValid);
|
||||
scope.error = model.hasError() ? model.getError() : baseMessage;
|
||||
});
|
||||
ctrl.$formatters.push(function(modelValue) {
|
||||
return modelValue === undefined ?
|
||||
( ctrl.$isEmpty(ctrl.$viewValue) ? undefined : ctrl.$viewValue ) :
|
||||
modelValue;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.directive('typedField', ['$compile', 'merlin.templates',
|
||||
function($compile, templates) {
|
||||
function updateAutoCompletionDirective(template) {
|
||||
|
@ -32,11 +32,18 @@
|
||||
});
|
||||
|
||||
var modelMixin = Barricade.Blueprint.create(function(type) {
|
||||
var isValid = true,
|
||||
isValidatable = false;
|
||||
this.value = function() {
|
||||
if ( !arguments.length ) {
|
||||
return this.get();
|
||||
if ( isValidatable ) {
|
||||
return isValid ? this.get() : undefined;
|
||||
} else {
|
||||
return this.get();
|
||||
}
|
||||
} else {
|
||||
this.set(arguments[0]);
|
||||
isValid = !this.hasError();
|
||||
}
|
||||
};
|
||||
this.id = utils.getNewId();
|
||||
@ -45,6 +52,10 @@
|
||||
return type;
|
||||
};
|
||||
|
||||
this.setValidatable = function(validatable) {
|
||||
isValidatable = validatable;
|
||||
};
|
||||
|
||||
this.setType = function(_type) {
|
||||
type = _type;
|
||||
};
|
||||
|
@ -54,8 +54,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
editable .fa-pencil {
|
||||
color: black;
|
||||
editable {
|
||||
.fa-pencil {
|
||||
color: black;
|
||||
}
|
||||
button:disabled {
|
||||
color: gray;
|
||||
}
|
||||
}
|
||||
|
||||
.section {
|
||||
|
@ -5,6 +5,6 @@
|
||||
</span>
|
||||
<span ng-show="isEdited">
|
||||
<input type="text" ng-model="editableValue" show-focus="isEdited">
|
||||
<button ng-click="accept()"><i class="fa fa-check"></i></button>
|
||||
<button ng-click="accept()" ng-disabled="!editableValue"><i class="fa fa-check"></i></button>
|
||||
<button ng-click="reject()"><i class="fa fa-close"></i></button>
|
||||
</span>
|
||||
|
@ -3,5 +3,6 @@
|
||||
<label for="elem-{$ $id $}">{$ value.title() $}</label>
|
||||
<input type="number" class="form-control" id="elem-{$ $id $}"
|
||||
ng-model="value.value" ng-model-options="{ getterSetter: true }"
|
||||
autocompletable="true">
|
||||
autocompletable="true" validatable-with="value">
|
||||
<div ng-show="error" class="alert alert-danger">{$ error $}</div>
|
||||
</div>
|
||||
|
@ -2,5 +2,6 @@
|
||||
<label for="elem-{$ $id $}">{$ value.title() $}</label>
|
||||
<input type="text" class="form-control" id="elem-{$ $id $}"
|
||||
ng-model="value.value" ng-model-options="{ getterSetter: true }"
|
||||
autocompletable="true">
|
||||
autocompletable="true" validatable-with="value">
|
||||
<div ng-show="error" class="alert alert-danger">{$ error $}</div>
|
||||
</div>
|
||||
|
@ -2,5 +2,6 @@
|
||||
<label for="elem-{$ $id $}">{$ value.title() $}</label>
|
||||
<textarea class="form-control" id="elem-{$ $id $}"
|
||||
ng-model="value.value" ng-model-options="{ getterSetter: true }"
|
||||
autocompletable="true"></textarea>
|
||||
autocompletable="true" validatable-with="value"></textarea>
|
||||
<div ng-show="error" class="alert alert-danger">{$ error $}</div>
|
||||
</div>
|
||||
|
@ -347,4 +347,83 @@ describe('merlin directives', function() {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("'validatable'", function() {
|
||||
var fields;
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
fields = $injector.get('merlin.field.models');
|
||||
}));
|
||||
|
||||
describe('working with the @constraints property:', function() {
|
||||
var model, elt,
|
||||
goodValue = 'allowedValue',
|
||||
badValue = 'restrictedValue',
|
||||
errorMessage = 'Wrong value provided';
|
||||
beforeEach(function() {
|
||||
var modelClass = fields.string.extend({}, {
|
||||
'@constraints': [
|
||||
function(value) {
|
||||
return value !== badValue ? true : errorMessage;
|
||||
}
|
||||
]
|
||||
});
|
||||
$scope.model = modelClass.create();
|
||||
elt = $compile('<form name="form"><input name="model" type="text" ' +
|
||||
'ng-model="model.value" ng-model-options="{ getterSetter: true }" ' +
|
||||
'validatable-with="model"></form>')($scope);
|
||||
});
|
||||
|
||||
describe('any valid value', function() {
|
||||
beforeEach(function() {
|
||||
$scope.form.model.$setViewValue(goodValue);
|
||||
$scope.$digest();
|
||||
});
|
||||
|
||||
it('is allowed to be entered', function() {
|
||||
expect($scope.form.model.$viewValue).toEqual(goodValue);
|
||||
});
|
||||
|
||||
it('is propagated into the model', function() {
|
||||
expect($scope.model.value()).toEqual(goodValue);
|
||||
});
|
||||
|
||||
it('does not cause the input to be marked as erroneous', function() {
|
||||
expect(elt.find('input').hasClass('ng-valid')).toBe(true);
|
||||
});
|
||||
|
||||
it('sets error message on scope to an empty string', function() {
|
||||
expect($scope.error).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('any invalid value', function() {
|
||||
beforeEach(function() {
|
||||
$scope.form.model.$setViewValue(badValue);
|
||||
$scope.$digest();
|
||||
});
|
||||
|
||||
it('is allowed to be entered', function() {
|
||||
expect($scope.form.model.$viewValue).toEqual(badValue);
|
||||
});
|
||||
|
||||
it('is not propagated into the model', function() {
|
||||
expect($scope.model.value()).toBe(undefined);
|
||||
});
|
||||
|
||||
it('causes the input to be marked as erroneous', function() {
|
||||
expect(elt.find('input').hasClass('ng-invalid')).toBe(true);
|
||||
});
|
||||
|
||||
it('exposes error message in the parent scope', function() {
|
||||
expect($scope.error).toEqual(errorMessage);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe('working with the @required property', function() {
|
||||
// TODO: fill in once validation of @required fields changes in Barricade
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user