Skip to content

Commit 5a3b80c

Browse files
committed
Template field type
Make one shot add-ons with the template type.
1 parent 523a0f0 commit 5a3b80c

File tree

3 files changed

+128
-10
lines changed

3 files changed

+128
-10
lines changed

docs/index.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Documentation
2424
1. [button](#button)
2525
1. [radios and radiobuttons](#radios-and-radiobuttons)
2626
1. [help](#help)
27+
1. [template](#template)
2728
1. [tabs](#tabs)
2829
1. [array](#array)
2930
1. [tabarray](#tabarray)
@@ -351,6 +352,7 @@ Schema Form currently supports the following form field types out of the box:
351352
| radios-inline | radio buttons in one line |
352353
| radiobuttons | radio buttons with bootstrap buttons |
353354
| help | insert arbitrary html |
355+
| template | insert an angular template |
354356
| tab | tabs with content |
355357
| array | a list you can add, remove and reorder |
356358
| tabarray | a tabbed version of array |
@@ -905,6 +907,39 @@ function FormCtrl($scope) {
905907
}
906908
```
907909
910+
### template
911+
`template` fields are like `help` fields but instead of arbitrary html you can insert or refer to
912+
an angular template to be inserted where the field should go. There is one catch though and that
913+
is that the scope is that of the decorator directive and its inside the isolated scope of the
914+
`sf-schema` directive, so anything you like to access in the template should be put on the form,
915+
which is available in template. It's basically a simple one shot version of add-ons, so see the
916+
see the docs on [Extending Schema Form](extending.md) for details on what is on scope and what's up
917+
with `$$value$$`
918+
919+
920+
921+
The `template` type should either have a `template` or a `templateUrl` option.
922+
923+
Ex.
924+
```javascript
925+
function FormCtrl($scope) {
926+
927+
$scope.form = [
928+
{
929+
type: "template",
930+
template: '<h1 ng-click="form.foo()">Yo {{form.name}}!</h1>',
931+
name: 'Ninja',
932+
foo: function() { console.log('oh noes!'); }
933+
},
934+
{
935+
type: "template",
936+
templateUrl: "templates/foo.html",
937+
myFavouriteVariable: 'OMG!!'
938+
}
939+
];
940+
}
941+
```
942+
908943
### tabs
909944
The `tabs` form type lets you split your form into tabs. It is similar to
910945
`fieldset` in that it just changes the presentation of the form. `tabs`

src/services/decorators.js

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ angular.module('schemaForm').provider('schemaFormDecorators',
3131

3232
var createDirective = function(name) {
3333
$compileProvider.directive(name,
34-
['$parse', '$compile', '$http', '$templateCache', '$interpolate','sfErrorMessage',
35-
function($parse, $compile, $http, $templateCache, $interpolate, sfErrorMessage) {
34+
['$parse', '$compile', '$http', '$templateCache', '$interpolate', '$q', 'sfErrorMessage',
35+
function($parse, $compile, $http, $templateCache, $interpolate, $q, sfErrorMessage) {
3636

3737
return {
3838
restrict: 'AE',
@@ -176,14 +176,28 @@ angular.module('schemaForm').provider('schemaFormDecorators',
176176
//ok let's replace that template!
177177
//We do this manually since we need to bind ng-model properly and also
178178
//for fieldsets to recurse properly.
179-
var url = templateUrl(name, form);
180-
$http.get(url, {cache: $templateCache}).then(function(res) {
181-
var key = form.key ?
182-
sfPathProvider.stringify(form.key).replace(/"/g, '&quot;') : '';
183-
var template = res.data.replace(
184-
/\$\$value\$\$/g,
185-
'model' + (key[0] !== '[' ? '.' : '') + key
186-
);
179+
var templatePromise;
180+
181+
// type: "template" is a special case. It can contain a template inline or an url.
182+
// otherwise we find out the url to the template and load them.
183+
if (form.type === 'template' && form.template) {
184+
templatePromise = $q.when(form.template);
185+
} else {
186+
var url = form.type === 'template' ? form.templateUrl : templateUrl(name, form);
187+
templatePromise = $http.get(url, {cache: $templateCache}).then(function(res) {
188+
return res.data;
189+
});
190+
}
191+
192+
templatePromise.then(function(template) {
193+
if (form.key) {
194+
var key = form.key ?
195+
sfPathProvider.stringify(form.key).replace(/"/g, '&quot;') : '';
196+
template = template.replace(
197+
/\$\$value\$\$/g,
198+
'model' + (key[0] !== '[' ? '.' : '') + key
199+
);
200+
}
187201
element.html(template);
188202

189203
// Do we have a condition? Then we slap on an ng-if on all children,

test/directives/schema-form-test.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,5 +1754,74 @@ describe('directive',function(){
17541754
});
17551755
});
17561756

1757+
it('should use supplied template with template field type',function() {
1758+
1759+
inject(function($compile, $rootScope){
1760+
var scope = $rootScope.$new();
1761+
scope.person = {};
1762+
1763+
scope.schema = {
1764+
type: 'object',
1765+
properties: {
1766+
name: {type: 'string'}
1767+
}
1768+
};
1769+
1770+
scope.form = [
1771+
{
1772+
type: 'template',
1773+
template: '<div>{{form.foo}}</div>',
1774+
foo: "Hello World"
1775+
}
1776+
];
1777+
1778+
var tmpl = angular.element('<form sf-schema="schema" sf-form="form" sf-model="person"></form>');
1779+
1780+
$compile(tmpl)(scope);
1781+
$rootScope.$apply();
1782+
1783+
tmpl.children().eq(0).html().should.be.eq('<div class="ng-binding ng-scope">Hello World</div>')
1784+
1785+
});
1786+
});
1787+
1788+
it('should load template by templateUrl, with template field type',function() {
1789+
1790+
inject(function($compile, $rootScope, $httpBackend){
1791+
1792+
$httpBackend.when('GET', '/template.html')
1793+
.respond("<div>{{form.foo}}</div>");
1794+
1795+
var scope = $rootScope.$new();
1796+
scope.person = {};
1797+
1798+
scope.schema = {
1799+
type: 'object',
1800+
properties: {
1801+
name: {type: 'string'}
1802+
}
1803+
};
1804+
1805+
scope.form = [
1806+
{
1807+
type: 'template',
1808+
templateUrl: '/template.html',
1809+
foo: 'Hello World'
1810+
}
1811+
];
1812+
1813+
var tmpl = angular.element('<form sf-schema="schema" sf-form="form" sf-model="person"></form>');
1814+
1815+
$compile(tmpl)(scope);
1816+
$rootScope.$apply();
1817+
$httpBackend.flush();
1818+
$httpBackend.verifyNoOutstandingExpectation();
1819+
$httpBackend.verifyNoOutstandingRequest();
1820+
1821+
tmpl.children().eq(0).html().should.be.eq('<div class="ng-binding ng-scope">Hello World</div>')
1822+
1823+
});
1824+
});
1825+
17571826

17581827
});

0 commit comments

Comments
 (0)