Merge pull request #2807 from colemanw/popups
[civicrm-core.git] / js / view / crm.profile-selector.js
1 (function($, _) {
2 if (!CRM.ProfileSelector) CRM.ProfileSelector = {};
3
4 CRM.ProfileSelector.Option = Backbone.Marionette.ItemView.extend({
5 template: '#profile_selector_option_template',
6 tagName: 'option',
7 modelEvents: {
8 'change:title': 'render'
9 },
10 onRender: function() {
11 this.$el.attr('value', this.model.get('id'));
12 }
13 });
14
15 CRM.ProfileSelector.Select = Backbone.Marionette.CollectionView.extend({
16 tagName: 'select',
17 itemView: CRM.ProfileSelector.Option
18 });
19
20 /**
21 * Render a pane with 'Select/Preview/Edit/Copy/Create' functionality for profiles.
22 *
23 * Note: This view works with a ufGroupCollection, and it creates popups for a
24 * ufGroupModel. These are related but not facilely. The ufGroupModels in the
25 * ufGroupCollection are never passed to the popup, and the models from the
26 * popup are never added to the collection. This is because the popup works
27 * with temporary, local copies -- but the collection reflects the actual list
28 * on the server.
29 *
30 * options:
31 * - ufGroupId: int, the default selection
32 * - ufGroupCollection: the profiles which can be selected
33 * - ufEntities: hard-coded entity list used with any new/existing forms
34 * (this may be removed when the form-runtime is updated to support hand-picking
35 * entities for each form)
36 */
37 CRM.ProfileSelector.View = Backbone.Marionette.Layout.extend({
38 template: '#profile_selector_template',
39 regions: {
40 selectRegion: '.crm-profile-selector-select'
41 },
42 events: {
43 'change .crm-profile-selector-select select': 'onChangeUfGroupId',
44 'click .crm-profile-selector-edit': 'doEdit',
45 'click .crm-profile-selector-copy': 'doCopy',
46 'click .crm-profile-selector-create': 'doCreate'
47 },
48 /** @var Marionette.View which specifically builds on jQuery-UI's dialog */
49 activeDialog: null,
50 onRender: function() {
51 var view = new CRM.ProfileSelector.Select({
52 collection: this.options.ufGroupCollection
53 });
54 this.selectRegion.show(view);
55 this.setUfGroupId(this.options.ufGroupId, {silent: true});
56 this.toggleButtons();
57 },
58 onChangeUfGroupId: function(event) {
59 this.options.ufGroupId = $(event.target).val();
60 this.trigger('change:ufGroupId', this);
61 this.toggleButtons();
62 this.doPreview();
63 },
64 toggleButtons: function() {
65 this.$('.crm-profile-selector-edit,.crm-profile-selector-copy').prop('disabled', !this.hasUfGroupId());
66 },
67 hasUfGroupId: function() {
68 return (this.getUfGroupId() && this.getUfGroupId() != '') ? true : false;
69 },
70 setUfGroupId: function(value, options) {
71 this.options.ufGroupId = value;
72 this.$('.crm-profile-selector-select select').val(value);
73 if (!options || !options.silent) {
74 this.$('.crm-profile-selector-select select').change();
75 }
76 },
77 getUfGroupId: function() {
78 return this.options.ufGroupId;
79 },
80 doPreview: function() {
81 var $pane = this.$('.crm-profile-selector-preview-pane');
82
83 if (!this.hasUfGroupId()) {
84 $pane.html($('#profile_selector_empty_preview_template').html());
85 return;
86 }
87
88 $pane.block({message: ts('Loading...'), theme: true});
89 $.ajax({
90 url: CRM.url("civicrm/ajax/inline"),
91 type: 'GET',
92 data: {
93 class_name: 'CRM_UF_Form_Inline_PreviewById',
94 id: this.getUfGroupId(),
95 snippet: 4
96 }
97 }).done(function(data) {
98 $pane
99 .unblock()
100 .html(data)
101 .click(function() {
102 return false; // disable buttons
103 });
104 });
105 return false;
106 },
107 doEdit: function() {
108 var profileSelectorView = this;
109 var designerDialog = new CRM.Designer.DesignerDialog({
110 findCreateUfGroupModel: function(options) {
111 var ufId = profileSelectorView.getUfGroupId();
112 // Retrieve UF group and fields from the api
113 CRM.api('UFGroup', 'getsingle', {id: ufId, "api.UFField.get": 1}, {
114 success: function(formData) {
115 // Note: With chaining, API returns some extraneous keys that aren't part of UFGroupModel
116 var ufGroupModel = new CRM.UF.UFGroupModel(_.pick(formData, _.keys(CRM.UF.UFGroupModel.prototype.schema)));
117 ufGroupModel.setUFGroupModel(ufGroupModel.calculateContactEntityType(), profileSelectorView.options.ufEntities);
118 ufGroupModel.getRel('ufFieldCollection').reset(_.values(formData["api.UFField.get"].values));
119 options.onLoad(ufGroupModel);
120 }
121 });
122 }
123 });
124 CRM.designerApp.vent.on('ufSaved', this.onSave, this);
125 this.setDialog(designerDialog);
126 return false;
127 },
128 doCopy: function() {
129 // This is largely the same as doEdit, but we ultimately pass in a deepCopy of the ufGroupModel.
130 var profileSelectorView = this;
131 var designerDialog = new CRM.Designer.DesignerDialog({
132 findCreateUfGroupModel: function(options) {
133 var ufId = profileSelectorView.getUfGroupId();
134 // Retrieve UF group and fields from the api
135 CRM.api('UFGroup', 'getsingle', {id: ufId, "api.UFField.get": 1}, {
136 success: function(formData) {
137 // Note: With chaining, API returns some extraneous keys that aren't part of UFGroupModel
138 var ufGroupModel = new CRM.UF.UFGroupModel(_.pick(formData, _.keys(CRM.UF.UFGroupModel.prototype.schema)));
139 ufGroupModel.setUFGroupModel(ufGroupModel.calculateContactEntityType(), profileSelectorView.options.ufEntities);
140 ufGroupModel.getRel('ufFieldCollection').reset(_.values(formData["api.UFField.get"].values));
141 options.onLoad(ufGroupModel.deepCopy());
142 }
143 });
144 }
145 });
146 CRM.designerApp.vent.on('ufSaved', this.onSave, this);
147 this.setDialog(designerDialog);
148 return false;
149 },
150 doCreate: function() {
151 var profileSelectorView = this;
152 var designerDialog = new CRM.Designer.DesignerDialog({
153 findCreateUfGroupModel: function(options) {
154 // Initialize new UF group
155 var ufGroupModel = new CRM.UF.UFGroupModel();
156 ufGroupModel.getRel('ufEntityCollection').reset(profileSelectorView.options.ufEntities);
157 options.onLoad(ufGroupModel);
158 }
159 });
160 CRM.designerApp.vent.on('ufSaved', this.onSave, this);
161 this.setDialog(designerDialog);
162 return false;
163 },
164 onSave: function() {
165 CRM.designerApp.vent.off('ufSaved', this.onSave, this);
166 var ufGroupId = this.activeDialog.model.get('id');
167 var modelFromCollection = this.options.ufGroupCollection.get(ufGroupId);
168 if (modelFromCollection) {
169 // copy in changes to UFGroup
170 modelFromCollection.set(this.activeDialog.model.toStrictJSON());
171 } else {
172 // add in new UFGroup
173 modelFromCollection = new CRM.UF.UFGroupModel(this.activeDialog.model.toStrictJSON());
174 this.options.ufGroupCollection.add(modelFromCollection);
175 }
176 this.setUfGroupId(ufGroupId);
177 this.doPreview();
178 },
179 setDialog: function(view) {
180 if (this.activeDialog) {
181 this.activeDialog.close();
182 }
183 this.activeDialog = view;
184 view.render();
185 }
186 });
187 })(CRM.$, CRM._);