Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 1 | /** |
| 2 | * © OpenCORD |
| 3 | * |
| 4 | * Visit http://guide.xosproject.org/devguide/addview/ for more information |
| 5 | * |
| 6 | * Created by teone on 5/25/16. |
| 7 | */ |
| 8 | |
| 9 | (function () { |
| 10 | 'use strict'; |
| 11 | |
| 12 | angular.module('xos.uiComponents') |
| 13 | /** |
| 14 | * @ngdoc directive |
| 15 | * @name xos.uiComponents.directive:xosField |
| 16 | * @restrict E |
| 17 | * @description The xos-field directive. |
| 18 | * This component decide, give a field wich kind of input it need to print. |
| 19 | * @param {string} name The field name |
| 20 | * @param {object} field The field configuration: |
| 21 | * ``` |
| 22 | * { |
| 23 | * label: 'Label', |
| 24 | * type: 'number', //typeof field |
| 25 | * validators: {} // see xosForm for more details |
| 26 | * } |
| 27 | * ``` |
| 28 | * @param {mixed} ngModel The field value |
Matteo Scandolo | b9fb625 | 2016-05-26 15:09:55 -0700 | [diff] [blame] | 29 | * |
| 30 | * @example |
| 31 | |
| 32 | # Basic Example |
| 33 | |
| 34 | <example module="sampleField1"> |
| 35 | <file name="script.js"> |
| 36 | angular.module('sampleField1', ['xos.uiComponents']) |
| 37 | .factory('_', function($window){ |
| 38 | return $window._; |
| 39 | }) |
| 40 | .controller('SampleCtrl', function(){ |
| 41 | this.name = 'input-name'; |
| 42 | this.field = {label: 'My String Value:', type: 'string'}; |
| 43 | this.model = 'my string'; |
| 44 | }); |
| 45 | </file> |
| 46 | <file name="index.html"> |
| 47 | <div ng-controller="SampleCtrl as vm"> |
| 48 | <xos-field ng-model="vm.model" name="vm.name" field="vm.field"></xos-field> |
| 49 | </div> |
| 50 | </file> |
| 51 | </example> |
| 52 | |
| 53 | # Possible Values |
| 54 | |
| 55 | <example module="sampleField2"> |
| 56 | <file name="script.js"> |
| 57 | angular.module('sampleField2', ['xos.uiComponents']) |
| 58 | .factory('_', function($window){ |
| 59 | return $window._; |
| 60 | }) |
| 61 | .controller('SampleCtrl', function(){ |
| 62 | this.field1 = { |
| 63 | name: 'number-field', |
| 64 | field: {label: 'My Number Value:', type: 'number'}, |
| 65 | model: 2 |
| 66 | }; |
| 67 | |
| 68 | this.field2 = { |
| 69 | name: 'date-field', |
| 70 | field: {label: 'My Date Value:', type: 'date'}, |
| 71 | model: new Date() |
| 72 | }; |
| 73 | |
| 74 | this.field3 = { |
| 75 | name: 'boolean-field', |
| 76 | field: {label: 'My Boolean Value:', type: 'boolean'}, |
| 77 | model: true |
| 78 | }; |
| 79 | |
| 80 | this.field4 = { |
| 81 | name: 'email-field', |
| 82 | field: {label: 'My Email Value:', type: 'email'}, |
| 83 | model: 'sample@domain.us' |
| 84 | }; |
| 85 | }); |
| 86 | </file> |
| 87 | <file name="index.html"> |
| 88 | <div ng-controller="SampleCtrl as vm"> |
| 89 | <xos-field ng-model="vm.field1.model" name="vm.field1.name" field="vm.field1.field"></xos-field> |
| 90 | <xos-field ng-model="vm.field2.model" name="vm.field2.name" field="vm.field2.field"></xos-field> |
| 91 | <xos-field ng-model="vm.field3.model" name="vm.field3.name" field="vm.field3.field"></xos-field> |
| 92 | <xos-field ng-model="vm.field4.model" name="vm.field4.name" field="vm.field4.field"></xos-field> |
| 93 | </div> |
| 94 | </file> |
| 95 | </example> |
| 96 | |
| 97 | # This element is recursive |
| 98 | |
| 99 | <example module="sampleField3"> |
| 100 | <file name="script.js"> |
| 101 | angular.module('sampleField3', ['xos.uiComponents']) |
| 102 | .factory('_', function($window){ |
| 103 | return $window._; |
| 104 | }) |
| 105 | .controller('SampleCtrl', function(){ |
| 106 | this.name = 'input-name'; |
| 107 | this.field = {label: 'My Object Value:', type: 'object'}; |
| 108 | this.model = { |
| 109 | name: 'Jhon', |
| 110 | age: '25', |
| 111 | email: 'jhon@thewall.ru', |
| 112 | active: true |
| 113 | }; |
| 114 | }); |
| 115 | </file> |
| 116 | <file name="index.html"> |
| 117 | <div ng-controller="SampleCtrl as vm"> |
| 118 | <xos-field ng-model="vm.model" name="vm.name" field="vm.field"></xos-field> |
| 119 | </div> |
| 120 | </file> |
| 121 | </example> |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 122 | */ |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 123 | .directive('xosField', function(RecursionHelper){ |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 124 | return { |
| 125 | restrict: 'E', |
| 126 | scope: { |
| 127 | name: '=', |
| 128 | field: '=', |
| 129 | ngModel: '=' |
| 130 | }, |
| 131 | template: ` |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 132 | <label ng-if="vm.field.type !== 'object'">{{vm.field.label}}</label> |
arpiagariu | 47cd689 | 2016-06-03 16:41:39 -0700 | [diff] [blame] | 133 | <!--<pre>{{vm.field.options | json}}</pre>--> |
| 134 | <!--<pre>{{vm.ngModel | json}}</pre>--> |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 135 | <input |
arpiagariu | 47cd689 | 2016-06-03 16:41:39 -0700 | [diff] [blame] | 136 | ng-if="vm.field.type !== 'boolean' && vm.field.type !== 'object' && vm.field.type !== 'select'" |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 137 | type="{{vm.field.type}}" |
| 138 | name="{{vm.name}}" |
| 139 | class="form-control" |
| 140 | ng-model="vm.ngModel" |
| 141 | ng-minlength="vm.field.validators.minlength || 0" |
| 142 | ng-maxlength="vm.field.validators.maxlength || 2000" |
| 143 | ng-required="vm.field.validators.required || false" /> |
arpiagariu | 47cd689 | 2016-06-03 16:41:39 -0700 | [diff] [blame] | 144 | <select class="form-control" ng-if ="vm.field.type === 'select'" |
| 145 | name = "{{vm.name}}" |
| 146 | ng-options="item.id as item.label for item in vm.field.options track by item.id" |
| 147 | ng-model="vm.ngModel" |
| 148 | ng-required="vm.field.validators.required || false"> |
| 149 | </select> |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 150 | <span class="boolean-field" ng-if="vm.field.type === 'boolean'"> |
| 151 | <button |
| 152 | class="btn btn-success" |
| 153 | ng-show="vm.ngModel" |
| 154 | ng-click="vm.ngModel = false"> |
| 155 | <i class="glyphicon glyphicon-ok"></i> |
| 156 | </button> |
| 157 | <button |
| 158 | class="btn btn-danger" |
| 159 | ng-show="!vm.ngModel" |
| 160 | ng-click="vm.ngModel = true"> |
| 161 | <i class="glyphicon glyphicon-remove"></i> |
| 162 | </button> |
| 163 | </span> |
| 164 | <div |
| 165 | class="panel panel-default object-field" |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 166 | ng-if="vm.field.type == 'object' && !vm.isEmptyObject(vm.ngModel)" |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 167 | > |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 168 | <div class="panel-heading">{{vm.field.label}}</div> |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 169 | <div class="panel-body"> |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 170 | <div ng-repeat="(k, v) in vm.ngModel"> |
| 171 | <xos-field |
| 172 | name="k" |
Matteo Scandolo | b9fb625 | 2016-05-26 15:09:55 -0700 | [diff] [blame] | 173 | field="{label: vm.formatLabel(k), type: vm.getType(v)}" |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 174 | ng-model="v"> |
| 175 | </xos-field> |
| 176 | </div> |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 177 | </div> |
| 178 | </div> |
| 179 | `, |
| 180 | bindToController: true, |
| 181 | controllerAs: 'vm', |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 182 | // the compile cicle is needed to support recursion |
| 183 | compile: function (element) { |
| 184 | return RecursionHelper.compile(element); |
| 185 | }, |
Matteo Scandolo | b9fb625 | 2016-05-26 15:09:55 -0700 | [diff] [blame] | 186 | controller: function($attrs, XosFormHelpers, LabelFormatter){ |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 187 | // console.log('Field: ', this.name, this.field, this.ngModel); |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 188 | if(!this.name){ |
| 189 | throw new Error('[xosField] Please provide a field name'); |
| 190 | } |
| 191 | if(!this.field){ |
| 192 | throw new Error('[xosField] Please provide a field definition'); |
| 193 | } |
Matteo Scandolo | b9fb625 | 2016-05-26 15:09:55 -0700 | [diff] [blame] | 194 | if(!$attrs.ngModel){ |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 195 | throw new Error('[xosField] Please provide an ng-model'); |
| 196 | } |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 197 | |
| 198 | this.getType = XosFormHelpers._getFieldFormat; |
Matteo Scandolo | b9fb625 | 2016-05-26 15:09:55 -0700 | [diff] [blame] | 199 | this.formatLabel = LabelFormatter.format; |
Matteo Scandolo | 03d8b8e | 2016-05-25 17:37:37 -0700 | [diff] [blame] | 200 | |
| 201 | this.isEmptyObject = o => Object.keys(o).length === 0; |
Matteo Scandolo | 974c0e4 | 2016-05-25 16:02:16 -0700 | [diff] [blame] | 202 | } |
| 203 | } |
| 204 | }); |
| 205 | })(); |