6b86d6718e3bce287657acf803fd3a04836808db
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Resources / Public / JavaScript / AjaxDataHandler.js
1 /**
2 * This file is part of the TYPO3 CMS project.
3 *
4 * It is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, either version 2
6 * of the License, or any later version.
7 *
8 * For the full copyright and license information, please read the
9 * LICENSE.txt file that was distributed with this source code.
10 *
11 * The TYPO3 project - inspiring people to share!
12 */
13
14 /**
15 * AjaxDataHandler - Javascript functions to work with AJAX and interacting with tce_db.php
16 */
17 define('TYPO3/CMS/Backend/AjaxDataHandler', ['jquery', 'TYPO3/CMS/Backend/Notification', 'TYPO3/CMS/Backend/Modal'], function ($) {
18 var AjaxDataHandler = {};
19
20 /**
21 * generic function to call from the outside the script and validate directly showing errors
22 * @param parameters
23 * @return a jQuery deferred object (promise)
24 */
25 AjaxDataHandler.process = function(parameters) {
26 return AjaxDataHandler._call(parameters).done(function(result) {
27 if (result.hasErrors) {
28 AjaxDataHandler.handleErrors(result);
29 }
30 });
31 };
32
33 AjaxDataHandler.initialize = function() {
34
35 // HIDE/UNHIDE: click events for all action icons to hide/unhide
36 $(document).on('click', '.t3js-record-hide', function(evt) {
37 evt.preventDefault();
38 var $anchorElement = $(this);
39 var $iconElement = $anchorElement.find('span');
40 var $rowElement = $anchorElement.closest('tr[data-uid]');
41 var table = $anchorElement.closest('table[data-table]').data('table');
42 var hasVisibleState = $anchorElement.data('state') === 'visible';
43 var params = $anchorElement.data('params');
44
45 var removeClass = hasVisibleState ? 'fa-toggle-on' : 'fa-toggle-off';
46 var addClass = hasVisibleState ? 'fa-toggle-off' : 'fa-toggle-on';
47 var nextState = hasVisibleState ? 'hidden' : 'visible';
48 var nextParams = hasVisibleState ? params.replace('=1', '=0') : params.replace('=0', '=1');
49
50 // add a spinner
51 $iconElement.removeClass(removeClass);
52 AjaxDataHandler._showSpinnerIcon($iconElement);
53
54 // make the AJAX call to toggle the visibility
55 AjaxDataHandler._call(params).done(function(result) {
56 AjaxDataHandler._hideSpinnerIcon($iconElement);
57 // print messages on errors
58 if (result.hasErrors) {
59 AjaxDataHandler.handleErrors(result);
60 // revert to the old class
61 $iconElement.addClass(removeClass);
62 } else {
63 $anchorElement.data('state', nextState).data('params', nextParams);
64 $iconElement.removeClass(removeClass).addClass(addClass);
65 if (nextState === 'hidden') {
66 // add overlay icon
67 $rowElement.find('td.col-icon span.t3-icon').append('<span class="t3-icon t3-icon-status t3-icon-status-overlay t3-icon-overlay-hidden t3-icon-overlay">&nbsp;</span>');
68 } else {
69 // remove overlay icon
70 $rowElement.find('td.col-icon span.t3-icon span.t3-icon').remove();
71 }
72 $rowElement.fadeTo('fast', 0.4, function() {
73 $rowElement.fadeTo('fast', 1);
74 });
75
76 if (table === 'pages') {
77 AjaxDataHandler.refreshPageTree();
78 }
79 }
80 });
81 });
82
83 // DELETE: click events for all action icons to delete
84 $(document).on('click', '.t3js-record-delete', function(evt) {
85 evt.preventDefault();
86 var $anchorElement = $(this);
87 var $modal = top.TYPO3.Modal.confirm($anchorElement.data('title'), $anchorElement.data('message'), top.TYPO3.Severity.warning, [
88 {
89 text: $(this).data('button-close-text') || TYPO3.lang['button.cancel'] || 'Cancel',
90 active: true,
91 name: 'cancel'
92 },
93 {
94 text: $(this).data('button-ok-text') || TYPO3.lang['button.delete'] || 'Delete',
95 btnClass: 'btn-warning',
96 name: 'delete'
97 }
98 ]);
99 $modal.on('button.clicked', function(e) {
100 if (e.target.name === 'cancel') {
101 top.TYPO3.Modal.dismiss();
102 } else if (e.target.name === 'delete') {
103 top.TYPO3.Modal.dismiss();
104 AjaxDataHandler.deleteRecord($anchorElement);
105 }
106 });
107 });
108 };
109
110 /**
111 * delete record by given element (icon in table)
112 * don't call it directly!
113 *
114 * @param element
115 */
116 AjaxDataHandler.deleteRecord = function(element) {
117 var $anchorElement = $(element);
118 var elementClass = 'fa-trash';
119 var params = $anchorElement.data('params');
120 var $iconElement = $anchorElement.find('span');
121
122 // add a spinner
123 $iconElement.removeClass(elementClass);
124 AjaxDataHandler._showSpinnerIcon($iconElement);
125
126 // make the AJAX call to toggle the visibility
127 AjaxDataHandler._call(params).done(function(result) {
128 AjaxDataHandler._hideSpinnerIcon($iconElement);
129 // revert to the old class
130 $iconElement.addClass(elementClass);
131 // print messages on errors
132 if (result.hasErrors) {
133 AjaxDataHandler.handleErrors(result);
134 } else {
135 var $table = $anchorElement.closest('table[data-table]');
136 var $panel = $anchorElement.closest('.panel');
137 var $panelHeading = $panel.find('.panel-heading');
138 var table = $table.data('table');
139 var $rowElements = $anchorElement.closest('tr[data-uid]');
140 var uid = $rowElements.data('uid');
141 var $translatedRowElements = $table.find('[data-l10parent=' + uid + ']').closest('tr[data-uid]');
142 $rowElements = $rowElements.add($translatedRowElements);
143
144 $rowElements.fadeTo('slow', 0.4, function() {
145 $rowElements.slideUp('slow', 0, function() {
146 $rowElements.remove();
147 if ($table.find('tbody tr').length === 0) {
148 $panel.slideUp('slow');
149 }
150 });
151 });
152 if ($anchorElement.data('l10parent') === '0' || $anchorElement.data('l10parent') === '') {
153 var count = Number($panelHeading.find('.t3js-table-total-items').html());
154 $panelHeading.find('.t3js-table-total-items').html(count-1);
155 }
156
157 if (table === 'pages') {
158 AjaxDataHandler.refreshPageTree();
159 }
160 }
161 });
162 };
163
164 /**
165 * handle the errors from result object
166 *
167 * @param result
168 * @private
169 */
170 AjaxDataHandler.handleErrors = function(result) {
171 $.each(result.messages, function(position, message) {
172 top.TYPO3.Notification.error(message.title, message.message);
173 });
174 };
175
176 /**
177 * refresh the page tree
178 * @private
179 */
180 AjaxDataHandler.refreshPageTree = function() {
181 if (top.TYPO3 && top.TYPO3.Backend && top.TYPO3.Backend.NavigationContainer && top.TYPO3.Backend.NavigationContainer.PageTree) {
182 top.TYPO3.Backend.NavigationContainer.PageTree.refreshTree();
183 }
184 };
185
186 /**
187 * AJAX call to tce_db.php
188 * returns a jQuery Promise to work with
189 * @private
190 */
191 AjaxDataHandler._call = function(params) {
192 return $.getJSON(TYPO3.settings.ajaxUrls['DataHandler::process'], params);
193 };
194
195 /**
196 * Replace the given icon with a spinner icon
197 * @private
198 */
199 AjaxDataHandler._showSpinnerIcon = function($iconElement) {
200 $iconElement.addClass('fa-spin fa-circle-o-notch');
201 };
202
203 /**
204 * Removes the spinner icon classes
205 * @private
206 */
207 AjaxDataHandler._hideSpinnerIcon = function($iconElement) {
208 $iconElement.removeClass('fa-spin fa-circle-o-notch');
209 };
210
211 /**
212 * initialize and return the object
213 */
214 return function() {
215 AjaxDataHandler.initialize();
216
217 // return the object in the global space
218 return AjaxDataHandler;
219 }();
220 });