Merge pull request #24117 from civicrm/5.52
[civicrm-core.git] / ext / afform / core / ang / af / afForm.component.js
CommitLineData
65d7084b
CW
1(function(angular, $, _) {
2 // Example usage: <af-form ctrl="afform">
3 angular.module('af').component('afForm', {
4 bindings: {
5 ctrl: '@'
6 },
aea64f20 7 controller: function($scope, $element, $timeout, crmApi4, crmStatus, $window, $location, $parse, FileUploader) {
65d7084b
CW
8 var schema = {},
9 data = {},
9d85626b 10 status,
f032946a 11 args,
aea64f20 12 submissionResponse,
65d7084b
CW
13 ctrl = this;
14
65d7084b 15 this.$onInit = function() {
652d6cee
CW
16 // This component has no template. It makes its controller available within it by adding it to the parent scope.
17 $scope.$parent[this.ctrl] = this;
18
65d7084b
CW
19 $timeout(ctrl.loadData);
20 };
21
22 this.registerEntity = function registerEntity(entity) {
23 schema[entity.modelName] = entity;
24 data[entity.modelName] = [];
25 };
26 this.getEntity = function getEntity(name) {
27 return schema[name];
28 };
29 // Returns field values for a given entity
30 this.getData = function getData(name) {
31 return data[name];
32 };
33 this.getSchema = function getSchema(name) {
34 return schema[name];
35 };
36 // Returns the 'meta' record ('name', 'description', etc) of the active form.
37 this.getFormMeta = function getFormMeta() {
38 return $scope.$parent.meta;
39 };
40 this.loadData = function() {
f032946a
CW
41 var toLoad = 0;
42 args = _.assign({}, $scope.$parent.routeParams || {}, $scope.$parent.options || {});
65d7084b 43 _.each(schema, function(entity, entityName) {
31c51d71 44 if (args[entityName] || entity.autofill) {
65d7084b
CW
45 toLoad++;
46 }
47 });
48 if (toLoad) {
31c51d71 49 crmApi4('Afform', 'prefill', {name: ctrl.getFormMeta().name, args: args})
65d7084b
CW
50 .then(function(result) {
51 _.each(result, function(item) {
52 data[item.name] = data[item.name] || {};
53 _.extend(data[item.name], item.values, schema[item.name].data || {});
54 });
55 });
56 }
57 };
58
9d85626b
CW
59 // Used when submitting file fields
60 this.fileUploader = new FileUploader({
61 url: CRM.url('civicrm/ajax/api4/Afform/submitFile'),
62 headers: {'X-Requested-With': 'XMLHttpRequest'},
63 onCompleteAll: postProcess,
64 onBeforeUploadItem: function(item) {
65 status.resolve();
66 status = CRM.status({start: ts('Uploading %1', {1: item.file.name})});
67 }
68 });
69
70 // Called after form is submitted and files are uploaded
71 function postProcess() {
bbc44f9f
CW
72 var metaData = ctrl.getFormMeta(),
73 dialog = $element.closest('.ui-dialog-content');
9d85626b 74
30f34544
CW
75 $element.trigger('crmFormSuccess', {
76 afform: metaData,
77 data: data
78 });
79
bbc44f9f
CW
80 status.resolve();
81 $element.unblock();
82
83 if (dialog.length) {
84 dialog.dialog('close');
85 }
86
87 else if (metaData.redirect) {
aea64f20 88 var url = replaceTokens(metaData.redirect, submissionResponse[0]);
9d85626b
CW
89 if (url.indexOf('civicrm/') === 0) {
90 url = CRM.url(url);
91 } else if (url.indexOf('/') === 0) {
92 url = $location.protocol() + '://' + $location.host() + url;
93 }
94 $window.location.href = url;
b6e13973 95 }
9d85626b
CW
96 }
97
aea64f20
CW
98 function replaceTokens(str, vars) {
99 function recurse(stack, values) {
100 _.each(values, function(value, key) {
101 console.log('value:' + value, stack);
102 if (_.isArray(value) || _.isPlainObject(value)) {
103 recurse(stack.concat([key]), value);
104 } else {
105 var token = (stack.length ? stack.join('.') + '.' : '') + key;
106 str = str.replace(new RegExp(_.escapeRegExp('[' + token + ']'), 'g'), value);
107 }
108 });
109 }
110 recurse([], vars);
111 return str;
112 }
113
9d85626b
CW
114 this.submit = function() {
115 status = CRM.status({});
687d7713
CW
116 $element.block();
117
9d85626b
CW
118 crmApi4('Afform', 'submit', {
119 name: ctrl.getFormMeta().name,
f032946a 120 args: args,
9d85626b
CW
121 values: data}
122 ).then(function(response) {
aea64f20 123 submissionResponse = response;
9d85626b
CW
124 if (ctrl.fileUploader.getNotUploadedItems().length) {
125 _.each(ctrl.fileUploader.getNotUploadedItems(), function(file) {
126 file.formData.push({
127 params: JSON.stringify(_.extend({
128 token: response[0].token,
129 name: ctrl.getFormMeta().name
130 }, file.crmApiParams()))
131 });
132 });
133 ctrl.fileUploader.uploadAll();
134 } else {
135 postProcess();
136 }
137 });
65d7084b
CW
138 };
139 }
140 });
141})(angular, CRM.$, CRM._);