blob: a2ee7d540807b5bc92926a12d299f063afa2438f [file] [log] [blame]
Matteo Scandolo7bc39c42016-04-20 11:38:42 -07001/**
2 * © OpenCORD
3 *
4 * Visit http://guide.xosproject.org/devguide/addview/ for more information
5 *
6 * Created by teone on 4/18/16.
7 */
8
9(function () {
10 'use strict';
11
Matteo Scandolo5dfcb082016-05-31 15:15:00 -070012
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070013 angular.module('xos.uiComponents')
14
15 /**
16 * @ngdoc directive
17 * @name xos.uiComponents.directive:xosForm
18 * @restrict E
Matteo Scandolo71378f92016-04-28 14:16:45 -070019 * @description The xos-form directive.
20 * This components have two usage, given a model it is able to autogenerate a form or it can be configured to create a custom form.
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070021 * @param {Object} config The configuration object
22 * ```
23 * {
24 * exclude: ['id', 'validators', 'created', 'updated', 'deleted'], //field to be skipped in the form, the provide values are concatenated
25 * actions: [ // define the form buttons with related callback
26 * {
27 label: 'save',
28 icon: 'ok', // refers to bootstraps glyphicon
29 cb: (user) => { // receive the model
30 console.log(user);
31 },
32 class: 'success'
33 }
Matteo Scandolo71378f92016-04-28 14:16:45 -070034 * ],
arpiagariu98680a52016-06-14 14:08:45 -070035 * feedback: {
36 show: false,
37 message: 'Form submitted successfully !!!',
38 type: 'success' //refers to bootstrap class
39 },
Matteo Scandolo71378f92016-04-28 14:16:45 -070040 * fields: {
41 * field_name: {
42 * label: 'Field Label',
arpiagariu98680a52016-06-14 14:08:45 -070043 * type: 'string' // options are: [date, boolean, number, email, string, select],
Matteo Scandolo71378f92016-04-28 14:16:45 -070044 * validators: {
arpiagariu98680a52016-06-14 14:08:45 -070045 * minlength: number,
Matteo Scandolo71378f92016-04-28 14:16:45 -070046 maxlength: number,
47 required: boolean,
48 min: number,
49 max: number
50 * }
51 * }
52 * }
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070053 * }
54 * ```
55 * @element ANY
56 * @scope
Matteo Scandolo974c0e42016-05-25 16:02:16 -070057 * @requires xos.uiComponents.directive:xosField
58 * @requires xos.uiComponents.XosFormHelpers
59 * @requires xos.helpers._
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070060 * @example
Matteo Scandolo71378f92016-04-28 14:16:45 -070061
62 Autogenerated form
63
Matteo Scandolo840260d2016-04-22 09:56:48 -070064 <example module="sampleForm">
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070065 <file name="script.js">
Matteo Scandolo840260d2016-04-22 09:56:48 -070066 angular.module('sampleForm', ['xos.uiComponents'])
Matteo Scandolo199ec002016-04-22 10:53:49 -070067 .factory('_', function($window){
68 return $window._;
69 })
Matteo Scandolo840260d2016-04-22 09:56:48 -070070 .controller('SampleCtrl', function(){
71 this.model = {
Matteo Scandolo199ec002016-04-22 10:53:49 -070072 first_name: 'Jhon',
73 last_name: 'Doe',
74 email: 'jhon.doe@sample.com',
75 active: true,
76 birthDate: '2015-02-17T22:06:38.059000Z'
Matteo Scandolo840260d2016-04-22 09:56:48 -070077 }
78 this.config = {
79 exclude: ['password', 'last_login'],
80 formName: 'sampleForm',
81 actions: [
82 {
83 label: 'Save',
84 icon: 'ok', // refers to bootstraps glyphicon
85 cb: (user) => { // receive the model
86 console.log(user);
87 },
88 class: 'success'
89 }
90 ]
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070091 };
92 });
93 </file>
Matteo Scandolo71378f92016-04-28 14:16:45 -070094 <file name="index.html">
95 <div ng-controller="SampleCtrl as vm">
96 <xos-form ng-model="vm.model" config="vm.config"></xos-form>
97 </div>
98 </file>
99 </example>
100
101 Configuration defined form
102
103 <example module="sampleForm1">
104 <file name="script.js">
arpiagariu98680a52016-06-14 14:08:45 -0700105 angular.module('sampleForm1', ['xos.uiComponents','ngResource', 'ngMockE2E'])
Matteo Scandolo71378f92016-04-28 14:16:45 -0700106 .factory('_', function($window){
107 return $window._;
108 })
arpiagariu98680a52016-06-14 14:08:45 -0700109 .controller('SampleCtrl1', function(SampleResource){
110
111
Matteo Scandolo71378f92016-04-28 14:16:45 -0700112 this.model = {
113 };
114
115 this.config = {
116 exclude: ['password', 'last_login'],
117 formName: 'sampleForm1',
arpiagariu98680a52016-06-14 14:08:45 -0700118 feedback: {
119 show: false,
120 message: 'Form submitted successfully !!!',
121 type: 'success'
122 },
Matteo Scandolo71378f92016-04-28 14:16:45 -0700123 actions: [
124 {
125 label: 'Save',
126 icon: 'ok', // refers to bootstraps glyphicon
127 cb: (user) => { // receive the model
128 console.log(user);
arpiagariu98680a52016-06-14 14:08:45 -0700129 this.config.feedback.show = true;
130 this.config.feedback.type='success';
Matteo Scandolo71378f92016-04-28 14:16:45 -0700131 },
132 class: 'success'
133 }
134 ],
135 fields: {
136 first_name: {
137 type: 'string',
138 validators: {
139 required: true
140 }
141 },
142 last_name: {
143 label: 'Surname',
144 type: 'string',
145 validators: {
146 required: true,
147 minlength: 10
148 }
149 },
150 age: {
151 type: 'number',
152 validators: {
153 required: true,
154 min: 21
155 }
156 },
arpiagariu98680a52016-06-14 14:08:45 -0700157
158 site: {
159 label: 'Site',
160 type: 'select',
161 validators: { required: true},
162 hint: 'The Site this Slice belongs to',
163 options: []
164 },
165 }
Matteo Scandolo71378f92016-04-28 14:16:45 -0700166 };
arpiagariu98680a52016-06-14 14:08:45 -0700167 SampleResource.query().$promise
168 .then((users) => {
169 //this.users_site = users;
170 //console.log(users);
171 this.optionVal = users;
172 this.config.fields['site'].options = this.optionVal;
173 //= this.optionVal;
174
175 })
176 .catch((e) => {
177 throw new Error(e);
Matteo Scandolo71378f92016-04-28 14:16:45 -0700178 });
arpiagariu98680a52016-06-14 14:08:45 -0700179
180 });
181 </file>
182 <file name="backend.js">
183 angular.module('sampleForm1')
184 .run(function($httpBackend, _){
185 let datas = [{id: 1, label: 'site1'},{id: 4, label: 'site4'},{id: 3, label: 'site3'}];
186 let paramsUrl = new RegExp(/\/test\/(.+)/);
187 $httpBackend.whenGET('/test').respond(200, datas)
188 })
189 .service('SampleResource', function($resource){
190 return $resource('/test/:id', {id: '@id'});
191 });
192
Matteo Scandolo71378f92016-04-28 14:16:45 -0700193 </file>
194 <file name="index.html">
195 <div ng-controller="SampleCtrl1 as vm">
196 <xos-form ng-model="vm.model" config="vm.config"></xos-form>
197 </div>
198 </file>
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700199 </example>
200
201 **/
202
203 .directive('xosForm', function(){
204 return {
205 restrict: 'E',
206 scope: {
207 config: '=',
208 ngModel: '='
209 },
210 template: `
arpiagariud4f6db12016-06-06 15:25:28 -0700211 <form name="vm.{{vm.config.formName || 'form'}}" novalidate>
Matteo Scandolo6e2e6ff2016-04-20 14:59:39 -0700212 <div class="form-group" ng-repeat="(name, field) in vm.formField">
arpiagariud4f6db12016-06-06 15:25:28 -0700213 <!--{{vm.ngModel[name] | json}}-->
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700214 <xos-field name="name" field="field" ng-model="vm.ngModel[name]"></xos-field>
arpiagariud4f6db12016-06-06 15:25:28 -0700215 <!--<pre>{{vm[vm.config.formName] || 'form' | json }}</pre>-->
216 <!--{{field}}-->
217 <xos-validation field="vm[vm.config.formName || 'form'][name]" form = "vm[vm.config.formName || 'form']"></xos-validation>
218 <div class="alert alert-info" ng-show="(field.hint).length >0" role="alert">{{field.hint}}</div>
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700219 </div>
220 <div class="form-group" ng-if="vm.config.actions">
arpiagariu4a872ad2016-06-10 13:13:36 -0700221 <xos-alert config="vm.config.feedback" show="vm.config.feedback.show">{{vm.config.feedback.message}}</xos-alert>
222
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700223 <button role="button" href=""
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700224 ng-repeat="action in vm.config.actions"
arpiagariu4a872ad2016-06-10 13:13:36 -0700225 ng-click="action.cb(vm.ngModel, vm[vm.config.formName || 'form'])"
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700226 class="btn btn-{{action.class}}"
227 title="{{action.label}}">
228 <i class="glyphicon glyphicon-{{action.icon}}"></i>
229 {{action.label}}
230 </button>
231 </div>
arpiagariud4f6db12016-06-06 15:25:28 -0700232 </form>
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700233 `,
234 bindToController: true,
235 controllerAs: 'vm',
Matteo Scandolo9f0e5ae2016-04-20 12:24:52 -0700236 controller: function($scope, $log, _, XosFormHelpers){
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700237
238 if(!this.config){
239 throw new Error('[xosForm] Please provide a configuration via the "config" attribute');
240 }
241
242 if(!this.config.actions){
243 throw new Error('[xosForm] Please provide an action list in the configuration');
244 }
245
arpiagariu10bd9cb2016-06-10 13:28:34 -0700246 if(!this.config.feedback){
247 this.config.feedback = {
248 show: false,
249 message: 'Form submitted successfully !!!',
250 type: 'success'
251 }
252 }
253
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700254 this.excludedField = ['id', 'validators', 'created', 'updated', 'deleted', 'backend_status'];
255 if(this.config && this.config.exclude){
256 this.excludedField = this.excludedField.concat(this.config.exclude);
257 }
258
259
260 this.formField = [];
arpiagariu4a872ad2016-06-10 13:13:36 -0700261 $scope.$watch(() => this.config, ()=> {
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700262
arpiagariu4a872ad2016-06-10 13:13:36 -0700263
264
265 if(!this.ngModel){
266 return;
267 }
268 let diff = _.difference(Object.keys(this.ngModel), this.excludedField);
269 let modelField = XosFormHelpers.parseModelField(diff);
270 this.formField = XosFormHelpers.buildFormStructure(modelField, this.config.fields, this.ngModel);
271
272
273 } ,true);
274
275
276 $scope.$watch(() => this.ngModel, (model) => {
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700277 // empty from old stuff
278 this.formField = {};
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700279 if(!model){
280 return;
281 }
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700282 let diff = _.difference(Object.keys(model), this.excludedField);
283 let modelField = XosFormHelpers.parseModelField(diff);
284 this.formField = XosFormHelpers.buildFormStructure(modelField, this.config.fields, model);
285 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700286
287 }
288 }
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700289 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700290})();