Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 14f4aaa

Browse files
committedMay 20, 2015
Move listening of event to preLink
So that it is guaranteed to listen before event is issued
1 parent 862feee commit 14f4aaa

File tree

3 files changed

+476
-470
lines changed

3 files changed

+476
-470
lines changed
 

‎dist/schema-form.js

Lines changed: 239 additions & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,277 +1727,280 @@ angular.module('schemaForm').directive('sfField',
17271727
transclude: false,
17281728
scope: true,
17291729
require: '?^sfSchema',
1730-
link: function(scope, element, attrs, sfSchema) {
1731-
1732-
//The ngModelController is used in some templates and
1733-
//is needed for error messages,
1734-
scope.$on('schemaFormPropagateNgModelController', function(event, ngModel) {
1735-
event.stopPropagation();
1736-
event.preventDefault();
1737-
scope.ngModel = ngModel;
1738-
});
1730+
link: {
1731+
pre: function(scope, element, attrs, sfSchema) {
1732+
//The ngModelController is used in some templates and
1733+
//is needed for error messages,
1734+
scope.$on('schemaFormPropagateNgModelController', function(event, ngModel) {
1735+
event.stopPropagation();
1736+
event.preventDefault();
1737+
scope.ngModel = ngModel;
1738+
});
1739+
},
1740+
post: function(scope, element, attrs, sfSchema) {
17391741

1740-
//Keep error prone logic from the template
1741-
scope.showTitle = function() {
1742-
return scope.form && scope.form.notitle !== true && scope.form.title;
1743-
};
1742+
//Keep error prone logic from the template
1743+
scope.showTitle = function() {
1744+
return scope.form && scope.form.notitle !== true && scope.form.title;
1745+
};
17441746

1745-
scope.listToCheckboxValues = function(list) {
1746-
var values = {};
1747-
angular.forEach(list, function(v) {
1748-
values[v] = true;
1749-
});
1750-
return values;
1751-
};
1747+
scope.listToCheckboxValues = function(list) {
1748+
var values = {};
1749+
angular.forEach(list, function(v) {
1750+
values[v] = true;
1751+
});
1752+
return values;
1753+
};
17521754

1753-
scope.checkboxValuesToList = function(values) {
1754-
var lst = [];
1755-
angular.forEach(values, function(v, k) {
1756-
if (v) {
1757-
lst.push(k);
1755+
scope.checkboxValuesToList = function(values) {
1756+
var lst = [];
1757+
angular.forEach(values, function(v, k) {
1758+
if (v) {
1759+
lst.push(k);
1760+
}
1761+
});
1762+
return lst;
1763+
};
1764+
1765+
scope.buttonClick = function($event, form) {
1766+
if (angular.isFunction(form.onClick)) {
1767+
form.onClick($event, form);
1768+
} else if (angular.isString(form.onClick)) {
1769+
if (sfSchema) {
1770+
//evaluating in scope outside of sfSchemas isolated scope
1771+
sfSchema.evalInParentScope(form.onClick, {'$event': $event, form: form});
1772+
} else {
1773+
scope.$eval(form.onClick, {'$event': $event, form: form});
1774+
}
17581775
}
1759-
});
1760-
return lst;
1761-
};
1776+
};
17621777

1763-
scope.buttonClick = function($event, form) {
1764-
if (angular.isFunction(form.onClick)) {
1765-
form.onClick($event, form);
1766-
} else if (angular.isString(form.onClick)) {
1778+
/**
1779+
* Evaluate an expression, i.e. scope.$eval
1780+
* but do it in sfSchemas parent scope sf-schema directive is used
1781+
* @param {string} expression
1782+
* @param {Object} locals (optional)
1783+
* @return {Any} the result of the expression
1784+
*/
1785+
scope.evalExpr = function(expression, locals) {
17671786
if (sfSchema) {
17681787
//evaluating in scope outside of sfSchemas isolated scope
1769-
sfSchema.evalInParentScope(form.onClick, {'$event': $event, form: form});
1770-
} else {
1771-
scope.$eval(form.onClick, {'$event': $event, form: form});
1788+
return sfSchema.evalInParentScope(expression, locals);
17721789
}
1773-
}
1774-
};
17751790

1776-
/**
1777-
* Evaluate an expression, i.e. scope.$eval
1778-
* but do it in sfSchemas parent scope sf-schema directive is used
1779-
* @param {string} expression
1780-
* @param {Object} locals (optional)
1781-
* @return {Any} the result of the expression
1782-
*/
1783-
scope.evalExpr = function(expression, locals) {
1784-
if (sfSchema) {
1785-
//evaluating in scope outside of sfSchemas isolated scope
1786-
return sfSchema.evalInParentScope(expression, locals);
1787-
}
1791+
return scope.$eval(expression, locals);
1792+
};
17881793

1789-
return scope.$eval(expression, locals);
1790-
};
1794+
/**
1795+
* Evaluate an expression, i.e. scope.$eval
1796+
* in this decorators scope
1797+
* @param {string} expression
1798+
* @param {Object} locals (optional)
1799+
* @return {Any} the result of the expression
1800+
*/
1801+
scope.evalInScope = function(expression, locals) {
1802+
if (expression) {
1803+
return scope.$eval(expression, locals);
1804+
}
1805+
};
17911806

1792-
/**
1793-
* Evaluate an expression, i.e. scope.$eval
1794-
* in this decorators scope
1795-
* @param {string} expression
1796-
* @param {Object} locals (optional)
1797-
* @return {Any} the result of the expression
1798-
*/
1799-
scope.evalInScope = function(expression, locals) {
1800-
if (expression) {
1801-
return scope.$eval(expression, locals);
1802-
}
1803-
};
1807+
/**
1808+
* Interpolate the expression.
1809+
* Similar to `evalExpr()` and `evalInScope()`
1810+
* but will not fail if the expression is
1811+
* text that contains spaces.
1812+
*
1813+
* Use the Angular `{{ interpolation }}`
1814+
* braces to access properties on `locals`.
1815+
*
1816+
* @param {string} content The string to interpolate.
1817+
* @param {Object} locals (optional) Properties that may be accessed in the
1818+
* `expression` string.
1819+
* @return {Any} The result of the expression or `undefined`.
1820+
*/
1821+
scope.interp = function(expression, locals) {
1822+
return (expression && $interpolate(expression)(locals));
1823+
};
18041824

1805-
/**
1806-
* Interpolate the expression.
1807-
* Similar to `evalExpr()` and `evalInScope()`
1808-
* but will not fail if the expression is
1809-
* text that contains spaces.
1810-
*
1811-
* Use the Angular `{{ interpolation }}`
1812-
* braces to access properties on `locals`.
1813-
*
1814-
* @param {string} content The string to interpolate.
1815-
* @param {Object} locals (optional) Properties that may be accessed in the
1816-
* `expression` string.
1817-
* @return {Any} The result of the expression or `undefined`.
1818-
*/
1819-
scope.interp = function(expression, locals) {
1820-
return (expression && $interpolate(expression)(locals));
1821-
};
1825+
//This works since we ot the ngModel from the array or the schema-validate directive.
1826+
scope.hasSuccess = function() {
1827+
if (!scope.ngModel) {
1828+
return false;
1829+
}
1830+
return scope.ngModel.$valid &&
1831+
(!scope.ngModel.$pristine || !scope.ngModel.$isEmpty(scope.ngModel.$modelValue));
1832+
};
18221833

1823-
//This works since we ot the ngModel from the array or the schema-validate directive.
1824-
scope.hasSuccess = function() {
1825-
if (!scope.ngModel) {
1826-
return false;
1827-
}
1828-
return scope.ngModel.$valid &&
1829-
(!scope.ngModel.$pristine || !scope.ngModel.$isEmpty(scope.ngModel.$modelValue));
1830-
};
1834+
scope.hasError = function() {
1835+
if (!scope.ngModel) {
1836+
return false;
1837+
}
1838+
return scope.ngModel.$invalid && !scope.ngModel.$pristine;
1839+
};
18311840

1832-
scope.hasError = function() {
1833-
if (!scope.ngModel) {
1834-
return false;
1835-
}
1836-
return scope.ngModel.$invalid && !scope.ngModel.$pristine;
1837-
};
1841+
/**
1842+
* DEPRECATED: use sf-messages instead.
1843+
* Error message handler
1844+
* An error can either be a schema validation message or a angular js validtion
1845+
* error (i.e. required)
1846+
*/
1847+
scope.errorMessage = function(schemaError) {
1848+
return sfErrorMessage.interpolate(
1849+
(schemaError && schemaError.code + '') || 'default',
1850+
(scope.ngModel && scope.ngModel.$modelValue) || '',
1851+
(scope.ngModel && scope.ngModel.$viewValue) || '',
1852+
scope.form,
1853+
scope.options && scope.options.validationMessage
1854+
);
1855+
};
18381856

1839-
/**
1840-
* DEPRECATED: use sf-messages instead.
1841-
* Error message handler
1842-
* An error can either be a schema validation message or a angular js validtion
1843-
* error (i.e. required)
1844-
*/
1845-
scope.errorMessage = function(schemaError) {
1846-
return sfErrorMessage.interpolate(
1847-
(schemaError && schemaError.code + '') || 'default',
1848-
(scope.ngModel && scope.ngModel.$modelValue) || '',
1849-
(scope.ngModel && scope.ngModel.$viewValue) || '',
1850-
scope.form,
1851-
scope.options && scope.options.validationMessage
1852-
);
1853-
};
1857+
// Rebind our part of the form to the scope.
1858+
var once = scope.$watch(attrs.sfField, function(form) {
1859+
if (form) {
1860+
console.warn('got form!!!!', form)
1861+
// Workaround for 'updateOn' error from ngModelOptions
1862+
// see https://github.com/Textalk/angular-schema-form/issues/255
1863+
// and https://github.com/Textalk/angular-schema-form/issues/206
1864+
form.ngModelOptions = form.ngModelOptions || {};
1865+
scope.form = form;
18541866

1855-
// Rebind our part of the form to the scope.
1856-
var once = scope.$watch(attrs.sfField, function(form) {
1857-
if (form) {
1858-
console.warn('got form!!!!', form)
1859-
// Workaround for 'updateOn' error from ngModelOptions
1860-
// see https://github.com/Textalk/angular-schema-form/issues/255
1861-
// and https://github.com/Textalk/angular-schema-form/issues/206
1862-
form.ngModelOptions = form.ngModelOptions || {};
1863-
scope.form = form;
1867+
/*
1868+
//ok let's replace that template!
1869+
//We do this manually since we need to bind ng-model properly and also
1870+
//for fieldsets to recurse properly.
1871+
var templatePromise;
18641872
1865-
/*
1866-
//ok let's replace that template!
1867-
//We do this manually since we need to bind ng-model properly and also
1868-
//for fieldsets to recurse properly.
1869-
var templatePromise;
1870-
1871-
// type: "template" is a special case. It can contain a template inline or an url.
1872-
// otherwise we find out the url to the template and load them.
1873-
if (form.type === 'template' && form.template) {
1874-
templatePromise = $q.when(form.template);
1875-
} else {
1876-
var url = form.type === 'template' ? form.templateUrl : templateUrl(name, form);
1877-
templatePromise = $http.get(url, {cache: $templateCache}).then(function(res) {
1878-
return res.data;
1879-
});
1880-
}
1881-
*/
1882-
/*
1883-
templatePromise.then(function(template) {
1884-
if (form.key) {
1885-
var key = form.key ?
1886-
sfPathProvider.stringify(form.key).replace(/"/g, '"') : '';
1887-
template = template.replace(
1888-
/\$\$value\$\$/g,
1889-
'model' + (key[0] !== '[' ? '.' : '') + key
1890-
);
1873+
// type: "template" is a special case. It can contain a template inline or an url.
1874+
// otherwise we find out the url to the template and load them.
1875+
if (form.type === 'template' && form.template) {
1876+
templatePromise = $q.when(form.template);
1877+
} else {
1878+
var url = form.type === 'template' ? form.templateUrl : templateUrl(name, form);
1879+
templatePromise = $http.get(url, {cache: $templateCache}).then(function(res) {
1880+
return res.data;
1881+
});
18911882
}
1892-
element.html(template);
1893-
*/
1894-
// Do we have a condition? Then we slap on an ng-if on all children,
1895-
// but be nice to existing ng-if.
1896-
/*if (form.condition) {
1897-
1898-
var evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex})';
1883+
*/
1884+
/*
1885+
templatePromise.then(function(template) {
18991886
if (form.key) {
1900-
evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex, "modelValue": model' + sfPath.stringify(form.key) + '})';
1887+
var key = form.key ?
1888+
sfPathProvider.stringify(form.key).replace(/"/g, '"') : '';
1889+
template = template.replace(
1890+
/\$\$value\$\$/g,
1891+
'model' + (key[0] !== '[' ? '.' : '') + key
1892+
);
19011893
}
1894+
element.html(template);
1895+
*/
1896+
// Do we have a condition? Then we slap on an ng-if on all children,
1897+
// but be nice to existing ng-if.
1898+
/*if (form.condition) {
19021899
1903-
angular.forEach(element.children(), function(child) {
1904-
var ngIf = child.getAttribute('ng-if');
1905-
child.setAttribute(
1906-
'ng-if',
1907-
ngIf ?
1908-
'(' + ngIf +
1909-
') || (' + evalExpr +')'
1910-
: evalExpr
1911-
);
1912-
});
1913-
}*/
1914-
//$compile(element.contents())(scope);
1915-
//});
1916-
1917-
// Where there is a key there is probably a ngModel
1918-
if (form.key) {
1919-
// It looks better with dot notation.
1920-
scope.$on(
1921-
'schemaForm.error.' + form.key.join('.'),
1922-
function(event, error, validationMessage, validity) {
1923-
if (validationMessage === true || validationMessage === false) {
1924-
validity = validationMessage;
1925-
validationMessage = undefined;
1900+
var evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex})';
1901+
if (form.key) {
1902+
evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex, "modelValue": model' + sfPath.stringify(form.key) + '})';
19261903
}
19271904
1928-
if (scope.ngModel && error) {
1929-
if (scope.ngModel.$setDirty()) {
1930-
scope.ngModel.$setDirty();
1931-
} else {
1932-
// FIXME: Check that this actually works on 1.2
1933-
scope.ngModel.$dirty = true;
1934-
scope.ngModel.$pristine = false;
1905+
angular.forEach(element.children(), function(child) {
1906+
var ngIf = child.getAttribute('ng-if');
1907+
child.setAttribute(
1908+
'ng-if',
1909+
ngIf ?
1910+
'(' + ngIf +
1911+
') || (' + evalExpr +')'
1912+
: evalExpr
1913+
);
1914+
});
1915+
}*/
1916+
//$compile(element.contents())(scope);
1917+
//});
1918+
1919+
// Where there is a key there is probably a ngModel
1920+
if (form.key) {
1921+
// It looks better with dot notation.
1922+
scope.$on(
1923+
'schemaForm.error.' + form.key.join('.'),
1924+
function(event, error, validationMessage, validity) {
1925+
if (validationMessage === true || validationMessage === false) {
1926+
validity = validationMessage;
1927+
validationMessage = undefined;
19351928
}
19361929

1937-
// Set the new validation message if one is supplied
1938-
// Does not work when validationMessage is just a string.
1939-
if (validationMessage) {
1940-
if (!form.validationMessage) {
1941-
form.validationMessage = {};
1930+
if (scope.ngModel && error) {
1931+
if (scope.ngModel.$setDirty()) {
1932+
scope.ngModel.$setDirty();
1933+
} else {
1934+
// FIXME: Check that this actually works on 1.2
1935+
scope.ngModel.$dirty = true;
1936+
scope.ngModel.$pristine = false;
1937+
}
1938+
1939+
// Set the new validation message if one is supplied
1940+
// Does not work when validationMessage is just a string.
1941+
if (validationMessage) {
1942+
if (!form.validationMessage) {
1943+
form.validationMessage = {};
1944+
}
1945+
form.validationMessage[error] = validationMessage;
19421946
}
1943-
form.validationMessage[error] = validationMessage;
1944-
}
19451947

1946-
scope.ngModel.$setValidity(error, validity === true);
1948+
scope.ngModel.$setValidity(error, validity === true);
19471949

1948-
if (validity === true) {
1949-
// Setting or removing a validity can change the field to believe its valid
1950-
// but its not. So lets trigger its validation as well.
1951-
scope.$broadcast('schemaFormValidate');
1950+
if (validity === true) {
1951+
// Setting or removing a validity can change the field to believe its valid
1952+
// but its not. So lets trigger its validation as well.
1953+
scope.$broadcast('schemaFormValidate');
1954+
}
19521955
}
1953-
}
1954-
});
1956+
});
19551957

1956-
// Clean up the model when the corresponding form field is $destroy-ed.
1957-
// Default behavior can be supplied as a globalOption, and behavior can be overridden in the form definition.
1958-
scope.$on('$destroy', function() {
1959-
// If the entire schema form is destroyed we don't touch the model
1960-
if (!scope.externalDestructionInProgress) {
1961-
var destroyStrategy = form.destroyStrategy ||
1962-
(scope.options && scope.options.destroyStrategy) || 'remove';
1963-
// No key no model, and we might have strategy 'retain'
1964-
if (form.key && destroyStrategy !== 'retain') {
1965-
1966-
// Get the object that has the property we wan't to clear.
1967-
var obj = scope.model;
1968-
if (form.key.length > 1) {
1969-
obj = sfSelect(form.key.slice(0, form.key.length - 1), obj);
1970-
}
1958+
// Clean up the model when the corresponding form field is $destroy-ed.
1959+
// Default behavior can be supplied as a globalOption, and behavior can be overridden in the form definition.
1960+
scope.$on('$destroy', function() {
1961+
// If the entire schema form is destroyed we don't touch the model
1962+
if (!scope.externalDestructionInProgress) {
1963+
var destroyStrategy = form.destroyStrategy ||
1964+
(scope.options && scope.options.destroyStrategy) || 'remove';
1965+
// No key no model, and we might have strategy 'retain'
1966+
if (form.key && destroyStrategy !== 'retain') {
19711967

1972-
// We can get undefined here if the form hasn't been filled out entirely
1973-
if (obj === undefined) {
1974-
return;
1975-
}
1968+
// Get the object that has the property we wan't to clear.
1969+
var obj = scope.model;
1970+
if (form.key.length > 1) {
1971+
obj = sfSelect(form.key.slice(0, form.key.length - 1), obj);
1972+
}
1973+
1974+
// We can get undefined here if the form hasn't been filled out entirely
1975+
if (obj === undefined) {
1976+
return;
1977+
}
1978+
1979+
// Type can also be a list in JSON Schema
1980+
var type = (form.schema && form.schema.type) || '';
19761981

1977-
// Type can also be a list in JSON Schema
1978-
var type = (form.schema && form.schema.type) || '';
1979-
1980-
// Empty means '',{} and [] for appropriate types and undefined for the rest
1981-
//console.log('destroy', destroyStrategy, form.key, type, obj);
1982-
if (destroyStrategy === 'empty' && type.indexOf('string') !== -1) {
1983-
obj[form.key.slice(-1)] = '';
1984-
} else if (destroyStrategy === 'empty' && type.indexOf('object') !== -1) {
1985-
obj[form.key.slice(-1)] = {};
1986-
} else if (destroyStrategy === 'empty' && type.indexOf('array') !== -1) {
1987-
obj[form.key.slice(-1)] = [];
1988-
} else if (destroyStrategy === 'null') {
1989-
obj[form.key.slice(-1)] = null;
1990-
} else {
1991-
delete obj[form.key.slice(-1)];
1982+
// Empty means '',{} and [] for appropriate types and undefined for the rest
1983+
//console.log('destroy', destroyStrategy, form.key, type, obj);
1984+
if (destroyStrategy === 'empty' && type.indexOf('string') !== -1) {
1985+
obj[form.key.slice(-1)] = '';
1986+
} else if (destroyStrategy === 'empty' && type.indexOf('object') !== -1) {
1987+
obj[form.key.slice(-1)] = {};
1988+
} else if (destroyStrategy === 'empty' && type.indexOf('array') !== -1) {
1989+
obj[form.key.slice(-1)] = [];
1990+
} else if (destroyStrategy === 'null') {
1991+
obj[form.key.slice(-1)] = null;
1992+
} else {
1993+
delete obj[form.key.slice(-1)];
1994+
}
19921995
}
19931996
}
1994-
}
1995-
});
1996-
}
1997+
});
1998+
}
19971999

1998-
once();
1999-
}
2000-
});
2000+
once();
2001+
}
2002+
});
2003+
}
20012004
}
20022005
};
20032006
}

‎dist/schema-form.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/directives/field.js

Lines changed: 236 additions & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -10,277 +10,280 @@ angular.module('schemaForm').directive('sfField',
1010
transclude: false,
1111
scope: true,
1212
require: '?^sfSchema',
13-
link: function(scope, element, attrs, sfSchema) {
13+
link: {
14+
pre: function(scope, element, attrs, sfSchema) {
15+
//The ngModelController is used in some templates and
16+
//is needed for error messages,
17+
scope.$on('schemaFormPropagateNgModelController', function(event, ngModel) {
18+
event.stopPropagation();
19+
event.preventDefault();
20+
scope.ngModel = ngModel;
21+
});
22+
},
23+
post: function(scope, element, attrs, sfSchema) {
1424

15-
//The ngModelController is used in some templates and
16-
//is needed for error messages,
17-
scope.$on('schemaFormPropagateNgModelController', function(event, ngModel) {
18-
event.stopPropagation();
19-
event.preventDefault();
20-
scope.ngModel = ngModel;
21-
});
25+
//Keep error prone logic from the template
26+
scope.showTitle = function() {
27+
return scope.form && scope.form.notitle !== true && scope.form.title;
28+
};
2229

23-
//Keep error prone logic from the template
24-
scope.showTitle = function() {
25-
return scope.form && scope.form.notitle !== true && scope.form.title;
26-
};
30+
scope.listToCheckboxValues = function(list) {
31+
var values = {};
32+
angular.forEach(list, function(v) {
33+
values[v] = true;
34+
});
35+
return values;
36+
};
2737

28-
scope.listToCheckboxValues = function(list) {
29-
var values = {};
30-
angular.forEach(list, function(v) {
31-
values[v] = true;
32-
});
33-
return values;
34-
};
38+
scope.checkboxValuesToList = function(values) {
39+
var lst = [];
40+
angular.forEach(values, function(v, k) {
41+
if (v) {
42+
lst.push(k);
43+
}
44+
});
45+
return lst;
46+
};
3547

36-
scope.checkboxValuesToList = function(values) {
37-
var lst = [];
38-
angular.forEach(values, function(v, k) {
39-
if (v) {
40-
lst.push(k);
48+
scope.buttonClick = function($event, form) {
49+
if (angular.isFunction(form.onClick)) {
50+
form.onClick($event, form);
51+
} else if (angular.isString(form.onClick)) {
52+
if (sfSchema) {
53+
//evaluating in scope outside of sfSchemas isolated scope
54+
sfSchema.evalInParentScope(form.onClick, {'$event': $event, form: form});
55+
} else {
56+
scope.$eval(form.onClick, {'$event': $event, form: form});
57+
}
4158
}
42-
});
43-
return lst;
44-
};
59+
};
4560

46-
scope.buttonClick = function($event, form) {
47-
if (angular.isFunction(form.onClick)) {
48-
form.onClick($event, form);
49-
} else if (angular.isString(form.onClick)) {
61+
/**
62+
* Evaluate an expression, i.e. scope.$eval
63+
* but do it in sfSchemas parent scope sf-schema directive is used
64+
* @param {string} expression
65+
* @param {Object} locals (optional)
66+
* @return {Any} the result of the expression
67+
*/
68+
scope.evalExpr = function(expression, locals) {
5069
if (sfSchema) {
5170
//evaluating in scope outside of sfSchemas isolated scope
52-
sfSchema.evalInParentScope(form.onClick, {'$event': $event, form: form});
53-
} else {
54-
scope.$eval(form.onClick, {'$event': $event, form: form});
71+
return sfSchema.evalInParentScope(expression, locals);
5572
}
56-
}
57-
};
5873

59-
/**
60-
* Evaluate an expression, i.e. scope.$eval
61-
* but do it in sfSchemas parent scope sf-schema directive is used
62-
* @param {string} expression
63-
* @param {Object} locals (optional)
64-
* @return {Any} the result of the expression
65-
*/
66-
scope.evalExpr = function(expression, locals) {
67-
if (sfSchema) {
68-
//evaluating in scope outside of sfSchemas isolated scope
69-
return sfSchema.evalInParentScope(expression, locals);
70-
}
71-
72-
return scope.$eval(expression, locals);
73-
};
74-
75-
/**
76-
* Evaluate an expression, i.e. scope.$eval
77-
* in this decorators scope
78-
* @param {string} expression
79-
* @param {Object} locals (optional)
80-
* @return {Any} the result of the expression
81-
*/
82-
scope.evalInScope = function(expression, locals) {
83-
if (expression) {
8474
return scope.$eval(expression, locals);
85-
}
86-
};
75+
};
8776

88-
/**
89-
* Interpolate the expression.
90-
* Similar to `evalExpr()` and `evalInScope()`
91-
* but will not fail if the expression is
92-
* text that contains spaces.
93-
*
94-
* Use the Angular `{{ interpolation }}`
95-
* braces to access properties on `locals`.
96-
*
97-
* @param {string} content The string to interpolate.
98-
* @param {Object} locals (optional) Properties that may be accessed in the
99-
* `expression` string.
100-
* @return {Any} The result of the expression or `undefined`.
101-
*/
102-
scope.interp = function(expression, locals) {
103-
return (expression && $interpolate(expression)(locals));
104-
};
77+
/**
78+
* Evaluate an expression, i.e. scope.$eval
79+
* in this decorators scope
80+
* @param {string} expression
81+
* @param {Object} locals (optional)
82+
* @return {Any} the result of the expression
83+
*/
84+
scope.evalInScope = function(expression, locals) {
85+
if (expression) {
86+
return scope.$eval(expression, locals);
87+
}
88+
};
10589

106-
//This works since we ot the ngModel from the array or the schema-validate directive.
107-
scope.hasSuccess = function() {
108-
if (!scope.ngModel) {
109-
return false;
110-
}
111-
return scope.ngModel.$valid &&
112-
(!scope.ngModel.$pristine || !scope.ngModel.$isEmpty(scope.ngModel.$modelValue));
113-
};
90+
/**
91+
* Interpolate the expression.
92+
* Similar to `evalExpr()` and `evalInScope()`
93+
* but will not fail if the expression is
94+
* text that contains spaces.
95+
*
96+
* Use the Angular `{{ interpolation }}`
97+
* braces to access properties on `locals`.
98+
*
99+
* @param {string} content The string to interpolate.
100+
* @param {Object} locals (optional) Properties that may be accessed in the
101+
* `expression` string.
102+
* @return {Any} The result of the expression or `undefined`.
103+
*/
104+
scope.interp = function(expression, locals) {
105+
return (expression && $interpolate(expression)(locals));
106+
};
114107

115-
scope.hasError = function() {
116-
if (!scope.ngModel) {
117-
return false;
118-
}
119-
return scope.ngModel.$invalid && !scope.ngModel.$pristine;
120-
};
108+
//This works since we ot the ngModel from the array or the schema-validate directive.
109+
scope.hasSuccess = function() {
110+
if (!scope.ngModel) {
111+
return false;
112+
}
113+
return scope.ngModel.$valid &&
114+
(!scope.ngModel.$pristine || !scope.ngModel.$isEmpty(scope.ngModel.$modelValue));
115+
};
121116

122-
/**
123-
* DEPRECATED: use sf-messages instead.
124-
* Error message handler
125-
* An error can either be a schema validation message or a angular js validtion
126-
* error (i.e. required)
127-
*/
128-
scope.errorMessage = function(schemaError) {
129-
return sfErrorMessage.interpolate(
130-
(schemaError && schemaError.code + '') || 'default',
131-
(scope.ngModel && scope.ngModel.$modelValue) || '',
132-
(scope.ngModel && scope.ngModel.$viewValue) || '',
133-
scope.form,
134-
scope.options && scope.options.validationMessage
135-
);
136-
};
117+
scope.hasError = function() {
118+
if (!scope.ngModel) {
119+
return false;
120+
}
121+
return scope.ngModel.$invalid && !scope.ngModel.$pristine;
122+
};
137123

138-
// Rebind our part of the form to the scope.
139-
var once = scope.$watch(attrs.sfField, function(form) {
140-
if (form) {
141-
console.warn('got form!!!!', form)
142-
// Workaround for 'updateOn' error from ngModelOptions
143-
// see https://github.com/Textalk/angular-schema-form/issues/255
144-
// and https://github.com/Textalk/angular-schema-form/issues/206
145-
form.ngModelOptions = form.ngModelOptions || {};
146-
scope.form = form;
124+
/**
125+
* DEPRECATED: use sf-messages instead.
126+
* Error message handler
127+
* An error can either be a schema validation message or a angular js validtion
128+
* error (i.e. required)
129+
*/
130+
scope.errorMessage = function(schemaError) {
131+
return sfErrorMessage.interpolate(
132+
(schemaError && schemaError.code + '') || 'default',
133+
(scope.ngModel && scope.ngModel.$modelValue) || '',
134+
(scope.ngModel && scope.ngModel.$viewValue) || '',
135+
scope.form,
136+
scope.options && scope.options.validationMessage
137+
);
138+
};
147139

148-
/*
149-
//ok let's replace that template!
150-
//We do this manually since we need to bind ng-model properly and also
151-
//for fieldsets to recurse properly.
152-
var templatePromise;
140+
// Rebind our part of the form to the scope.
141+
var once = scope.$watch(attrs.sfField, function(form) {
142+
if (form) {
143+
console.warn('got form!!!!', form)
144+
// Workaround for 'updateOn' error from ngModelOptions
145+
// see https://github.com/Textalk/angular-schema-form/issues/255
146+
// and https://github.com/Textalk/angular-schema-form/issues/206
147+
form.ngModelOptions = form.ngModelOptions || {};
148+
scope.form = form;
153149

154-
// type: "template" is a special case. It can contain a template inline or an url.
155-
// otherwise we find out the url to the template and load them.
156-
if (form.type === 'template' && form.template) {
157-
templatePromise = $q.when(form.template);
158-
} else {
159-
var url = form.type === 'template' ? form.templateUrl : templateUrl(name, form);
160-
templatePromise = $http.get(url, {cache: $templateCache}).then(function(res) {
161-
return res.data;
162-
});
163-
}
164-
*/
165-
/*
166-
templatePromise.then(function(template) {
167-
if (form.key) {
168-
var key = form.key ?
169-
sfPathProvider.stringify(form.key).replace(/"/g, '"') : '';
170-
template = template.replace(
171-
/\$\$value\$\$/g,
172-
'model' + (key[0] !== '[' ? '.' : '') + key
173-
);
174-
}
175-
element.html(template);
176-
*/
177-
// Do we have a condition? Then we slap on an ng-if on all children,
178-
// but be nice to existing ng-if.
179-
/*if (form.condition) {
150+
/*
151+
//ok let's replace that template!
152+
//We do this manually since we need to bind ng-model properly and also
153+
//for fieldsets to recurse properly.
154+
var templatePromise;
180155
181-
var evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex})';
156+
// type: "template" is a special case. It can contain a template inline or an url.
157+
// otherwise we find out the url to the template and load them.
158+
if (form.type === 'template' && form.template) {
159+
templatePromise = $q.when(form.template);
160+
} else {
161+
var url = form.type === 'template' ? form.templateUrl : templateUrl(name, form);
162+
templatePromise = $http.get(url, {cache: $templateCache}).then(function(res) {
163+
return res.data;
164+
});
165+
}
166+
*/
167+
/*
168+
templatePromise.then(function(template) {
182169
if (form.key) {
183-
evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex, "modelValue": model' + sfPath.stringify(form.key) + '})';
184-
}
185-
186-
angular.forEach(element.children(), function(child) {
187-
var ngIf = child.getAttribute('ng-if');
188-
child.setAttribute(
189-
'ng-if',
190-
ngIf ?
191-
'(' + ngIf +
192-
') || (' + evalExpr +')'
193-
: evalExpr
170+
var key = form.key ?
171+
sfPathProvider.stringify(form.key).replace(/"/g, '"') : '';
172+
template = template.replace(
173+
/\$\$value\$\$/g,
174+
'model' + (key[0] !== '[' ? '.' : '') + key
194175
);
195-
});
196-
}*/
197-
//$compile(element.contents())(scope);
198-
//});
176+
}
177+
element.html(template);
178+
*/
179+
// Do we have a condition? Then we slap on an ng-if on all children,
180+
// but be nice to existing ng-if.
181+
/*if (form.condition) {
199182
200-
// Where there is a key there is probably a ngModel
201-
if (form.key) {
202-
// It looks better with dot notation.
203-
scope.$on(
204-
'schemaForm.error.' + form.key.join('.'),
205-
function(event, error, validationMessage, validity) {
206-
if (validationMessage === true || validationMessage === false) {
207-
validity = validationMessage;
208-
validationMessage = undefined;
183+
var evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex})';
184+
if (form.key) {
185+
evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex, "modelValue": model' + sfPath.stringify(form.key) + '})';
209186
}
210187
211-
if (scope.ngModel && error) {
212-
if (scope.ngModel.$setDirty()) {
213-
scope.ngModel.$setDirty();
214-
} else {
215-
// FIXME: Check that this actually works on 1.2
216-
scope.ngModel.$dirty = true;
217-
scope.ngModel.$pristine = false;
188+
angular.forEach(element.children(), function(child) {
189+
var ngIf = child.getAttribute('ng-if');
190+
child.setAttribute(
191+
'ng-if',
192+
ngIf ?
193+
'(' + ngIf +
194+
') || (' + evalExpr +')'
195+
: evalExpr
196+
);
197+
});
198+
}*/
199+
//$compile(element.contents())(scope);
200+
//});
201+
202+
// Where there is a key there is probably a ngModel
203+
if (form.key) {
204+
// It looks better with dot notation.
205+
scope.$on(
206+
'schemaForm.error.' + form.key.join('.'),
207+
function(event, error, validationMessage, validity) {
208+
if (validationMessage === true || validationMessage === false) {
209+
validity = validationMessage;
210+
validationMessage = undefined;
218211
}
219212

220-
// Set the new validation message if one is supplied
221-
// Does not work when validationMessage is just a string.
222-
if (validationMessage) {
223-
if (!form.validationMessage) {
224-
form.validationMessage = {};
213+
if (scope.ngModel && error) {
214+
if (scope.ngModel.$setDirty()) {
215+
scope.ngModel.$setDirty();
216+
} else {
217+
// FIXME: Check that this actually works on 1.2
218+
scope.ngModel.$dirty = true;
219+
scope.ngModel.$pristine = false;
225220
}
226-
form.validationMessage[error] = validationMessage;
227-
}
228221

229-
scope.ngModel.$setValidity(error, validity === true);
222+
// Set the new validation message if one is supplied
223+
// Does not work when validationMessage is just a string.
224+
if (validationMessage) {
225+
if (!form.validationMessage) {
226+
form.validationMessage = {};
227+
}
228+
form.validationMessage[error] = validationMessage;
229+
}
230230

231-
if (validity === true) {
232-
// Setting or removing a validity can change the field to believe its valid
233-
// but its not. So lets trigger its validation as well.
234-
scope.$broadcast('schemaFormValidate');
231+
scope.ngModel.$setValidity(error, validity === true);
232+
233+
if (validity === true) {
234+
// Setting or removing a validity can change the field to believe its valid
235+
// but its not. So lets trigger its validation as well.
236+
scope.$broadcast('schemaFormValidate');
237+
}
235238
}
236-
}
237-
});
239+
});
238240

239-
// Clean up the model when the corresponding form field is $destroy-ed.
240-
// Default behavior can be supplied as a globalOption, and behavior can be overridden in the form definition.
241-
scope.$on('$destroy', function() {
242-
// If the entire schema form is destroyed we don't touch the model
243-
if (!scope.externalDestructionInProgress) {
244-
var destroyStrategy = form.destroyStrategy ||
245-
(scope.options && scope.options.destroyStrategy) || 'remove';
246-
// No key no model, and we might have strategy 'retain'
247-
if (form.key && destroyStrategy !== 'retain') {
241+
// Clean up the model when the corresponding form field is $destroy-ed.
242+
// Default behavior can be supplied as a globalOption, and behavior can be overridden in the form definition.
243+
scope.$on('$destroy', function() {
244+
// If the entire schema form is destroyed we don't touch the model
245+
if (!scope.externalDestructionInProgress) {
246+
var destroyStrategy = form.destroyStrategy ||
247+
(scope.options && scope.options.destroyStrategy) || 'remove';
248+
// No key no model, and we might have strategy 'retain'
249+
if (form.key && destroyStrategy !== 'retain') {
248250

249-
// Get the object that has the property we wan't to clear.
250-
var obj = scope.model;
251-
if (form.key.length > 1) {
252-
obj = sfSelect(form.key.slice(0, form.key.length - 1), obj);
253-
}
251+
// Get the object that has the property we wan't to clear.
252+
var obj = scope.model;
253+
if (form.key.length > 1) {
254+
obj = sfSelect(form.key.slice(0, form.key.length - 1), obj);
255+
}
254256

255-
// We can get undefined here if the form hasn't been filled out entirely
256-
if (obj === undefined) {
257-
return;
258-
}
257+
// We can get undefined here if the form hasn't been filled out entirely
258+
if (obj === undefined) {
259+
return;
260+
}
259261

260-
// Type can also be a list in JSON Schema
261-
var type = (form.schema && form.schema.type) || '';
262+
// Type can also be a list in JSON Schema
263+
var type = (form.schema && form.schema.type) || '';
262264

263-
// Empty means '',{} and [] for appropriate types and undefined for the rest
264-
//console.log('destroy', destroyStrategy, form.key, type, obj);
265-
if (destroyStrategy === 'empty' && type.indexOf('string') !== -1) {
266-
obj[form.key.slice(-1)] = '';
267-
} else if (destroyStrategy === 'empty' && type.indexOf('object') !== -1) {
268-
obj[form.key.slice(-1)] = {};
269-
} else if (destroyStrategy === 'empty' && type.indexOf('array') !== -1) {
270-
obj[form.key.slice(-1)] = [];
271-
} else if (destroyStrategy === 'null') {
272-
obj[form.key.slice(-1)] = null;
273-
} else {
274-
delete obj[form.key.slice(-1)];
265+
// Empty means '',{} and [] for appropriate types and undefined for the rest
266+
//console.log('destroy', destroyStrategy, form.key, type, obj);
267+
if (destroyStrategy === 'empty' && type.indexOf('string') !== -1) {
268+
obj[form.key.slice(-1)] = '';
269+
} else if (destroyStrategy === 'empty' && type.indexOf('object') !== -1) {
270+
obj[form.key.slice(-1)] = {};
271+
} else if (destroyStrategy === 'empty' && type.indexOf('array') !== -1) {
272+
obj[form.key.slice(-1)] = [];
273+
} else if (destroyStrategy === 'null') {
274+
obj[form.key.slice(-1)] = null;
275+
} else {
276+
delete obj[form.key.slice(-1)];
277+
}
275278
}
276279
}
277-
}
278-
});
279-
}
280+
});
281+
}
280282

281-
once();
282-
}
283-
});
283+
once();
284+
}
285+
});
286+
}
284287
}
285288
};
286289
}

0 commit comments

Comments
 (0)
Please sign in to comment.