blob: 09557f00cea6aea43af0ec8206bd63bf699e22de [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 * ],
35 * fields: {
36 * field_name: {
37 * label: 'Field Label',
38 * type: 'string' // options are: [date, boolean, number, email, string],
39 * validators: {
40 * minlength: number,
41 maxlength: number,
42 required: boolean,
43 min: number,
44 max: number
45 * }
46 * }
47 * }
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070048 * }
49 * ```
50 * @element ANY
51 * @scope
Matteo Scandolo974c0e42016-05-25 16:02:16 -070052 * @requires xos.uiComponents.directive:xosField
53 * @requires xos.uiComponents.XosFormHelpers
54 * @requires xos.helpers._
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070055 * @example
Matteo Scandolo71378f92016-04-28 14:16:45 -070056
57 Autogenerated form
58
Matteo Scandolo840260d2016-04-22 09:56:48 -070059 <example module="sampleForm">
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070060 <file name="script.js">
Matteo Scandolo840260d2016-04-22 09:56:48 -070061 angular.module('sampleForm', ['xos.uiComponents'])
Matteo Scandolo199ec002016-04-22 10:53:49 -070062 .factory('_', function($window){
63 return $window._;
64 })
Matteo Scandolo840260d2016-04-22 09:56:48 -070065 .controller('SampleCtrl', function(){
66 this.model = {
Matteo Scandolo199ec002016-04-22 10:53:49 -070067 first_name: 'Jhon',
68 last_name: 'Doe',
69 email: 'jhon.doe@sample.com',
70 active: true,
71 birthDate: '2015-02-17T22:06:38.059000Z'
Matteo Scandolo840260d2016-04-22 09:56:48 -070072 }
73 this.config = {
74 exclude: ['password', 'last_login'],
75 formName: 'sampleForm',
76 actions: [
77 {
78 label: 'Save',
79 icon: 'ok', // refers to bootstraps glyphicon
80 cb: (user) => { // receive the model
81 console.log(user);
82 },
83 class: 'success'
84 }
85 ]
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070086 };
87 });
88 </file>
Matteo Scandolo71378f92016-04-28 14:16:45 -070089 <file name="index.html">
90 <div ng-controller="SampleCtrl as vm">
91 <xos-form ng-model="vm.model" config="vm.config"></xos-form>
92 </div>
93 </file>
94 </example>
95
96 Configuration defined form
97
98 <example module="sampleForm1">
99 <file name="script.js">
100 angular.module('sampleForm1', ['xos.uiComponents'])
101 .factory('_', function($window){
102 return $window._;
103 })
104 .controller('SampleCtrl1', function(){
105 this.model = {
106 };
107
108 this.config = {
109 exclude: ['password', 'last_login'],
110 formName: 'sampleForm1',
111 actions: [
112 {
113 label: 'Save',
114 icon: 'ok', // refers to bootstraps glyphicon
115 cb: (user) => { // receive the model
116 console.log(user);
117 },
118 class: 'success'
119 }
120 ],
121 fields: {
122 first_name: {
123 type: 'string',
124 validators: {
125 required: true
126 }
127 },
128 last_name: {
129 label: 'Surname',
130 type: 'string',
131 validators: {
132 required: true,
133 minlength: 10
134 }
135 },
136 age: {
137 type: 'number',
138 validators: {
139 required: true,
140 min: 21
141 }
142 },
143 }
144 };
145 });
146 </file>
147 <file name="index.html">
148 <div ng-controller="SampleCtrl1 as vm">
149 <xos-form ng-model="vm.model" config="vm.config"></xos-form>
150 </div>
151 </file>
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700152 </example>
153
154 **/
155
156 .directive('xosForm', function(){
157 return {
158 restrict: 'E',
159 scope: {
160 config: '=',
161 ngModel: '='
162 },
163 template: `
arpiagariud4f6db12016-06-06 15:25:28 -0700164 <form name="vm.{{vm.config.formName || 'form'}}" novalidate>
Matteo Scandolo6e2e6ff2016-04-20 14:59:39 -0700165 <div class="form-group" ng-repeat="(name, field) in vm.formField">
arpiagariud4f6db12016-06-06 15:25:28 -0700166 <!--{{vm.ngModel[name] | json}}-->
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700167 <xos-field name="name" field="field" ng-model="vm.ngModel[name]"></xos-field>
arpiagariud4f6db12016-06-06 15:25:28 -0700168 <!--<pre>{{vm[vm.config.formName] || 'form' | json }}</pre>-->
169 <!--{{field}}-->
170 <xos-validation field="vm[vm.config.formName || 'form'][name]" form = "vm[vm.config.formName || 'form']"></xos-validation>
171 <div class="alert alert-info" ng-show="(field.hint).length >0" role="alert">{{field.hint}}</div>
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700172 </div>
173 <div class="form-group" ng-if="vm.config.actions">
arpiagariu4a872ad2016-06-10 13:13:36 -0700174 <xos-alert config="vm.config.feedback" show="vm.config.feedback.show">{{vm.config.feedback.message}}</xos-alert>
175
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700176 <button role="button" href=""
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700177 ng-repeat="action in vm.config.actions"
arpiagariu4a872ad2016-06-10 13:13:36 -0700178 ng-click="action.cb(vm.ngModel, vm[vm.config.formName || 'form'])"
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700179 class="btn btn-{{action.class}}"
180 title="{{action.label}}">
181 <i class="glyphicon glyphicon-{{action.icon}}"></i>
182 {{action.label}}
183 </button>
184 </div>
arpiagariud4f6db12016-06-06 15:25:28 -0700185 </form>
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700186 `,
187 bindToController: true,
188 controllerAs: 'vm',
Matteo Scandolo9f0e5ae2016-04-20 12:24:52 -0700189 controller: function($scope, $log, _, XosFormHelpers){
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700190
191 if(!this.config){
192 throw new Error('[xosForm] Please provide a configuration via the "config" attribute');
193 }
194
195 if(!this.config.actions){
196 throw new Error('[xosForm] Please provide an action list in the configuration');
197 }
198
arpiagariu10bd9cb2016-06-10 13:28:34 -0700199 if(!this.config.feedback){
200 this.config.feedback = {
201 show: false,
202 message: 'Form submitted successfully !!!',
203 type: 'success'
204 }
205 }
206
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700207 this.excludedField = ['id', 'validators', 'created', 'updated', 'deleted', 'backend_status'];
208 if(this.config && this.config.exclude){
209 this.excludedField = this.excludedField.concat(this.config.exclude);
210 }
211
212
213 this.formField = [];
arpiagariu4a872ad2016-06-10 13:13:36 -0700214 $scope.$watch(() => this.config, ()=> {
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700215
arpiagariu4a872ad2016-06-10 13:13:36 -0700216
217
218 if(!this.ngModel){
219 return;
220 }
221 let diff = _.difference(Object.keys(this.ngModel), this.excludedField);
222 let modelField = XosFormHelpers.parseModelField(diff);
223 this.formField = XosFormHelpers.buildFormStructure(modelField, this.config.fields, this.ngModel);
224
225
226 } ,true);
227
228
229 $scope.$watch(() => this.ngModel, (model) => {
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700230 // empty from old stuff
231 this.formField = {};
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700232 if(!model){
233 return;
234 }
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700235 let diff = _.difference(Object.keys(model), this.excludedField);
236 let modelField = XosFormHelpers.parseModelField(diff);
237 this.formField = XosFormHelpers.buildFormStructure(modelField, this.config.fields, model);
238 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700239
240 }
241 }
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700242 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700243})();