Skip to content
This repository was archived by the owner on Apr 30, 2018. It is now read-only.

Commit 34952e3

Browse files
committed
updated build to support multiple targets, stripped down existing templates to vanilla html, moved bootstrap templates to their own folder, added bootstrap build target
1 parent 6ba3440 commit 34952e3

28 files changed

+443
-46
lines changed

Gruntfile.js

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ module.exports = function(grunt) {
2727
src: ['**']
2828
},
2929
clean: {
30-
build: ['.tmp/**/*', 'dist/**/*']
30+
build: ['.tmp/**/*'],
31+
dist: ['dist/**/*']
3132
},
3233
copy: {
33-
build: {
34+
vanilla: {
3435
files: [
3536
{
3637
expand: true,
@@ -40,11 +41,21 @@ module.exports = function(grunt) {
4041
}
4142
]
4243
},
44+
bootstrap: {
45+
files: [
46+
{
47+
expand: true,
48+
cwd: '<%= formlyConfig.base %>/',
49+
src: ['directives/formly*.js', 'directives/bootstrap/formly*.html', 'modules/formly*.*', 'providers/formly*.*', '!.jshintrc'],
50+
dest: '.tmp/'
51+
}
52+
]
53+
},
4354
deploy: {
4455
files: [{
4556
expand: true,
46-
cwd: '.tmp',
47-
src: ['formly.js', 'formly.min.js', 'formly.min.map'],
57+
cwd: '.tmp/dist',
58+
src: ['formly*.*'],
4859
dest: 'dist/'
4960
}]
5061
}
@@ -57,24 +68,51 @@ module.exports = function(grunt) {
5768
}
5869
},
5970
uglify: {
60-
build: {
61-
src: '.tmp/formly.js',
62-
dest: '.tmp/formly.min.js'
71+
vanilla: {
72+
src: '.tmp/dist/formly.js',
73+
dest: '.tmp/dist/formly.min.js'
74+
},
75+
bootstrap: {
76+
src: '.tmp/dist/formly.bootstrap.js',
77+
dest: '.tmp/dist/formly.bootstrap.min.js'
6378
},
6479
options: {
6580
mangle: true,
6681
sourceMap: true
6782
}
6883
},
6984
ngtemplates: {
70-
build: {
85+
vanilla: {
86+
cwd: '.tmp/',
87+
src: [
88+
'directives/formly*.html'
89+
],
90+
dest: '.tmp/formly-templates.js',
91+
options: {
92+
module: 'formly.render',
93+
htmlmin: {
94+
collapseBooleanAttributes: true,
95+
collapseWhitespace: true,
96+
removeAttributeQuotes: true,
97+
removeComments: true, // Only if you don't use comment directives!
98+
removeEmptyAttributes: true,
99+
removeRedundantAttributes: false, //removing this as it can removes properties that can be used when styling
100+
removeScriptTypeAttributes: true,
101+
removeStyleLinkTypeAttributes: true
102+
}
103+
}
104+
},
105+
bootstrap: {
71106
cwd: '.tmp/',
72107
src: [
73-
'**/formly*.html'
108+
'directives/bootstrap/formly*.html'
74109
],
75110
dest: '.tmp/formly-templates.js',
76111
options: {
77112
module: 'formly.render',
113+
url: function(url) {
114+
return url.replace('bootstrap/', '');
115+
},
78116
htmlmin: {
79117
collapseBooleanAttributes: true,
80118
collapseWhitespace: true,
@@ -89,9 +127,13 @@ module.exports = function(grunt) {
89127
}
90128
},
91129
ngmin: {
92-
build: {
130+
vanilla: {
93131
src: '.tmp/formly.js',
94-
dest: '.tmp/formly.js'
132+
dest: '.tmp/dist/formly.js'
133+
},
134+
bootstrap: {
135+
src: '.tmp/formly.js',
136+
dest: '.tmp/dist/formly.bootstrap.js'
95137
}
96138
},
97139
watch: {
@@ -126,12 +168,28 @@ module.exports = function(grunt) {
126168
]);
127169

128170
grunt.registerTask('build', [
171+
'clean:dist',
172+
'build:vanilla',
173+
'build:bootstrap'
174+
]);
175+
176+
grunt.registerTask('build:vanilla', [
177+
'clean:build',
178+
'copy:vanilla',
179+
'ngtemplates:vanilla',
180+
'concat:build',
181+
'ngmin:vanilla',
182+
'uglify:vanilla',
183+
'copy:deploy'
184+
]);
185+
186+
grunt.registerTask('build:bootstrap', [
129187
'clean:build',
130-
'copy:build',
131-
'ngtemplates:build',
188+
'copy:bootstrap',
189+
'ngtemplates:bootstrap',
132190
'concat:build',
133-
'ngmin:build',
134-
'uglify:build',
191+
'ngmin:bootstrap',
192+
'uglify:bootstrap',
135193
'copy:deploy'
136194
]);
137195
};

dist/formly.bootstrap.js

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
// Render module for formly to display forms
2+
angular.module('formly.render', []);
3+
// Main Formly Module
4+
angular.module('formly', ['formly.render']);
5+
'use strict';
6+
angular.module('formly.render').directive('formlyField', [
7+
'$http',
8+
'$compile',
9+
'$templateCache',
10+
'formlyTemplate',
11+
function formlyField($http, $compile, $templateCache, formlyTemplate) {
12+
return {
13+
restrict: 'AE',
14+
transclude: true,
15+
scope: {
16+
optionsData: '&options',
17+
formId: '=formId',
18+
index: '=index',
19+
value: '=formValue'
20+
},
21+
link: function fieldLink($scope, $element, $attr) {
22+
var template = $scope.options.template;
23+
if (template) {
24+
setElementTemplate(template);
25+
} else {
26+
var templateUrl = $scope.options.templateUrl || formlyTemplate.getTemplateUrl($scope.options.type);
27+
if (templateUrl) {
28+
$http.get(templateUrl, { cache: $templateCache }).then(function (response) {
29+
setElementTemplate(response.data);
30+
}, function (error) {
31+
console.log('Formly Error: Problem loading template for ' + templateUrl, error);
32+
});
33+
} else {
34+
console.log('Formly Error: template type \'' + $scope.options.type + '\' not supported.');
35+
}
36+
}
37+
function setElementTemplate(templateData) {
38+
$element.html(templateData);
39+
$compile($element.contents())($scope);
40+
}
41+
},
42+
controller: [
43+
'$scope',
44+
function fieldController($scope) {
45+
$scope.options = $scope.optionsData();
46+
if (typeof $scope.options.default !== 'undefined') {
47+
$scope.value = $scope.options.default;
48+
}
49+
var type = $scope.options.type;
50+
if (!type && $scope.options.template) {
51+
type = 'template';
52+
} else if (!type && $scope.options.templateUrl) {
53+
type = 'templateUrl';
54+
}
55+
// set field id to link labels and fields
56+
$scope.id = $scope.formId + type + $scope.index;
57+
}
58+
]
59+
};
60+
}
61+
]);
62+
'use strict';
63+
angular.module('formly.render').directive('formlyForm', [
64+
'formlyOptions',
65+
'$compile',
66+
function formlyForm(formlyOptions, $compile) {
67+
return {
68+
restrict: 'AE',
69+
templateUrl: 'directives/formly-form.html',
70+
replace: true,
71+
scope: {
72+
fields: '=',
73+
options: '=?',
74+
result: '=',
75+
formOnParentScope: '=name'
76+
},
77+
compile: function (scope, iElement, iAttrs, controller, transcludeFn) {
78+
return {
79+
post: function (scope, ele, attr, controller) {
80+
scope.options = angular.extend(formlyOptions.getOptions(), scope.options);
81+
if (scope.options.submitButtonTemplate) {
82+
ele.find('button').replaceWith($compile(scope.options.submitButtonTemplate)(scope));
83+
}
84+
//Post gets called after angular has created the FormController
85+
//Now pass the FormController back up to the parent scope
86+
scope.formOnParentScope = scope[attr.name];
87+
}
88+
};
89+
},
90+
controller: [
91+
'$scope',
92+
'$element',
93+
'$parse',
94+
function ($scope, $element, $parse) {
95+
// setup watches for watchExpressions
96+
angular.forEach($scope.fields, function (field, index) {
97+
if (angular.isDefined(field.watch)) {
98+
var watchExpression = field.watch.expression;
99+
if (angular.isFunction(watchExpression)) {
100+
// wrap the field's watch expression so we can call it with the field as the first arg as a helper
101+
watchExpression = function () {
102+
var args = Array.prototype.slice.call(arguments, 0);
103+
args.unshift(field);
104+
return field.watch.expression.apply(this, args);
105+
};
106+
}
107+
$scope.$watch(watchExpression, function () {
108+
// wrap the field's watch listener so we can call it with the field as the first arg as a helper
109+
var args = Array.prototype.slice.call(arguments, 0);
110+
args.unshift(field);
111+
return field.watch.listener.apply(this, args);
112+
});
113+
}
114+
});
115+
$scope.$watch('result', function (newValue) {
116+
angular.forEach($scope.fields, function (field, index) {
117+
if (field.hideExpression) {
118+
field.hide = $parse(field.hideExpression)($scope.result);
119+
}
120+
});
121+
}, true);
122+
}
123+
]
124+
};
125+
}
126+
]);
127+
'use strict';
128+
angular.module('formly.render').provider('formlyOptions', function () {
129+
var options = {
130+
uniqueFormId: null,
131+
submitCopy: 'Submit',
132+
hideSubmit: false,
133+
submitButtonTemplate: null
134+
};
135+
function setOption(name, value) {
136+
if (typeof name === 'string') {
137+
options[name] = value;
138+
} else {
139+
angular.forEach(name, function (val, name) {
140+
setOption(name, val);
141+
});
142+
}
143+
}
144+
function getOptions() {
145+
// copy to avoid third-parties manipulating the options outside of the api.
146+
return angular.copy(options);
147+
}
148+
this.setOption = setOption;
149+
this.getOptions = getOptions;
150+
this.$get = function formlyOptions() {
151+
return this;
152+
};
153+
});
154+
'use strict';
155+
angular.module('formly.render').provider('formlyTemplate', function () {
156+
var templateMap = {
157+
textarea: 'directives/formly-field-textarea.html',
158+
radio: 'directives/formly-field-radio.html',
159+
select: 'directives/formly-field-select.html',
160+
number: 'directives/formly-field-number.html',
161+
checkbox: 'directives/formly-field-checkbox.html',
162+
password: 'directives/formly-field-password.html',
163+
hidden: 'directives/formly-field-hidden.html',
164+
email: 'directives/formly-field-email.html',
165+
text: 'directives/formly-field-text.html'
166+
};
167+
function setTemplateUrl(name, templateUrl) {
168+
if (typeof name === 'string') {
169+
templateMap[name] = templateUrl;
170+
} else {
171+
angular.forEach(name, function (templateUrl, name) {
172+
setTemplateUrl(name, templateUrl);
173+
});
174+
}
175+
}
176+
function getTemplateUrl(type) {
177+
return templateMap[type];
178+
}
179+
;
180+
this.setTemplateUrl = setTemplateUrl;
181+
this.getTemplateUrl = getTemplateUrl;
182+
this.$get = function formlyTemplate() {
183+
return this;
184+
};
185+
});
186+
angular.module('formly.render').run([
187+
'$templateCache',
188+
function ($templateCache) {
189+
'use strict';
190+
$templateCache.put('directives/formly-field-checkbox.html', '<div class=checkbox><label><input type=checkbox ng-required=options.required ng-disabled=options.disabled ng-model=value> {{options.label || \'Checkbox\'}} {{options.required ? \'*\' : \'\'}}</label></div>');
191+
$templateCache.put('directives/formly-field-email.html', '<div class=form-group><label for={{id}}>{{options.label || \'Email\'}} {{options.required ? \'*\' : \'\'}}</label><input type=email class=form-control id={{id}} placeholder={{options.placeholder}} ng-required=options.required ng-disabled=options.disabled ng-model=value></div>');
192+
$templateCache.put('directives/formly-field-hidden.html', '<input type=hidden ng-model=value>');
193+
$templateCache.put('directives/formly-field-number.html', '<div class=form-group><label for={{id}}>{{options.label || \'Number\'}} {{options.required ? \'*\' : \'\'}}</label><input type=number class=form-control id={{id}} placeholder={{options.placeholder}} ng-required=options.required ng-disabled=options.disabled min={{options.min}} max={{options.max}} ng-minlength={{options.minlength}} ng-maxlength={{options.maxlength}} ng-model=value></div>');
194+
$templateCache.put('directives/formly-field-password.html', '<div class=form-group><label for={{id}}>{{options.label || \'Password\'}} {{options.required ? \'*\' : \'\'}}</label><input type=password class=form-control id={{id}} ng-required=options.required ng-disabled=options.disabled ng-model=value></div>');
195+
$templateCache.put('directives/formly-field-radio.html', '<div class=radio-group><label class=control-label>{{options.label}} {{options.required ? \'*\' : \'\'}}</label><div class=radio ng-repeat="(key, option) in options.options"><label><input type=radio name={{id}} id="{{id + \'_\'+ $index}}" ng-value=option.value ng-required=options.required ng-model=$parent.value> {{option.name}}</label></div></div>');
196+
$templateCache.put('directives/formly-field-select.html', '<div class=form-group><label for={{id}}>{{options.label || \'Select\'}} {{options.required ? \'*\' : \'\'}}</label><select class=form-control id={{id}} ng-model=value ng-required=options.required ng-disabled=options.disabled ng-init="value = options.options[options.default]" ng-options="option.name group by option.group for option in options.options"></select></div>');
197+
$templateCache.put('directives/formly-field-text.html', '<div class=form-group><label for={{id}}>{{options.label || \'Text\'}} {{options.required ? \'*\' : \'\'}}</label><input type=text class=form-control id={{id}} placeholder={{options.placeholder}} ng-required=options.required ng-disabled=options.disabled ng-model=value></div>');
198+
$templateCache.put('directives/formly-field-textarea.html', '<div class=form-group><label for={{id}}>{{options.label || \'Text\'}} {{options.required ? \'*\' : \'\'}}</label><textarea type=text class=form-control id={{id}} rows={{options.lines}} placeholder={{options.placeholder}} ng-required=options.required ng-disabled=options.disabled ng-model=value>\n' + '\t</textarea></div>');
199+
$templateCache.put('directives/formly-field.html', '');
200+
$templateCache.put('directives/formly-form.html', '<form class=formly role=form><formly-field ng-repeat="field in fields" options=field form-value=result[field.key||$index] class=formly-field form-id=options.uniqueFormId index=$index ng-hide=field.hide></formly-field><button type=submit class="btn btn-primary" ng-hide=options.hideSubmit>{{options.submitCopy || "Submit"}}</button></form>');
201+
}
202+
]);

dist/formly.bootstrap.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)