]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/services/fm_record_editor.js
webstaff: new directive: egEditFmRecord
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / services / fm_record_editor.js
1 angular.module('egFmRecordEditorMod',
2     ['egCoreMod', 'egUiMod', 'ui.bootstrap'])
3
4 .directive('egEditFmRecord', function() {
5     return {
6         restrict : 'AE',
7         transclude : true,
8         scope : {
9             // IDL class hint (e.g. "aou")
10             idlClass : '@',
11
12             // mode: 'create' for creating a new record,
13             //       'update' for editing an existing record
14             mode : '@',
15
16             // record ID to update
17             recordId : '=',
18
19             // comma-separated list of fields that should not be
20             // displayed
21             hiddenFields : '@',
22
23             // comma-separated list of fields that should always
24             // be read-only
25             readonlyFields : '@',
26
27             // comma-separated list of required fields; this
28             // supplements what the IDL considers required
29             requiredFields : '@',
30
31             // hash, keyed by field name, of functions to invoke
32             // to check whether a field is required.  Each
33             // callback is passed the field name and the record
34             // and should return a boolean value. This supports
35             // cases where whether a field is required or not
36             // depends on the current value of another field.
37             isRequiredOverride : '@',
38
39             // reference to handler to run upon saving
40             // record. The handler will be passed the
41             // record ID and a parameter indicating whether
42             // the save did a create or an update. Note that
43             // even if the mode of the egEditFmRecord is
44             // 'create', the onSave handler may still get
45             // 'update' if the user is permitted to create a
46             // record, then update it
47             onSave : '=',
48
49             // reference to handler to run if the user
50             // cancels the dialog
51             onCancel : '='
52
53         },
54
55         templateUrl : '/eg/staff/share/t_fm_record_editor',
56
57         controller : [
58                     '$scope','egCore',
59             function($scope , egCore) {
60
61             function list_to_hash(str) {
62                 var hash = {};
63                 if (angular.isString(str)) {
64                     str.split(/,/).map(function(s) {
65                         hash[s.trim()] = true;
66                     });
67                 }
68                 return hash;
69             }
70
71             $scope.required = list_to_hash($scope.requiredFields);
72             $scope.readonly = list_to_hash($scope.readonlyFields);
73             $scope.hidden = list_to_hash($scope.hiddenFields);
74
75             $scope.record_label = egCore.idl.classes[$scope.idlClass].label;
76             $scope.rec_orgs = {};
77
78             if ($scope.mode == 'update') {
79                 egCore.pcrud.retrieve($scope.idlClass, $scope.recordId).then(function(r) {
80                     $scope.rec = r;
81                     convert_datatypes_to_js($scope.rec);
82                     $scope.fields = get_field_list();
83                 });
84             } else {
85                 $scope.rec = new egCore.idl[$scope.idlClass]();
86                 $scope.fields = get_field_list();
87             }
88
89             function convert_datatypes_to_js(rec) {
90                 var fields = egCore.idl.classes[$scope.idlClass].fields;
91                 angular.forEach(fields, function(field) {
92                     if (field.datatype == 'bool') {
93                         if (rec[field.name]() == 't') {
94                             rec[field.name](true);
95                         } else if (rec[field.name]() == 'f') {
96                             rec[field.name](false);
97                         }
98                     }
99                 });
100             }
101
102             function convert_datatypes_to_idl(rec) {
103                 var fields = egCore.idl.classes[$scope.idlClass].fields;
104                 angular.forEach(fields, function(field) {
105                     if (field.datatype == 'bool') {
106                         if (rec[field.name]() == true) {
107                             rec[field.name]('t');
108                         } else if (rec[field.name]() == false) {
109                             rec[field.name]('f');
110                         }
111                     }
112                 });
113             }
114
115             function flatten_linked_values(cls, list) {
116                 var results = [];
117                 var fields = egCore.idl.classes[cls].fields;
118                 var id_field;
119                 var selector;
120                 angular.forEach(fields, function(fld) {
121                     if (fld.datatype == 'id') {
122                         id_field = fld.name;
123                         selector = fld.selector ? fld.selector : id_field;
124                         return;
125                     }
126                 });
127                 angular.forEach(list, function(item) {
128                     var rec = egCore.idl.toHash(item);
129                     results.push({
130                         id : rec[id_field],
131                         name : rec[selector]
132                     });
133                 });
134                 return results;
135             }
136
137             function get_field_list() {
138                 var fields = egCore.idl.classes[$scope.idlClass].fields;
139
140                 angular.forEach(fields, function(field) {
141                     field.readonly = (field.name in $scope.readonly);
142                     if (angular.isObject($scope.isRequiredOverride) &&
143                         field.name in $scope.isRequiredOverride) {
144                         field.is_required = function() {
145                             return $scope.isRequiredOverride[field.name](field.name, $scope.rec);
146                         }
147                     } else {
148                         field.is_required = function() {
149                             return field.required || (field.name in $scope.required);
150                         }
151                     }
152                     if (field.datatype == 'link') {
153                     egCore.pcrud.retrieveAll(
154                             field.class, {}, {atomic : true}
155                         ).then(function(list) {
156                             field.linked_values = flatten_linked_values(field.class, list);
157                         });
158                     }
159                     if (field.datatype == 'org_unit') {
160                         $scope.rec_orgs[field.name] = function(org) {
161                             if (arguments.length == 1) $scope.rec[field.name](org.id());
162                             return egCore.org.get($scope.rec[field.name]());
163                         }
164                     }
165                 });
166                 return fields.filter(function(field) { return !(field.name in $scope.hidden) });
167             }
168
169             $scope.ok = function($event) {
170                 var recToSave = egCore.idl.Clone($scope.rec)
171                 convert_datatypes_to_idl(recToSave);
172                 if ($scope.mode == 'update') {
173                     egCore.pcrud.update(recToSave).then(function() {
174                         $scope.onSave($event);
175                     });
176                 } else {
177                     egCore.pcrud.create(recToSave).then(function() {
178                         $scope.onSave($event);
179                     });
180                 }
181             }
182             $scope.cancel = function($event) {
183                 $scope.onCancel($event);
184             }
185         }]
186     };
187 })