blob: 92843c2e2510cd3e7f2a51ffcbcfdb8e19ce9c6b [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: `
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700164 <ng-form name="vm.{{vm.config.formName || 'form'}}">
Matteo Scandolo6e2e6ff2016-04-20 14:59:39 -0700165 <div class="form-group" ng-repeat="(name, field) in vm.formField">
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700166 <xos-field name="name" field="field" ng-model="vm.ngModel[name]"></xos-field>
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700167 <xos-validation errors="vm[vm.config.formName || 'form'][name].$error"></xos-validation>
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700168 </div>
169 <div class="form-group" ng-if="vm.config.actions">
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700170 <button role="button" href=""
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700171 ng-repeat="action in vm.config.actions"
172 ng-click="action.cb(vm.ngModel)"
173 class="btn btn-{{action.class}}"
174 title="{{action.label}}">
175 <i class="glyphicon glyphicon-{{action.icon}}"></i>
176 {{action.label}}
177 </button>
178 </div>
179 </ng-form>
180 `,
181 bindToController: true,
182 controllerAs: 'vm',
Matteo Scandolo9f0e5ae2016-04-20 12:24:52 -0700183 controller: function($scope, $log, _, XosFormHelpers){
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700184
185 if(!this.config){
186 throw new Error('[xosForm] Please provide a configuration via the "config" attribute');
187 }
188
189 if(!this.config.actions){
190 throw new Error('[xosForm] Please provide an action list in the configuration');
191 }
192
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700193 this.excludedField = ['id', 'validators', 'created', 'updated', 'deleted', 'backend_status'];
194 if(this.config && this.config.exclude){
195 this.excludedField = this.excludedField.concat(this.config.exclude);
196 }
197
198
199 this.formField = [];
200 $scope.$watch(() => this.ngModel, (model) => {
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700201
202 // empty from old stuff
203 this.formField = {};
204
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700205 if(!model){
206 return;
207 }
Matteo Scandoloe2ee2d92016-04-27 15:58:16 -0700208
209 let diff = _.difference(Object.keys(model), this.excludedField);
210 let modelField = XosFormHelpers.parseModelField(diff);
211 this.formField = XosFormHelpers.buildFormStructure(modelField, this.config.fields, model);
212 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700213
214 }
215 }
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700216 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700217})();