Skip to content

Commit 141101e

Browse files
committed
Gulped
1 parent ffab373 commit 141101e

File tree

2 files changed

+159
-101
lines changed

2 files changed

+159
-101
lines changed

dist/schema-form.js

+158-100
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,10 @@ angular.module('schemaForm').provider('schemaFormDecorators',
168168

169169
var createDirective = function(name) {
170170
$compileProvider.directive(name,
171-
['$parse', '$compile', '$http', '$templateCache', '$interpolate', '$q', 'sfErrorMessage', 'sfPath',
172-
function($parse, $compile, $http, $templateCache, $interpolate, $q, sfErrorMessage, sfPath) {
171+
['$parse', '$compile', '$http', '$templateCache', '$interpolate', '$q', 'sfErrorMessage',
172+
'sfPath','sfSelect',
173+
function($parse, $compile, $http, $templateCache, $interpolate, $q, sfErrorMessage,
174+
sfPath, sfSelect) {
173175

174176
return {
175177
restrict: 'AE',
@@ -398,7 +400,48 @@ angular.module('schemaForm').provider('schemaFormDecorators',
398400
scope.$broadcast('schemaFormValidate');
399401
}
400402
}
401-
})
403+
});
404+
405+
// Clean up the model when the corresponding form field is $destroy-ed.
406+
// Default behavior can be supplied as a globalOption, and behavior can be overridden in the form definition.
407+
scope.$on('$destroy', function() {
408+
// If the entire schema form is destroyed we don't touch the model
409+
if (!scope.externalDestructionInProgress) {
410+
var destroyStrategy = form.destroyStrategy ||
411+
(scope.options && scope.options.destroyStrategy) || 'remove';
412+
// No key no model, and we might have strategy 'retain'
413+
if (form.key && destroyStrategy !== 'retain') {
414+
415+
// Get the object that has the property we wan't to clear.
416+
var obj = scope.model;
417+
if (form.key.length > 1) {
418+
obj = sfSelect(form.key.slice(0, form.key.length - 1), obj);
419+
}
420+
421+
// We can get undefined here if the form hasn't been filled out entirely
422+
if (obj === undefined) {
423+
return;
424+
}
425+
426+
// Type can also be a list in JSON Schema
427+
var type = (form.schema && form.schema.type) || '';
428+
429+
// Empty means '',{} and [] for appropriate types and undefined for the rest
430+
//console.log('destroy', destroyStrategy, form.key, type, obj);
431+
if (destroyStrategy === 'empty' && type.indexOf('string') !== -1) {
432+
obj[form.key.slice(-1)] = '';
433+
} else if (destroyStrategy === 'empty' && type.indexOf('object') !== -1) {
434+
obj[form.key.slice(-1)] = {};
435+
} else if (destroyStrategy === 'empty' && type.indexOf('array') !== -1) {
436+
obj[form.key.slice(-1)] = [];
437+
} else if (destroyStrategy === 'null') {
438+
obj[form.key.slice(-1)] = null;
439+
} else {
440+
delete obj[form.key.slice(-1)];
441+
}
442+
}
443+
}
444+
});
402445
}
403446

404447
once();
@@ -1633,7 +1676,10 @@ angular.module('schemaForm')
16331676
// they have been removed from the DOM
16341677
// https://github.com/Textalk/angular-schema-form/issues/200
16351678
if (childScope) {
1679+
// Destroy strategy should not be acted upon
1680+
scope.externalDestructionInProgress = true;
16361681
childScope.$destroy();
1682+
scope.externalDestructionInProgress = false;
16371683
}
16381684
childScope = scope.$new();
16391685

@@ -1680,14 +1726,16 @@ angular.module('schemaForm')
16801726
$compile(element.children())(childScope);
16811727

16821728
//ok, now that that is done let's set any defaults
1683-
schemaForm.traverseSchema(schema, function(prop, path) {
1684-
if (angular.isDefined(prop['default'])) {
1685-
var val = sfSelect(path, scope.model);
1686-
if (angular.isUndefined(val)) {
1687-
sfSelect(path, scope.model, prop['default']);
1729+
if (!scope.options || scope.options.setSchemaDefaults !== false) {
1730+
schemaForm.traverseSchema(schema, function(prop, path) {
1731+
if (angular.isDefined(prop['default'])) {
1732+
var val = sfSelect(path, scope.model);
1733+
if (angular.isUndefined(val)) {
1734+
sfSelect(path, scope.model, prop['default']);
1735+
}
16881736
}
1689-
}
1690-
});
1737+
});
1738+
}
16911739

16921740
scope.$emit('sf-render-finished', element);
16931741
};
@@ -1720,121 +1768,131 @@ angular.module('schemaForm')
17201768
}
17211769
});
17221770

1771+
scope.$on('$destroy', function() {
1772+
// Each field listens to the $destroy event so that it can remove any value
1773+
// from the model if that field is removed from the form. This is the default
1774+
// destroy strategy. But if the entire form (or at least the part we're on)
1775+
// gets removed, like when routing away to another page, then we definetly want to
1776+
// keep the model intact. So therefore we set a flag to tell the others it's time to just
1777+
// let it be.
1778+
scope.externalDestructionInProgress = true;
1779+
});
17231780
}
17241781
};
17251782
}
17261783
]);
17271784

1728-
angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSelect', function(sfValidator, sfSelect) {
1729-
return {
1730-
restrict: 'A',
1731-
scope: false,
1732-
// We want the link function to be *after* the input directives link function so we get access
1733-
// the parsed value, ex. a number instead of a string
1734-
priority: 500,
1735-
require: 'ngModel',
1736-
link: function(scope, element, attrs, ngModel) {
1785+
angular.module('schemaForm').directive('schemaValidate', ['sfValidator', '$parse',
1786+
function(sfValidator, $parse) {
17371787

1788+
return {
1789+
restrict: 'A',
1790+
scope: false,
1791+
// We want the link function to be *after* the input directives link function so we get access
1792+
// the parsed value, ex. a number instead of a string
1793+
priority: 500,
1794+
require: 'ngModel',
1795+
link: function(scope, element, attrs, ngModel) {
17381796

1739-
// We need the ngModelController on several places,
1740-
// most notably for errors.
1741-
// So we emit it up to the decorator directive so it can put it on scope.
1742-
scope.$emit('schemaFormPropagateNgModelController', ngModel);
1797+
// We need the ngModelController on several places,
1798+
// most notably for errors.
1799+
// So we emit it up to the decorator directive so it can put it on scope.
1800+
scope.$emit('schemaFormPropagateNgModelController', ngModel);
17431801

1744-
var error = null;
1802+
var error = null;
17451803

1746-
var getForm = function() {
1747-
if (!form) {
1748-
form = scope.$eval(attrs.schemaValidate);
1749-
}
1750-
return form;
1751-
};
1752-
var form = getForm();
1753-
if (form.copyValueTo) {
1754-
ngModel.$viewChangeListeners.push(function() {
1755-
var paths = form.copyValueTo;
1756-
angular.forEach(paths, function(path) {
1757-
sfSelect(path, scope.model, ngModel.$modelValue);
1804+
var getForm = function() {
1805+
if (!form) {
1806+
form = scope.$eval(attrs.schemaValidate);
1807+
}
1808+
return form;
1809+
};
1810+
var form = getForm();
1811+
if (form.copyValueTo) {
1812+
ngModel.$viewChangeListeners.push(function() {
1813+
var paths = form.copyValueTo;
1814+
angular.forEach(paths, function(path) {
1815+
sfSelect(path, scope.model, ngModel.$modelValue);
1816+
});
17581817
});
1759-
});
1760-
}
1818+
}
17611819

1762-
// Validate against the schema.
1820+
// Validate against the schema.
17631821

1764-
var validate = function(viewValue) {
1765-
form = getForm();
1766-
//Still might be undefined
1767-
if (!form) {
1768-
return viewValue;
1769-
}
1822+
var validate = function(viewValue) {
1823+
form = getForm();
1824+
//Still might be undefined
1825+
if (!form) {
1826+
return viewValue;
1827+
}
17701828

1771-
// Omit TV4 validation
1772-
if (scope.options && scope.options.tv4Validation === false) {
1773-
return viewValue;
1774-
}
1829+
// Omit TV4 validation
1830+
if (scope.options && scope.options.tv4Validation === false) {
1831+
return viewValue;
1832+
}
17751833

1776-
var result = sfValidator.validate(form, viewValue);
1777-
// Since we might have different tv4 errors we must clear all
1778-
// errors that start with tv4-
1779-
Object.keys(ngModel.$error)
1834+
var result = sfValidator.validate(form, viewValue);
1835+
// Since we might have different tv4 errors we must clear all
1836+
// errors that start with tv4-
1837+
Object.keys(ngModel.$error)
17801838
.filter(function(k) { return k.indexOf('tv4-') === 0; })
17811839
.forEach(function(k) { ngModel.$setValidity(k, true); });
17821840

1783-
if (!result.valid) {
1784-
// it is invalid, return undefined (no model update)
1785-
ngModel.$setValidity('tv4-' + result.error.code, false);
1786-
error = result.error;
1787-
return undefined;
1788-
}
1789-
return viewValue;
1790-
};
1791-
1792-
// Custom validators, parsers, formatters etc
1793-
if (typeof form.ngModel === 'function') {
1794-
form.ngModel(ngModel);
1795-
}
1841+
if (!result.valid) {
1842+
// it is invalid, return undefined (no model update)
1843+
ngModel.$setValidity('tv4-' + result.error.code, false);
1844+
error = result.error;
1845+
return undefined;
1846+
}
1847+
return viewValue;
1848+
};
17961849

1797-
['$parsers', '$viewChangeListeners', '$formatters'].forEach(function(attr) {
1798-
if (form[attr] && ngModel[attr]) {
1799-
form[attr].forEach(function(fn) {
1800-
ngModel[attr].push(fn);
1801-
});
1850+
// Custom validators, parsers, formatters etc
1851+
if (typeof form.ngModel === 'function') {
1852+
form.ngModel(ngModel);
18021853
}
1803-
});
18041854

1805-
['$validators', '$asyncValidators'].forEach(function(attr) {
1806-
// Check if our version of angular has i, i.e. 1.3+
1807-
if (form[attr] && ngModel[attr]) {
1808-
angular.forEach(form[attr], function(fn, name) {
1809-
ngModel[attr][name] = fn;
1810-
});
1811-
}
1812-
});
1855+
['$parsers', '$viewChangeListeners', '$formatters'].forEach(function(attr) {
1856+
if (form[attr] && ngModel[attr]) {
1857+
form[attr].forEach(function(fn) {
1858+
ngModel[attr].push(fn);
1859+
});
1860+
}
1861+
});
18131862

1814-
// Get in last of the parses so the parsed value has the correct type.
1815-
// We don't use $validators since we like to set different errors depeding tv4 error codes
1816-
ngModel.$parsers.push(validate);
1863+
['$validators', '$asyncValidators'].forEach(function(attr) {
1864+
// Check if our version of angular has i, i.e. 1.3+
1865+
if (form[attr] && ngModel[attr]) {
1866+
angular.forEach(form[attr], function(fn, name) {
1867+
ngModel[attr][name] = fn;
1868+
});
1869+
}
1870+
});
18171871

1818-
// Listen to an event so we can validate the input on request
1819-
scope.$on('schemaFormValidate', function() {
1820-
if (ngModel.$setDirty) {
1821-
// Angular 1.3+
1822-
ngModel.$setDirty();
1823-
validate(ngModel.$modelValue);
1824-
} else {
1825-
// Angular 1.2
1826-
ngModel.$setViewValue(ngModel.$viewValue);
1827-
}
1872+
// Get in last of the parses so the parsed value has the correct type.
1873+
// We don't use $validators since we like to set different errors depeding tv4 error codes
1874+
ngModel.$parsers.push(validate);
18281875

1829-
});
1876+
// Listen to an event so we can validate the input on request
1877+
scope.$on('schemaFormValidate', function() {
1878+
if (ngModel.$setDirty) {
1879+
// Angular 1.3+
1880+
ngModel.$setDirty();
1881+
validate(ngModel.$modelValue);
1882+
} else {
1883+
// Angular 1.2
1884+
ngModel.$setViewValue(ngModel.$viewValue);
1885+
}
18301886

1831-
scope.schemaError = function() {
1832-
return error;
1833-
};
1887+
});
18341888

1835-
}
1836-
};
1837-
}]);
1889+
scope.schemaError = function() {
1890+
return error;
1891+
};
1892+
1893+
}
1894+
};
1895+
}]);
18381896

18391897
return schemaForm;
18401898
}));

0 commit comments

Comments
 (0)