Skip to content

Commit ce4ba1c

Browse files
committed
Initial remote data load for select
Still needs filtering and default options etc...
1 parent 963d775 commit ce4ba1c

6 files changed

+195
-52
lines changed
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"titleMap": [
3+
{ "value": "jkr1", "name": "Harry Potter", "group": "Childrens" },
4+
{ "value": "eb1", "name": "Blinky Bill", "group": "Childrens" },
5+
{ "value": "da1", "name": "A Hitchhiker's Guide To The Galaxy", "group": "Sci-Fi" },
6+
{ "value": "ow1", "name": "The Picture of Dorian Gray", "group": "Horror" },
7+
{ "value": "wc", "name": "A Nightmare On Elm Street", "group": "Horror" }
8+
]
9+
}
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"titleMap": [
3+
{ "value": "ss1", "name": "Demolition Man", "group": "Stallone" },
4+
{ "value": "ss2", "name": "Rocky", "group": "Stallone" },
5+
{ "value": "ss3", "name": "Rambo", "group": "Stallone" },
6+
{ "value": "jcvd1", "name": "Double Impact", "group": "Van Damme" },
7+
{ "value": "jcvd2", "name": "Bloodsport", "group": "Van Damme" },
8+
{ "value": "jcvd3", "name": "Kickboxer", "group": "Van Damme" }
9+
]
10+
}

examples/data/titlemaps.json

+29-15
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,23 @@
1717
"enum": ["a","b","c"]
1818
},
1919
"noenum": { "type": "string", "title": "No enum, but forms says it's a select", "default": "a3" },
20-
"selectOptionData": { "type": "string", "title": "Dynamic Options", "default": "The Terminator" },
20+
"selectOptionData": {
21+
"type": "string",
22+
"title": "Dynamic Options",
23+
"default": "The Terminator"
24+
},
25+
"radios": {
26+
"title": "Basic radio button example to pick remote dataset",
27+
"type": "string",
28+
"enum": ["books","movies"]
29+
},
30+
"selectOptionRemote": {
31+
"type": "string",
32+
"title": "Remote Options",
33+
"links":[
34+
{ "rel": "options", "href": "./data/remote-titlemap-{radios}.json" }
35+
]
36+
},
2137
"array": {
2238
"title": "Array with enum defaults to 'checkboxes'",
2339
"type": "array",
@@ -35,11 +51,6 @@
3551
"enum": ["a","b","c"]
3652
}
3753
},
38-
"radios": {
39-
"title": "Basic radio button example",
40-
"type": "string",
41-
"enum": ["a","b","c"]
42-
},
4354
"radiobuttons": {
4455
"title": "Radio buttons used to switch a boolean or multiple values",
4556
"type": "boolean",
@@ -81,6 +92,18 @@
8192
"key": "selectOptionData",
8293
"type": "select",
8394
"optionData": "arnieFlix"
95+
},
96+
{
97+
"key": "radios",
98+
"type": "radios",
99+
"titleMap": [
100+
{ "value":"books", "name": "Books" },
101+
{ "value":"movies", "name":"Movies" }
102+
]
103+
},
104+
{
105+
"key": "selectOptionRemote",
106+
"type": "select"
84107
}
85108
]
86109
},
@@ -94,15 +117,6 @@
94117
{ "value":"c", "name":"C" }
95118
]
96119
},
97-
{
98-
"key": "radios",
99-
"type": "radios",
100-
"titleMap": [
101-
{ "value":"c", "name": "C" },
102-
{ "value":"b", "name":"B" },
103-
{ "value":"a", "name":"A" }
104-
]
105-
},
106120
{
107121
"key":"radiobuttons",
108122
"type": "radiobuttons",

material-decorator.js

+73-18
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,19 @@ $templateCache.put("decorators/material/switch.html","<md-input-container class=
2323
$templateCache.put("decorators/material/tabarray.html","<div sf-array=\"form\" ng-init=\"selected = { tab: 0 }\" class=\"clearfix schema-form-tabarray schema-form-tabarray-{{form.tabType || \'left\'}} {{form.htmlClass}}\"><div ng-if=\"!form.tabType || form.tabType !== \'right\'\" ng-class=\"{\'col-xs-3\': !form.tabType || form.tabType === \'left\'}\"><ul class=\"nav nav-tabs\" ng-class=\"{ \'tabs-left\': !form.tabType || form.tabType === \'left\'}\"><li ng-repeat=\"item in modelArray track by $index\" ng-click=\"$event.preventDefault() || (selected.tab = $index)\" ng-class=\"{active: selected.tab === $index}\"><a href=\"#\">{{interp(form.title,{\'$index\':$index, value: item}) || $index}}</a></li><li ng-hide=\"form.readonly\" ng-click=\"$event.preventDefault() || (selected.tab = appendToArray().length - 1)\"><a href=\"#\"><i class=\"glyphicon glyphicon-plus\"></i> {{ form.add || \'Add\'}}</a></li></ul></div><div ng-class=\"{\'col-xs-9\': !form.tabType || form.tabType === \'left\' || form.tabType === \'right\'}\"><div class=\"tab-content {{form.fieldHtmlClass}}\"><div class=\"tab-pane clearfix\" ng-repeat=\"item in modelArray track by $index\" ng-show=\"selected.tab === $index\" ng-class=\"{active: selected.tab === $index}\"><sf-decorator ng-init=\"arrayIndex = $index\" form=\"copyWithIndex($index)\"></sf-decorator><button ng-hide=\"form.readonly\" ng-click=\"selected.tab = deleteFromArray($index).length - 1\" type=\"button\" class=\"btn {{ form.style.remove || \'btn-default\' }} pull-right\"><i class=\"glyphicon glyphicon-trash\"></i> {{ form.remove || \'Remove\'}}</button></div></div></div><div ng-if=\"form.tabType === \'right\'\" class=\"col-xs-3\"><ul class=\"nav nav-tabs tabs-right\"><li ng-repeat=\"item in modelArray track by $index\" ng-click=\"$event.preventDefault() || (selected.tab = $index)\" ng-class=\"{active: selected.tab === $index}\"><a href=\"#\">{{interp(form.title,{\'$index\':$index, value: item}) || $index}}</a></li><li ng-hide=\"form.readonly\" ng-click=\"$event.preventDefault() || appendToArray()\"><a href=\"#\"><i class=\"glyphicon glyphicon-plus\"></i> {{ form.add || \'Add\'}}</a></li></ul></div></div>");
2424
$templateCache.put("decorators/material/tabs.html","<div sf-field-model=\"\" class=\"schema-form-tabs {{::form.htmlClass}}\"><md-tabs md-dynamic-height=\"\" md-selected=\"selected\" md-autoselect=\"\" ng-init=\"selected = 0\"></md-tabs></div>");
2525
$templateCache.put("decorators/material/textarea.html","<md-input-container class=\"{{::form.htmlClass}} schema-form-textarea\" sf-messages=\"\"><label ng-show=\"showTitle()\" for=\"{{::form.key|sfCamelKey}}\">{{::form.title}}</label> <textarea ng-class=\"::form.fieldHtmlClass\" id=\"{{::form.key|sfCamelKey}}\" sf-changed=\"form\" ng-disabled=\"::form.readonly\" sf-field-model=\"\" schema-validate=\"form\" name=\"{{::form.key|sfCamelKey}}\"></textarea></md-input-container>");}]);
26-
(function (angular, undefined) {'use strict';
26+
(function(angular, undefined) {'use strict';
2727
angular
2828
.module('schemaForm')
2929
.config(materialDecoratorConfig)
30+
.directive('sfmExternalOptions', sfmExternalOptionsDirective)
3031
.filter('sfCamelKey', sfCamelKeyFilter);
3132

3233
materialDecoratorConfig.$inject = [
3334
'schemaFormProvider', 'schemaFormDecoratorsProvider', 'sfBuilderProvider', 'sfPathProvider', '$injector'
3435
];
3536

36-
function materialDecoratorConfig(schemaFormProvider, decoratorsProvider, sfBuilderProvider, sfPathProvider, $injector) {
37+
function materialDecoratorConfig(
38+
schemaFormProvider, decoratorsProvider, sfBuilderProvider, sfPathProvider, $injector) {
3739
var base = 'decorators/material/';
3840

3941
var simpleTransclusion = sfBuilderProvider.builders.simpleTransclusion;
@@ -134,31 +136,47 @@ $templateCache.put("decorators/material/textarea.html","<md-input-container clas
134136
};
135137

136138
function sfOptionsBuilder(args) {
139+
var mdSelectFrag = args.fieldFrag.querySelector('md-select');
137140
var enumTitleMap = [];
138141
var i;
139142
var mdSelectFrag;
140143

144+
args.form.selectOptions = [];
141145
args.form.getOptions = getOptionsHandler;
142146

143-
if (args.form.titleMap) {
144-
args.form.selectOptions = args.form.titleMap;
145-
}
146-
else if (args.form.enum && args.form.enum.length) {
147-
for (i = 0; i < args.form.enum.length; i++) {
148-
if (args.form.enum[i] && args.form.enum[i].length) {
149-
enumTitleMap.push({ name:args.form.enum[i], value:args.form.enum[i] });
147+
if (args.form.schema.links && (typeof args.form.schema.links) === 'object') {
148+
var link;
149+
var related = /({)([^}]*)(})/gm;
150+
var source = /{{([^}]*)}}/gm;
151+
var matched;
152+
153+
for (i = 0; i < args.form.schema.links.length; i++) {
154+
link = args.form.schema.links[i];
155+
if (link.rel === 'options') {
156+
// TODO enable filter to allow processing results
157+
// args.form.optionSource = link.href.replace(related, '$1$1 model.$2 | _externalOptionUri $3$3');
158+
args.form.optionSource = link.href.replace(related, '$1$1 model.$2 $3$3');
159+
// args.form.watchList = [];
160+
// matched = args.form.optionSource.match(source);
161+
// while ((matched = source.exec(args.form.optionSource)) !== null) {
162+
// args.form.watchList.push(matched);
163+
// };
150164
};
151165
};
152-
args.form.selectOptions = enumTitleMap;
166+
167+
mdSelectFrag.setAttribute('sfm-external-options', args.form.optionSource);
168+
}
169+
else {
170+
args.form.selectOptions = sfOptionsProcessor(args.form);
153171
};
154172

155173
// TODO implement $watch for remote data loading after the page loads
156-
function getOptionsHandler(form, evalExpr, $watch) {
157-
if(form.optionData) {
174+
function getOptionsHandler(form, evalExpr) {
175+
if (form.optionData) {
158176
return evalExpr(form.optionData);
159177
};
160178

161-
if(form.selectOptions) {
179+
if (form.selectOptions) {
162180
return form.selectOptions;
163181
};
164182

@@ -214,17 +232,54 @@ $templateCache.put("decorators/material/textarea.html","<md-input-container clas
214232
};
215233
};
216234

235+
function sfOptionsProcessor(data) {
236+
var enumTitleMap = [];
237+
238+
if (data.titleMap) {
239+
return data.titleMap;
240+
}
241+
else if (data.enum && data.enum.length) {
242+
for (i = 0; i < data.enum.length; i++) {
243+
if (data.enum[i] && data.enum[i].length) {
244+
enumTitleMap.push({ name: data.enum[i], value: data.enum[i] });
245+
};
246+
};
247+
};
248+
249+
return enumTitleMap;
250+
};
251+
252+
sfmExternalOptionsDirective.$inject = [ '$http' ];
253+
254+
function sfmExternalOptionsDirective($http) {
255+
var directive = {
256+
link: link,
257+
restrict: 'A'
258+
};
259+
260+
return directive;
261+
262+
function link(scope, element, attrs) {
263+
attrs.$observe('sfmExternalOptions', function(dataURI) {
264+
$http.get(dataURI)
265+
.then(function(response) {
266+
scope.form.selectOptions = sfOptionsProcessor(response.data);
267+
});
268+
});
269+
};
270+
};
271+
217272
/**
218273
* sfCamelKey Filter
219274
*/
220-
function sfCamelKeyFilter () {
221-
return function (formKey) {
222-
if(!formKey) return '';
275+
function sfCamelKeyFilter() {
276+
return function(formKey) {
277+
if (!formKey) { return ''; };
223278
var part, i, key;
224279
key = formKey.slice();
225-
for(i=0;i<key.length; i++){
280+
for (i = 0; i < key.length; i++) {
226281
part = key[i].toLowerCase().split('');
227-
if(i && part.length) part[0] = part[0].toUpperCase();
282+
if (i && part.length) { part[0] = part[0].toUpperCase(); };
228283
key[i] = part.join('');
229284
};
230285
return key.join('');

0 commit comments

Comments
 (0)