blob: db4a2fd43fbb8e1fe2480bfddadc7ccedd678bfd [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
12 angular.module('xos.uiComponents')
13
14 /**
15 * @ngdoc directive
16 * @name xos.uiComponents.directive:xosForm
17 * @restrict E
Matteo Scandolo71378f92016-04-28 14:16:45 -070018 * @description The xos-form directive.
19 * 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 -070020 * @param {Object} config The configuration object
21 * ```
22 * {
23 * exclude: ['id', 'validators', 'created', 'updated', 'deleted'], //field to be skipped in the form, the provide values are concatenated
24 * actions: [ // define the form buttons with related callback
25 * {
26 label: 'save',
27 icon: 'ok', // refers to bootstraps glyphicon
28 cb: (user) => { // receive the model
29 console.log(user);
30 },
31 class: 'success'
32 }
Matteo Scandolo71378f92016-04-28 14:16:45 -070033 * ],
34 * fields: {
35 * field_name: {
36 * label: 'Field Label',
37 * type: 'string' // options are: [date, boolean, number, email, string],
38 * validators: {
39 * minlength: number,
40 maxlength: number,
41 required: boolean,
42 min: number,
43 max: number
44 * }
45 * }
46 * }
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070047 * }
48 * ```
49 * @element ANY
50 * @scope
Matteo Scandolo974c0e42016-05-25 16:02:16 -070051 * @requires xos.uiComponents.directive:xosField
52 * @requires xos.uiComponents.XosFormHelpers
53 * @requires xos.helpers._
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070054 * @example
Matteo Scandolo71378f92016-04-28 14:16:45 -070055
56 Autogenerated form
57
Matteo Scandolo840260d2016-04-22 09:56:48 -070058 <example module="sampleForm">
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070059 <file name="script.js">
Matteo Scandolo840260d2016-04-22 09:56:48 -070060 angular.module('sampleForm', ['xos.uiComponents'])
Matteo Scandolo199ec002016-04-22 10:53:49 -070061 .factory('_', function($window){
62 return $window._;
63 })
Matteo Scandolo840260d2016-04-22 09:56:48 -070064 .controller('SampleCtrl', function(){
65 this.model = {
Matteo Scandolo199ec002016-04-22 10:53:49 -070066 first_name: 'Jhon',
67 last_name: 'Doe',
68 email: 'jhon.doe@sample.com',
69 active: true,
70 birthDate: '2015-02-17T22:06:38.059000Z'
Matteo Scandolo840260d2016-04-22 09:56:48 -070071 }
72 this.config = {
73 exclude: ['password', 'last_login'],
74 formName: 'sampleForm',
75 actions: [
76 {
77 label: 'Save',
78 icon: 'ok', // refers to bootstraps glyphicon
79 cb: (user) => { // receive the model
80 console.log(user);
81 },
82 class: 'success'
83 }
84 ]
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070085 };
86 });
87 </file>
Matteo Scandolo71378f92016-04-28 14:16:45 -070088 <file name="index.html">
89 <div ng-controller="SampleCtrl as vm">
90 <xos-form ng-model="vm.model" config="vm.config"></xos-form>
91 </div>
92 </file>
93 </example>
94
95 Configuration defined form
96
97 <example module="sampleForm1">
98 <file name="script.js">
99 angular.module('sampleForm1', ['xos.uiComponents'])
100 .factory('_', function($window){
101 return $window._;
102 })
103 .controller('SampleCtrl1', function(){
104 this.model = {
105 };
106
107 this.config = {
108 exclude: ['password', 'last_login'],
109 formName: 'sampleForm1',
110 actions: [
111 {
112 label: 'Save',
113 icon: 'ok', // refers to bootstraps glyphicon
114 cb: (user) => { // receive the model
115 console.log(user);
116 },
117 class: 'success'
118 }
119 ],
120 fields: {
121 first_name: {
122 type: 'string',
123 validators: {
124 required: true
125 }
126 },
127 last_name: {
128 label: 'Surname',
129 type: 'string',
130 validators: {
131 required: true,
132 minlength: 10
133 }
134 },
135 age: {
136 type: 'number',
137 validators: {
138 required: true,
139 min: 21
140 }
141 },
142 }
143 };
144 });
145 </file>
146 <file name="index.html">
147 <div ng-controller="SampleCtrl1 as vm">
148 <xos-form ng-model="vm.model" config="vm.config"></xos-form>
149 </div>
150 </file>
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700151 </example>
152
153 **/
154
155 .directive('xosForm', function(){
156 return {
157 restrict: 'E',
158 scope: {
159 config: '=',
160 ngModel: '='
161 },
162 template: `
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700163 <ng-form name="vm.{{vm.config.formName || 'form'}}">
Matteo Scandolo6e2e6ff2016-04-20 14:59:39 -0700164 <div class="form-group" ng-repeat="(name, field) in vm.formField">
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700165 <xos-field name="name" field="field" ng-model="vm.ngModel[name]"></xos-field>
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700166 <xos-validation errors="vm[vm.config.formName || 'form'][name].$error"></xos-validation>
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700167 </div>
168 <div class="form-group" ng-if="vm.config.actions">
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700169 <button role="button" href=""
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700170 ng-repeat="action in vm.config.actions"
171 ng-click="action.cb(vm.ngModel)"
172 class="btn btn-{{action.class}}"
173 title="{{action.label}}">
174 <i class="glyphicon glyphicon-{{action.icon}}"></i>
175 {{action.label}}
176 </button>
177 </div>
178 </ng-form>
179 `,
180 bindToController: true,
181 controllerAs: 'vm',
Matteo Scandolo9f0e5ae2016-04-20 12:24:52 -0700182 controller: function($scope, $log, _, XosFormHelpers){
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700183
184 if(!this.config){
185 throw new Error('[xosForm] Please provide a configuration via the "config" attribute');
186 }
187
188 if(!this.config.actions){
189 throw new Error('[xosForm] Please provide an action list in the configuration');
190 }
191
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700192 this.excludedField = ['id', 'validators', 'created', 'updated', 'deleted', 'backend_status'];
193 if(this.config && this.config.exclude){
194 this.excludedField = this.excludedField.concat(this.config.exclude);
195 }
196
197
198 this.formField = [];
199 $scope.$watch(() => this.ngModel, (model) => {
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700200
201 // empty from old stuff
202 this.formField = {};
203
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700204 if(!model){
205 return;
206 }
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700207
208 let diff = _.difference(Object.keys(model), this.excludedField);
209 let modelField = XosFormHelpers.parseModelField(diff);
210 this.formField = XosFormHelpers.buildFormStructure(modelField, this.config.fields, model);
211 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700212
213 }
214 }
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700215 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700216})();