Merge pull request #22449 from mattwire/phpnotices
[civicrm-core.git] / templates / CRM / common / TabHeader.js
1 // https://civicrm.org/licensing
2 (function($, _) {
3 /**
4 * By default this simply loads tabs via ajax CRM.loadPage method
5 * Tabs with class 'ajaxForm' will use CRM.loadForm instead, suitable for most forms
6 * Tabs with class 'livePage' will get popup action links, suitable for crud tables
7 */
8 $(function($) {
9 // CRM.tabSettings.active is the name of the tab which should open on page load
10 var tabSettings = CRM.tabSettings ? _.cloneDeep(CRM.tabSettings) : {};
11 tabSettings.active = tabSettings.active ? $('#tab_' + tabSettings.active).prevAll().length : 0;
12 $("#mainTabContainer")
13 .on('tabsbeforeactivate', function(e, ui) {
14 // CRM-14353 - Warn of unsaved changes for all forms except those which have opted out
15 if (CRM.utils.initialValueChanged($('form:not([data-warn-changes=false])', ui.oldPanel))) {
16 CRM.alert(ts('Your changes in the <em>%1</em> tab have not been saved.', {1: ui.oldTab.text()}), ts('Unsaved Changes'), 'warning');
17 }
18 })
19 .on('tabsbeforeload', function(e, ui) {
20 // Use civicrm ajax wrappers rather than the default $.load
21 if (!ui.panel.data("civiCrmSnippet")) {
22 var method = ui.tab.hasClass('ajaxForm') ? 'loadForm' : 'loadPage';
23 var params = {target: ui.panel};
24 if (method === 'loadForm') {
25 params.autoClose = params.openInline = params.cancelButton = params.refreshAction = false;
26 ui.panel.on('crmFormLoad', function() {
27 // Hack: "Save and done" and "Cancel" buttons submit without ajax
28 $('.cancel.crm-form-submit, button[name$=upload_done]', this).on('click', function(e) {
29 $(this).closest('form').ajaxFormUnbind();
30 });
31 });
32 }
33 if (ui.tab.hasClass('livePage') && CRM.config.ajaxPopupsEnabled) {
34 ui.panel
35 .off('click.crmLivePage')
36 .on('click.crmLivePage', 'a.button, a.action-item', CRM.popup)
37 .on('crmPopupFormSuccess.crmLivePage', 'a.button, a.action-item:not(.crm-enable-disable)', CRM.refreshParent);
38 }
39 ui.panel
40 .off('.tabInfo')
41 .on('crmLoad.tabInfo crmFormSuccess.tabInfo', function(e, data) {
42 if (data) {
43 if (typeof(data.tabCount) !== 'undefined') {
44 CRM.tabHeader.updateCount(ui.tab, data.tabCount);
45 }
46 if (typeof(data.tabValid) !== 'undefined') {
47 var method = data.tabValid ? 'removeClass' : 'addClass';
48 ui.tab[method]('disabled');
49 }
50 }
51 });
52 CRM[method]($('a', ui.tab).attr('href'), params);
53 }
54 e.preventDefault();
55 })
56 .tabs(tabSettings);
57 // Any load/submit event could potentially call for tabs to refresh.
58 $(document).on('crmLoad.tabInfo crmFormSuccess.tabInfo', function(e, data) {
59 if (data && $.isPlainObject(data.updateTabs)) {
60 $.each(data.updateTabs, CRM.tabHeader.updateCount);
61 $.each(data.updateTabs, CRM.tabHeader.resetTab);
62 }
63 });
64 });
65
66 // Utility functions
67 CRM.tabHeader = CRM.tabHeader || {};
68
69 /**
70 * Return active tab
71 */
72 CRM.tabHeader.getActiveTab = function() {
73 return $('.ui-tabs-active', '#mainTabContainer');
74 };
75
76 /**
77 * Make a given tab the active one
78 * @param tab jQuery selector
79 */
80 CRM.tabHeader.focus = function(tab) {
81 $('#mainTabContainer').tabs('option', 'active', $(tab).prevAll().length);
82 };
83
84 /**
85 * @param tab jQuery selector
86 * @returns panel jQuery object
87 */
88 CRM.tabHeader.getTabPanel = function(tab) {
89 var selector = $(tab).attr('aria-controls');
90 return selector ? $('#' + selector) : $();
91 };
92
93 /**
94 * @param tab jQuery selector
95 * @returns {string|null}
96 */
97 function getCountClass(tab) {
98 var $tab = $(tab),
99 css = $tab.attr('class') || '',
100 val = css.match(/(crm-count-\d+)/);
101 return val && val.length ? val[0] : null;
102 }
103
104 /**
105 * @param tab jQuery selector
106 * @returns {Number|null}
107 */
108 CRM.tabHeader.getCount = function(tab) {
109 var cssClass = getCountClass(tab);
110 return cssClass ? parseInt(cssClass.slice(10), 10) : null;
111 };
112
113 /**
114 * Update the counter in a tab
115 * @param tab jQuery selector
116 * @param count {Number}
117 */
118 CRM.tabHeader.updateCount = function(tab, count) {
119 var oldClass = getCountClass(tab);
120 if (oldClass) {
121 $(tab).removeClass(oldClass);
122 }
123 $(tab)
124 .addClass('crm-count-' + count)
125 .find('a em').html('' + count);
126 };
127
128 /**
129 * Refresh tab immediately if it is active (or force=true)
130 * otherwise ensure it will be refreshed next time the user clicks on it
131 *
132 * @param tab
133 * @param force
134 */
135 CRM.tabHeader.resetTab = function(tab, force) {
136 var $panel = CRM.tabHeader.getTabPanel(tab);
137 if ($(tab).hasClass('ui-tabs-active')) {
138 $panel.crmSnippet('refresh');
139 }
140 else if (force) {
141 if ($panel.data("civiCrmSnippet")) {
142 $panel.crmSnippet('refresh');
143 } else {
144 $("#mainTabContainer").trigger('tabsbeforeload', [{panel: $panel, tab: $(tab)}]);
145 }
146 }
147 else if ($panel.data("civiCrmSnippet")) {
148 $panel.crmSnippet('destroy');
149 }
150 };
151 })(CRM.$, CRM._);