Skip to content

Commit 1b6bac1

Browse files
committedDec 19, 2014
Merge branch 'feature/optimizeinserts' into development
2 parents 91860e5 + fc1bce4 commit 1b6bac1

File tree

3 files changed

+76
-28
lines changed

3 files changed

+76
-28
lines changed
 

‎docs/index.md

+36
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Documentation
2525
1. [array](#array)
2626
1. [tabarray](#tabarray)
2727
1. [Post process function](#post-process-function)
28+
1. [Manual field insertion](#manual-field-insertion)
2829
1. [Extending Schema Form](extending.md)
2930

3031
Basic Usage
@@ -1010,3 +1011,38 @@ angular.module('myModule', ['schemaForm']).config(function(schemaFormProvider){
10101011

10111012
});
10121013
```
1014+
1015+
1016+
1017+
### Manual field insertion
1018+
There is a limited feature for controlling manually where a generated field should go so you can
1019+
,as an example, wrap it in custom html. Consider the feature experimental.
1020+
1021+
It has a number of drawbacks though.
1022+
1023+
1. You can only insert fields that are in the root level of your form definition, i.e. not inside fieldset, arrays etc.
1024+
1. Generated fields are always last in the form so if you don't supply slots for all of your top level fields the rest goes below.
1025+
1. To match "keys" of forms we match against the internal array format, hence the key "name" becomes "['name']" and "foo.bar" becomes "['foo']['bar']"
1026+
1027+
Define "slots" for the generated field by adding an element with the attribute `sf-insert-field`
1028+
1029+
ex.
1030+
```js
1031+
$scope.form = [
1032+
"name",
1033+
"email",
1034+
"comment"
1035+
]
1036+
```
1037+
1038+
```html
1039+
<form sf-model="model"
1040+
sf-form="form"
1041+
sf-schema="schema">
1042+
<em>before</em>
1043+
<div sf-insert-field="['email']"></div>
1044+
<em>after</em>
1045+
1046+
<!-- the rest of the form, i.e. name and comment will be generated here -->
1047+
</form>
1048+
```

‎src/directives/schema-form.js

+28-16
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ FIXME: real documentation
55

66
angular.module('schemaForm')
77
.directive('sfSchema',
8-
['$compile', 'schemaForm', 'schemaFormDecorators', 'sfSelect',
9-
function($compile, schemaForm, schemaFormDecorators, sfSelect) {
8+
['$compile', 'schemaForm', 'schemaFormDecorators', 'sfSelect', 'sfPath',
9+
function($compile, schemaForm, schemaFormDecorators, sfSelect, sfPath) {
1010

1111
var SNAKE_CASE_REGEXP = /[A-Z]/g;
1212
var snakeCase = function(name, separator) {
@@ -83,23 +83,35 @@ angular.module('schemaForm')
8383
//clean all but pre existing html.
8484
element.children(':not(.schema-form-ignore)').remove();
8585

86+
// Find all slots.
87+
var slots = {};
88+
var slotsFound = element[0].querySelectorAll('*[sf-insert-field]');
89+
90+
for (var i = 0; i < slotsFound.length; i++) {
91+
slots[slotsFound[i].getAttribute('sf-insert-field')] = slotsFound[i];
92+
}
93+
8694
//Create directives from the form definition
87-
angular.forEach(merged,function(obj,i){
88-
var n = document.createElement(attrs.sfDecorator || snakeCase(schemaFormDecorators.defaultDecorator,'-'));
95+
angular.forEach(merged, function(obj, i) {
96+
var n = document.createElement(attrs.sfDecorator ||
97+
snakeCase(schemaFormDecorators.defaultDecorator, '-'));
8998
n.setAttribute('form','schemaForm.form['+i+']');
90-
var slot;
91-
try {
92-
slot = element[0].querySelector('*[sf-insert-field="' + obj.key + '"]');
93-
} catch(err) {
94-
// field insertion not supported for complex keys
95-
slot = null;
96-
}
97-
if(slot) {
98-
slot.innerHTML = "";
99-
slot.appendChild(n);
100-
} else {
101-
frag.appendChild(n);
99+
100+
// Check if there is a slot to put this in...
101+
if (obj.key) {
102+
var slot = slots[sfPath.stringify(obj.key)];
103+
if (slot) {
104+
while (slot.firstChild) {
105+
slot.removeChild(slot.firstChild);
106+
}
107+
slot.appendChild(n);
108+
return;
109+
}
102110
}
111+
112+
// ...otherwise add it to the frag
113+
frag.appendChild(n);
114+
103115
});
104116

105117
element[0].appendChild(frag);

‎test/directives/schema-form-test.js

+12-12
Original file line numberDiff line numberDiff line change
@@ -173,17 +173,17 @@ describe('directive',function(){
173173
});
174174
});
175175

176-
it('should preserve existing html and insert fields in matching slots',function(){
176+
it('should preserve existing html and insert fields in matching slots', function() {
177177

178-
inject(function($compile,$rootScope){
178+
inject(function($compile, $rootScope){
179179
var scope = $rootScope.$new();
180180
scope.person = {};
181181

182182
scope.schema = exampleSchema;
183183

184-
scope.form = ["*"];
184+
scope.form = ['*'];
185185

186-
var tmpl = angular.element('<form sf-schema="schema" sf-form="form" sf-model="person"><ul><li sf-insert-field="name"></li></ul></form>');
186+
var tmpl = angular.element('<form sf-schema="schema" sf-form="form" sf-model="person"><ul><li sf-insert-field="[\'name\']"></li></ul></form>');
187187

188188
$compile(tmpl)(scope);
189189
$rootScope.$apply();
@@ -192,7 +192,7 @@ describe('directive',function(){
192192
tmpl.children().eq(0).find('input').attr('ng-model').should.be.equal('model[\'name\']');
193193
});
194194
});
195-
195+
196196

197197
it('should handle submit buttons',function(){
198198

@@ -592,7 +592,7 @@ describe('directive',function(){
592592

593593
});
594594
});
595-
595+
596596
it('should handle schema form default in deep structure',function(){
597597

598598
inject(function($compile,$rootScope){
@@ -1725,8 +1725,8 @@ describe('directive',function(){
17251725
tmpl.children().eq(0).find('select').eq(0).find('option').eq(2).text().trim().should.be.eq('The A');
17261726
});
17271727
});
1728-
1729-
1728+
1729+
17301730
it('should update array form on model array ref change',function(){
17311731

17321732
inject(function($compile,$rootScope){
@@ -1772,7 +1772,7 @@ describe('directive',function(){
17721772
$rootScope.$apply();
17731773

17741774
tmpl.children().eq(0).find('ol').children().length.should.be.eq(2);
1775-
1775+
17761776
var new_names = [
17771777
{
17781778
firstname: 'Bill',
@@ -1789,11 +1789,11 @@ describe('directive',function(){
17891789
lastname: 'Buster'
17901790
}
17911791
];
1792-
1792+
17931793
scope.person.names = new_names;
1794-
1794+
17951795
$rootScope.$apply();
1796-
1796+
17971797
tmpl.children().eq(0).find('ol').children().length.should.be.eq(4);
17981798
});
17991799
});

0 commit comments

Comments
 (0)
Please sign in to comment.