(function($, _) { if (!CRM.ProfileSelector) CRM.ProfileSelector = {}; CRM.ProfileSelector.Option = Backbone.Marionette.ItemView.extend({ template: '#profile_selector_option_template', tagName: 'option', modelEvents: { 'change:title': 'render' }, onRender: function() { this.$el.attr('value', this.model.get('id')); } }); CRM.ProfileSelector.Select = Backbone.Marionette.CollectionView.extend({ tagName: 'select', itemView: CRM.ProfileSelector.Option }); /** * Render a pane with 'Select/Preview/Edit/Copy/Create' functionality for profiles. * * Note: This view works with a ufGroupCollection, and it creates popups for a * ufGroupModel. These are related but not facilely. The ufGroupModels in the * ufGroupCollection are never passed to the popup, and the models from the * popup are never added to the collection. This is because the popup works * with temporary, local copies -- but the collection reflects the actual list * on the server. * * options: * - ufGroupId: int, the default selection * - ufGroupCollection: the profiles which can be selected * - ufEntities: hard-coded entity list used with any new/existing forms * (this may be removed when the form-runtime is updated to support hand-picking * entities for each form) */ CRM.ProfileSelector.View = Backbone.Marionette.Layout.extend({ template: '#profile_selector_template', regions: { selectRegion: '.crm-profile-selector-select' }, events: { 'change .crm-profile-selector-select select': 'onChangeUfGroupId', 'click .crm-profile-selector-edit': 'doEdit', 'click .crm-profile-selector-copy': 'doCopy', 'click .crm-profile-selector-create': 'doCreate', 'click .crm-profile-selector-preview': 'doShowPreview', // prevent interaction with preview form 'click .crm-profile-selector-preview-pane': false, 'crmLoad .crm-profile-selector-preview-pane': 'disableForm' }, /** @var Marionette.View which specifically builds on jQuery-UI's dialog */ activeDialog: null, onRender: function() { var view = new CRM.ProfileSelector.Select({ collection: this.options.ufGroupCollection }); this.selectRegion.show(view); this.setUfGroupId(this.options.ufGroupId, {silent: true}); this.toggleButtons(); this.$('.crm-profile-selector-select select').css('width', '25em').crmSelect2(); this.doShowPreview(); }, onChangeUfGroupId: function(event) { this.options.ufGroupId = $(event.target).val(); this.trigger('change:ufGroupId', this); this.toggleButtons(); this.doPreview(); }, toggleButtons: function() { this.$('.crm-profile-selector-edit,.crm-profile-selector-copy').prop('disabled', !this.hasUfGroupId()); }, hasUfGroupId: function() { return (this.getUfGroupId() && this.getUfGroupId() !== '') ? true : false; }, setUfGroupId: function(value, options) { this.options.ufGroupId = value; this.$('.crm-profile-selector-select select').val(value); this.$('.crm-profile-selector-select select').select2('val', value, (!options || !options.silent)); }, getUfGroupId: function() { return this.options.ufGroupId; }, doPreview: function() { var $pane = this.$('.crm-profile-selector-preview-pane'); if (!this.hasUfGroupId()) { $pane.html($('#profile_selector_empty_preview_template').html()); } else { CRM.loadPage(CRM.url("civicrm/ajax/inline", {class_name: 'CRM_UF_Form_Inline_PreviewById', id: this.getUfGroupId()}), {target: $pane}); } }, doShowPreview: function() { var $preview = this.$('.crm-profile-selector-preview'); var $pane = this.$('.crm-profile-selector-preview-pane'); if ($preview.hasClass('crm-profile-selector-preview-show')) { $preview.removeClass('crm-profile-selector-preview-show'); $preview.find('.crm-i').removeClass('fa-television').addClass('fa-times'); $pane.show(); } else { $preview.addClass('crm-profile-selector-preview-show'); $preview.find('.crm-i').removeClass('fa-times').addClass('fa-television'); $pane.hide(); } }, disableForm: function() { this.$(':input', '.crm-profile-selector-preview-pane').not('.select2-input').prop('readOnly', true); }, doEdit: function(e) { e.preventDefault(); var profileSelectorView = this; var designerDialog = new CRM.Designer.DesignerDialog({ findCreateUfGroupModel: function(options) { var ufId = profileSelectorView.getUfGroupId(); // Retrieve UF group and fields from the api CRM.api('UFGroup', 'getsingle', {id: ufId, "api.UFField.get": 1}, { success: function(formData) { // Note: With chaining, API returns some extraneous keys that aren't part of UFGroupModel var ufGroupModel = new CRM.UF.UFGroupModel(_.pick(formData, _.keys(CRM.UF.UFGroupModel.prototype.schema))); ufGroupModel.setUFGroupModel(ufGroupModel.calculateContactEntityType(), profileSelectorView.options.ufEntities); ufGroupModel.getRel('ufFieldCollection').reset(_.values(formData["api.UFField.get"].values)); options.onLoad(ufGroupModel); } }); } }); CRM.designerApp.vent.on('ufSaved', this.onSave, this); this.setDialog(designerDialog); }, doCopy: function(e) { e.preventDefault(); // This is largely the same as doEdit, but we ultimately pass in a deepCopy of the ufGroupModel. var profileSelectorView = this; var designerDialog = new CRM.Designer.DesignerDialog({ findCreateUfGroupModel: function(options) { var ufId = profileSelectorView.getUfGroupId(); // Retrieve UF group and fields from the api CRM.api('UFGroup', 'getsingle', {id: ufId, "api.UFField.get": 1}, { success: function(formData) { // Note: With chaining, API returns some extraneous keys that aren't part of UFGroupModel var ufGroupModel = new CRM.UF.UFGroupModel(_.pick(formData, _.keys(CRM.UF.UFGroupModel.prototype.schema))); ufGroupModel.setUFGroupModel(ufGroupModel.calculateContactEntityType(), profileSelectorView.options.ufEntities); ufGroupModel.getRel('ufFieldCollection').reset(_.values(formData["api.UFField.get"].values)); options.onLoad(ufGroupModel.deepCopy()); } }); } }); CRM.designerApp.vent.on('ufSaved', this.onSave, this); this.setDialog(designerDialog); }, doCreate: function(e) { e.preventDefault(); var profileSelectorView = this; var designerDialog = new CRM.Designer.DesignerDialog({ findCreateUfGroupModel: function(options) { // Initialize new UF group var ufGroupModel = new CRM.UF.UFGroupModel(); ufGroupModel.getRel('ufEntityCollection').reset(profileSelectorView.options.ufEntities); options.onLoad(ufGroupModel); } }); CRM.designerApp.vent.on('ufSaved', this.onSave, this); this.setDialog(designerDialog); }, onSave: function() { CRM.designerApp.vent.off('ufSaved', this.onSave, this); var ufGroupId = this.activeDialog.model.get('id'); var modelFromCollection = this.options.ufGroupCollection.get(ufGroupId); if (modelFromCollection) { // copy in changes to UFGroup modelFromCollection.set(this.activeDialog.model.toStrictJSON()); } else { // add in new UFGroup modelFromCollection = new CRM.UF.UFGroupModel(this.activeDialog.model.toStrictJSON()); this.options.ufGroupCollection.add(modelFromCollection); } this.setUfGroupId(ufGroupId); this.doPreview(); }, setDialog: function(view) { if (this.activeDialog) { this.activeDialog.close(); } this.activeDialog = view; view.render(); } }); })(CRM.$, CRM._);