Skip to content

Commit 04ac040

Browse files
committed
Merge branch 'release/0.8.1'
2 parents d7c206d + d6d37ce commit 04ac040

34 files changed

+953
-156
lines changed

.jscs.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"preset": "google",
3-
"maximumLineLength": 100
3+
"maximumLineLength": 100,
4+
"disallowMultipleLineBreaks": false
45
}

.jshintrc

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
"undef": true,
33
"unused": true,
44
"browser": true,
5-
"globals": {
5+
"globals": {
6+
"ObjectPath": false,
67
"console":false,
78
"jQuery": false,
89
"$":false,
910
"assertEquals": false,
1011
"jstestdriver": false,
1112
"assertTrue": false,
12-
"assertFalse": false,
13+
"assertFalse": false,
1314
"describe": false,
1415
"it":false,
1516
"expect": false,
@@ -24,4 +25,4 @@
2425
"Jed": false,
2526
"tws": false
2627
}
27-
}
28+
}

CHANGELOG

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
v0.8.1
2+
------
3+
* Fixed order of error messages, thanks @davidlgj
4+
* Added `modelValue` to variables available in a condition, thanks @dben
5+
* UMD wrapping, thanks @dwikle
6+
* disableErrorState, disableSuccessState options, thanks @domasx2
7+
* Awesome gist integration to example page, thanks @dervisevic
8+
* Global option to disable tv4 validation, thanks @maff
9+
* Option: labelHtmlClass, thanks @AlexAlbala
10+
* Doc fixes and updates, thanks @Minisai, @jdcaballerov, @cjroth, @dervisevic
11+
* Bugfixes, thanks @engelfrost, @mqamhieh, @carchrae
12+
13+
114
v0.8.0
215
Loads of stuff happened this release, so we're bumping version to 0.8.0.
316
Note as well that there is a small change to `tabsarray` type regarding its title, the title is now
@@ -16,7 +29,7 @@ See the docs on `tabarray` for an more info.
1629
directive for add-on to use. thanks @davidlgj
1730
* interpolation instead of eval'ing in tabarray title, thanks @coridyn
1831
* Lots of bugfixes, most notable checkboxes validation now works, thanks @davidlgj, @coridyn,
19-
@ulion, @adamcbuckley
32+
@ulion, @adamcbuckley
2033

2134
v0.7.13
2235
-------

README.md

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Angular Schema Form [![alt text][1.1]][1]
1+
Angular Schema Form
22
===================
33
[![Build Status](https://travis-ci.org/Textalk/angular-schema-form.svg?branch=master)](https://travis-ci.org/Textalk/angular-schema-form)
44
[![Coverage Status](https://coveralls.io/repos/Textalk/angular-schema-form/badge.png?branch=master)](https://coveralls.io/r/Textalk/angular-schema-form?branch=development)
@@ -8,14 +8,15 @@ Angular Schema Form [![alt text][1.1]][1]
88

99
Generate forms from JSON schemas using AngularJS!
1010

11-
Web Page
11+
Web Page / Twitter
1212
--------
13-
[schemaform.io](http://schemaform.io)
13+
[schemaform.io](http://schemaform.io) / [@SchemaFormIO](http://twitter.com/SchemaFormIO)
1414

1515
Demo Time!
1616
----------
17-
[Try out the example page](http://schemaform.io/examples/bootstrap-example.html).
18-
Try editing the schema or form definition and see what comes out!
17+
[Try out the example page](http://schemaform.io/examples/bootstrap-example.html). Try editing the schema or form definition and see what comes out!
18+
19+
Now you can save your code and share it!
1920

2021
What is it?
2122
----------
@@ -200,8 +201,3 @@ $ bower install
200201
$ sudo npm install -g karma-cli
201202
$ karma start karma.conf.js
202203
```
203-
204-
<!-- Please don't remove this: Grab your social icons from https://github.com/carlsednaoui/gitsocial -->
205-
[1.1]: http://i.imgur.com/tXSoThF.png (twitter icon with padding)
206-
[1]: http://www.twitter.com/ngSchemaForm
207-
[1.2]: http://i.imgur.com/wWzX9uB.png (twitter icon without padding)

bower.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"dist/schema-form.js",
55
"dist/bootstrap-decorator.js"
66
],
7-
"version": "0.8.0",
7+
"version": "0.8.1",
88
"authors": [
99
"Textalk",
1010
"David Jensen <[email protected]>",

dist/bootstrap-decorator.js

+8-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/bootstrap-decorator.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/schema-form.js

+61-37
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
(function(root, factory) {
2+
if (typeof define === 'function' && define.amd) {
3+
define(['angular', 'ObjectPath', 'tv4'], factory);
4+
} else if (typeof exports === 'object') {
5+
module.exports = factory(require('angular'), require('ObjectPath'), require('tv4'));
6+
} else {
7+
root.schemaForm = factory(root.angular, root.ObjectPath, root.tv4);
8+
}
9+
}(this, function(angular, ObjectPath, tv4) {
110
// Deps is sort of a problem for us, maybe in the future we will ask the user to depend
211
// on modules for add-ons
312

@@ -20,7 +29,7 @@ try {
2029
deps.push('angularSpectrumColorpicker');
2130
} catch (e) {}
2231

23-
angular.module('schemaForm', deps);
32+
var schemaForm = angular.module('schemaForm', deps);
2433

2534
angular.module('schemaForm').provider('sfPath',
2635
[function() {
@@ -159,8 +168,8 @@ angular.module('schemaForm').provider('schemaFormDecorators',
159168

160169
var createDirective = function(name) {
161170
$compileProvider.directive(name,
162-
['$parse', '$compile', '$http', '$templateCache', '$interpolate', '$q', 'sfErrorMessage',
163-
function($parse, $compile, $http, $templateCache, $interpolate, $q, sfErrorMessage) {
171+
['$parse', '$compile', '$http', '$templateCache', '$interpolate', '$q', 'sfErrorMessage', 'sfPath',
172+
function($parse, $compile, $http, $templateCache, $interpolate, $q, sfErrorMessage, sfPath) {
164173

165174
return {
166175
restrict: 'AE',
@@ -287,6 +296,7 @@ angular.module('schemaForm').provider('schemaFormDecorators',
287296
return sfErrorMessage.interpolate(
288297
(schemaError && schemaError.code + '') || 'default',
289298
(scope.ngModel && scope.ngModel.$modelValue) || '',
299+
(scope.ngModel && scope.ngModel.$viewValue) || '',
290300
scope.form,
291301
scope.options && scope.options.validationMessage
292302
);
@@ -331,18 +341,23 @@ angular.module('schemaForm').provider('schemaFormDecorators',
331341
// Do we have a condition? Then we slap on an ng-if on all children,
332342
// but be nice to existing ng-if.
333343
if (form.condition) {
344+
345+
var evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex})';
346+
if (form.key) {
347+
evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex, "modelValue": model' + sfPath.stringify(form.key) + '})';
348+
}
349+
334350
angular.forEach(element.children(), function(child) {
335351
var ngIf = child.getAttribute('ng-if');
336352
child.setAttribute(
337353
'ng-if',
338354
ngIf ?
339355
'(' + ngIf +
340-
') || (evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex }))'
341-
: 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex })'
356+
') || (' + evalExpr +')'
357+
: evalExpr
342358
);
343359
});
344360
}
345-
346361
$compile(element.contents())(scope);
347362
});
348363

@@ -372,15 +387,16 @@ angular.module('schemaForm').provider('schemaFormDecorators',
372387
if (!form.validationMessage) {
373388
form.validationMessage = {};
374389
}
375-
console.log('settings validationMessage', validationMessage)
376390
form.validationMessage[error] = validationMessage;
377391
}
378392

379393
scope.ngModel.$setValidity(error, validity === true);
380394

381-
// Setting or removing a validity can change the field to believe its valid
382-
// but its not. So lets trigger its validation as well.
383-
scope.$broadcast('schemaFormValidate');
395+
if (validity === true) {
396+
// Setting or removing a validity can change the field to believe its valid
397+
// but its not. So lets trigger its validation as well.
398+
scope.$broadcast('schemaFormValidate');
399+
}
384400
}
385401
})
386402
}
@@ -548,32 +564,32 @@ angular.module('schemaForm').provider('sfErrorMessage', function() {
548564
// TODO: Humanize these.
549565
var defaultMessages = {
550566
'default': 'Field does not validate',
551-
0: 'Invalid type, expected {{schema.type}})',
567+
0: 'Invalid type, expected {{schema.type}}',
552568
1: 'No enum match for: {{value}}',
553569
10: 'Data does not match any schemas from "anyOf"',
554570
11: 'Data does not match any schemas from "oneOf"',
555571
12: 'Data is valid against more than one schema from "oneOf"',
556572
13: 'Data matches schema from "not"',
557573
// Numeric errors
558-
100: 'Value {{value}} is not a multiple of {{schema.multipleOf}}',
559-
101: 'Value {{value}} is less than minimum {{schema.minimum}}',
560-
102: 'Value {{value}} is equal to exclusive minimum {{schema.minimum}}',
561-
103: 'Value {{value}} is greater than maximum {{schema.maximum}}',
562-
104: 'Value {{value}} is equal to exclusive maximum {{schema.maximum}}',
563-
105: 'Value {{value}} is not a valid number',
574+
100: 'Value is not a multiple of {{schema.divisibleBy}}',
575+
101: '{{viewValue}} is less than the allowed minimum of {{schema.minimum}}',
576+
102: '{{viewValue}} is equal to the exclusive minimum {{schema.minimum}}',
577+
103: '{{viewValue}} is greater than the allowed maximum of {{schema.maximum}}',
578+
104: '{{viewValue}} is equal to the exclusive maximum {{schema.maximum}}',
579+
105: 'Value is not a valid number',
564580
// String errors
565-
200: 'String is too short ({{value.length}} chars), minimum {{schema.minimum}}',
566-
201: 'String is too long ({{value.length}} chars), maximum {{schema.maximum}}',
581+
200: 'String is too short ({{viewValue.length}} chars), minimum {{schema.minLength}}',
582+
201: 'String is too long ({{viewValue.length}} chars), maximum {{schema.maxLength}}',
567583
202: 'String does not match pattern: {{schema.pattern}}',
568584
// Object errors
569-
300: 'Too few properties defined, minimum {{schema.minimum}}',
570-
301: 'Too many properties defined, maximum {{schema.maximum}}',
585+
300: 'Too few properties defined, minimum {{schema.minProperties}}',
586+
301: 'Too many properties defined, maximum {{schema.maxProperties}}',
571587
302: 'Required',
572588
303: 'Additional properties not allowed',
573589
304: 'Dependency failed - key must exist',
574590
// Array errors
575-
400: 'Array is too short ({{value.length}}), minimum {{schema.minimum}}',
576-
401: 'Array is too long ({{value.length}}), maximum {{schema.maximum}}',
591+
400: 'Array is too short ({{value.length}}), minimum {{schema.maxItems}}',
592+
401: 'Array is too long ({{value.length}}), maximum {{schema.minItems}}',
577593
402: 'Array items are not unique',
578594
403: 'Additional items not allowed',
579595
// Format errors
@@ -585,6 +601,15 @@ angular.module('schemaForm').provider('sfErrorMessage', function() {
585601
1000: 'Unknown property (not in schema)'
586602
};
587603

604+
// In some cases we get hit with an angular validation error
605+
defaultMessages.number = defaultMessages[105];
606+
defaultMessages.required = defaultMessages[302];
607+
defaultMessages.min = defaultMessages[101];
608+
defaultMessages.max = defaultMessages[103];
609+
defaultMessages.maxlength = defaultMessages[201];
610+
defaultMessages.minlength = defaultMessages[200];
611+
defaultMessages.pattern = defaultMessages[202];
612+
588613
this.setDefaultMessages = function(messages) {
589614
defaultMessages = messages;
590615
};
@@ -609,12 +634,13 @@ angular.module('schemaForm').provider('sfErrorMessage', function() {
609634
* @param {string} error the error code, i.e. tv4-xxx for tv4 errors, otherwise it's whats on
610635
* ngModel.$error for custom errors.
611636
* @param {Any} value the actual model value.
637+
* @param {Any} viewValue the viewValue
612638
* @param {Object} form a form definition object for this field
613639
* @param {Object} global the global validation messages object (even though its called global
614640
* its actually just shared in one instance of sf-schema)
615641
* @return {string} The error message.
616642
*/
617-
service.interpolate = function(error, value, form, global) {
643+
service.interpolate = function(error, value, viewValue, form, global) {
618644
global = global || {};
619645
var validationMessage = form.validationMessage || {};
620646

@@ -640,6 +666,7 @@ angular.module('schemaForm').provider('sfErrorMessage', function() {
640666
var context = {
641667
error: error,
642668
value: value,
669+
viewValue: viewValue,
643670
form: form,
644671
schema: form.schema,
645672
title: form.title || (form.schema && form.schema.title)
@@ -1495,7 +1522,7 @@ angular.module('schemaForm').directive('sfMessage',
14951522
}
14961523

14971524
var update = function(valid) {
1498-
if (valid && scope.hasError()) {
1525+
if (valid && !scope.hasError()) {
14991526
element.html(msg);
15001527
} else {
15011528

@@ -1505,24 +1532,13 @@ angular.module('schemaForm').directive('sfMessage',
15051532

15061533
// We only show one error.
15071534
// TODO: Make that optional
1508-
// tv4- errors take precedence
15091535
var error = errors[0];
1510-
if (errors.length > 1) {
1511-
1512-
error = errors.reduce(function(prev, value) {
1513-
if (prev && prev.indexOf('tv4-') === 0) {
1514-
return prev;
1515-
}
1516-
return value;
1517-
});
1518-
console.log('reduced',errors, error)
1519-
1520-
}
15211536

15221537
if (error) {
15231538
element.html(sfErrorMessage.interpolate(
15241539
error,
15251540
scope.ngModel.$modelValue,
1541+
scope.ngModel.$viewValue,
15261542
scope.form,
15271543
scope.options && scope.options.validationMessage
15281544
));
@@ -1752,6 +1768,11 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSele
17521768
return viewValue;
17531769
}
17541770

1771+
// Omit TV4 validation
1772+
if (scope.options && scope.options.tv4Validation === false) {
1773+
return viewValue;
1774+
}
1775+
17551776
var result = sfValidator.validate(form, viewValue);
17561777
// Since we might have different tv4 errors we must clear all
17571778
// errors that start with tv4-
@@ -1814,3 +1835,6 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSele
18141835
}
18151836
};
18161837
}]);
1838+
1839+
return schemaForm;
1840+
}));

dist/schema-form.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.md

+11-7
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,8 @@ And of global options
249249
250250
251251
### Message Interpolation
252-
Having a good validation message is hard, sometimes you need to reference the actual value, title
253-
och constraint that you hit. Schema Form supports interpolation of error messages to make this a
252+
Having a good validation message is hard, sometimes you need to reference the actual value, title,
253+
or constraint that you hit. Schema Form supports interpolation of error messages to make this a
254254
little bit easier.
255255
256256
The context variables available to you are:
@@ -260,6 +260,7 @@ The context variables available to you are:
260260
| error | The error code |
261261
| title | Title of the field |
262262
| value | The model value |
263+
| viewValue | The view value (probably the one you want) |
263264
| form | form definition object for this field |
264265
| schema | schema for this field |
265266
@@ -622,12 +623,15 @@ General options most field types can handle:
622623
validationMessage: "Oh noes, please write a proper address", // A custom validation error message
623624
onChange: "valueChanged(form.key,modelValue)", // onChange event handler, expression or function
624625
feedback: false, // Inline feedback icons
626+
disableSuccessState: false, // Set true to NOT apply 'has-success' class to a field that was validated successfully
627+
disableErrorState: false, // Set true to NOT apply 'has-error' class to a field that failed validation
625628
placeholder: "Input...", // placeholder on inputs and textarea
626629
ngModelOptions: { ... }, // Passed along to ng-model-options
627630
readonly: true, // Same effect as readOnly in schema. Put on a fieldset or array
628631
// and their items will inherit it.
629632
htmlClass: "street foobar", // CSS Class(es) to be added to the container div
630633
fieldHtmlClass: "street" // CSS Class(es) to be added to field input (or similar)
634+
labelHtmlClass: "street" // CSS Class(es) to be added to the label of the field (or similar)
631635
copyValueTo: ["address.street"], // Copy values to these schema keys.
632636
condition: "person.age < 18" // Show or hide field depending on an angular expression
633637
}
@@ -726,9 +730,9 @@ the surface it uses `ng-if` so the hidden field is *not* part of the form.
726730
727731
`condition` should be a string with an angular expression. If that expression evaluates as thruthy
728732
the field will be rendered into the DOM otherwise not. The expression is evaluated in the parent scope of
729-
the `sf-schema` directive (the same as onClick on buttons) but with access to the current model
730-
and current array index under the name `model` and `arrayIndex`. This is useful for hiding/showing
731-
parts of a form depending on another form control.
733+
the `sf-schema` directive (the same as onClick on buttons) but with access to the current model,
734+
current model value and current array index under the name `model`, `modelValue` and `arrayIndex`.
735+
This is useful for hiding/showing parts of a form depending on another form control.
732736
733737
ex. A checkbox that shows an input field for a code when checked
734738
@@ -758,8 +762,8 @@ function FormCtrl($scope) {
758762
"name",
759763
"eligible",
760764
{
761-
key: "code",
762-
condition: "person.eligible", //or "model.eligable"
765+
"key": "code",
766+
"condition": "person.eligible", //or "model.eligible"
763767
}
764768
]
765769
}

0 commit comments

Comments
 (0)