0719121ff42ed16e4cc8391107a14d57b652457f
[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 'use strict';
19
20 var AjaxDataHandler = {};
21
22 /**
23 * generic function to call from the outside the script and validate directly showing errors
24 * @param parameters
25 * @return a jQuery deferred object (promise)
26 */
27 AjaxDataHandler.process = function(parameters) {
28 return AjaxDataHandler._call(parameters).done(function(result) {
29 if (result.hasErrors) {
30 AjaxDataHandler.handleErrors(result);
31 }
32 });
33 };
34
35 AjaxDataHandler.initialize = function() {
36
37 // HIDE/UNHIDE: click events for all action icons to hide/unhide
38 $(document).on('click', '.t3js-record-hide', function(evt) {
39 evt.preventDefault();
40 var $anchorElement = $(this);
41 var $iconElement = $anchorElement.find('i');
42 var $rowElement = $anchorElement.closest('tr[data-uid]');
43 var params = $anchorElement.data('params');
44 var removeClass = $anchorElement.data('state') === 'visible' ? 'fa-toggle-on' : 'fa-toggle-off';
45
46 // add a spinner
47 $iconElement.removeClass(removeClass);
48 AjaxDataHandler._showSpinnerIcon($iconElement);
49
50 // make the AJAX call to toggle the visibility
51 AjaxDataHandler._call(params).done(function(result) {
52 AjaxDataHandler._hideSpinnerIcon($iconElement);
53 // print messages on errors
54 if (result.hasErrors) {
55 AjaxDataHandler.handleErrors(result);
56 // revert to the old class
57 $iconElement.addClass(removeClass);
58 } else {
59 // adjust overlay icon
60 AjaxDataHandler.toggleRow($rowElement);
61 }
62 });
63 });
64
65 // DELETE: click events for all action icons to delete
66 $(document).on('click', '.t3js-record-delete', function(evt) {
67 evt.preventDefault();
68 var $anchorElement = $(this);
69 var $modal = top.TYPO3.Modal.confirm($anchorElement.data('title'), $anchorElement.data('message'), top.TYPO3.Severity.warning, [
70 {
71 text: $(this).data('button-close-text') || TYPO3.lang['button.cancel'] || 'Cancel',
72 active: true,
73 name: 'cancel'
74 },
75 {
76 text: $(this).data('button-ok-text') || TYPO3.lang['button.delete'] || 'Delete',
77 btnClass: 'btn-warning',
78 name: 'delete'
79 }
80 ]);
81 $modal.on('button.clicked', function(e) {
82 if (e.target.name === 'cancel') {
83 top.TYPO3.Modal.dismiss();
84 } else if (e.target.name === 'delete') {
85 top.TYPO3.Modal.dismiss();
86 AjaxDataHandler.deleteRecord($anchorElement);
87 }
88 });
89 });
90 };
91
92 /**
93 * Toggle row visibility after record has been changed
94 *
95 * @param $rowElement
96 */
97 AjaxDataHandler.toggleRow = function($rowElement) {
98 var $anchorElement = $rowElement.find('.t3js-record-hide');
99 var table = $anchorElement.closest('table[data-table]').data('table');
100 var params = $anchorElement.data('params');
101 var nextParams, nextState, className;
102
103 if ($anchorElement.data('state') === 'hidden') {
104 nextState = 'visible';
105 nextParams = params.replace('=0', '=1');
106 className = 'fa-toggle-on';
107 } else {
108 nextState = 'hidden';
109 nextParams = params.replace('=1', '=0');
110 className = 'fa-toggle-off';
111 }
112 $anchorElement.data('state', nextState).data('params', nextParams);
113
114 // Update tooltip title
115 $anchorElement.tooltip('hide').one('hidden.bs.tooltip', function() {
116 var nextTitle = $anchorElement.data('toggleTitle');
117 // Bootstrap Tooltip internally uses only .attr('data-original-title')
118 $anchorElement
119 .data('toggleTitle', $anchorElement.attr('data-original-title'))
120 .attr('data-original-title', nextTitle)
121 .tooltip('show');
122 });
123
124 var $iconElement = $anchorElement.find('i');
125 $iconElement.addClass(className);
126
127 var $icon = $rowElement.find('td.col-icon span.t3-icon');
128 var $overlayIcon = $icon.find('span.t3-icon');
129 if ($overlayIcon.length) {
130 $overlayIcon.remove();
131 } else {
132 $icon.append('<span class="t3-icon t3-icon-status t3-icon-status-overlay t3-icon-overlay-hidden t3-icon-overlay">&nbsp;</span>');
133 }
134
135 $rowElement.fadeTo('fast', 0.4, function() {
136 $rowElement.fadeTo('fast', 1);
137 });
138 if (table === 'pages') {
139 AjaxDataHandler.refreshPageTree();
140 }
141 };
142
143 /**
144 * delete record by given element (icon in table)
145 * don't call it directly!
146 *
147 * @param element
148 */
149 AjaxDataHandler.deleteRecord = function(element) {
150 var $anchorElement = $(element);
151 var elementClass = 'fa-trash';
152 var params = $anchorElement.data('params');
153 var $iconElement = $anchorElement.find('span');
154
155 // add a spinner
156 $iconElement.removeClass(elementClass);
157 AjaxDataHandler._showSpinnerIcon($iconElement);
158
159 // make the AJAX call to toggle the visibility
160 AjaxDataHandler._call(params).done(function(result) {
161 AjaxDataHandler._hideSpinnerIcon($iconElement);
162 // revert to the old class
163 $iconElement.addClass(elementClass);
164 // print messages on errors
165 if (result.hasErrors) {
166 AjaxDataHandler.handleErrors(result);
167 } else {
168 var $table = $anchorElement.closest('table[data-table]');
169 var $panel = $anchorElement.closest('.panel');
170 var $panelHeading = $panel.find('.panel-heading');
171 var table = $table.data('table');
172 var $rowElements = $anchorElement.closest('tr[data-uid]');
173 var uid = $rowElements.data('uid');
174 var $translatedRowElements = $table.find('[data-l10nparent=' + uid + ']').closest('tr[data-uid]');
175 $rowElements = $rowElements.add($translatedRowElements);
176
177 $rowElements.fadeTo('slow', 0.4, function() {
178 $rowElements.slideUp('slow', 0, function() {
179 $rowElements.remove();
180 if ($table.find('tbody tr').length === 0) {
181 $panel.slideUp('slow');
182 }
183 });
184 });
185 if ($anchorElement.data('l10parent') === '0' || $anchorElement.data('l10parent') === '') {
186 var count = Number($panelHeading.find('.t3js-table-total-items').html());
187 $panelHeading.find('.t3js-table-total-items').html(count-1);
188 }
189
190 if (table === 'pages') {
191 AjaxDataHandler.refreshPageTree();
192 }
193 }
194 });
195 };
196
197 /**
198 * handle the errors from result object
199 *
200 * @param result
201 * @private
202 */
203 AjaxDataHandler.handleErrors = function(result) {
204 $.each(result.messages, function(position, message) {
205 top.TYPO3.Notification.error(message.title, message.message);
206 });
207 };
208
209 /**
210 * refresh the page tree
211 * @private
212 */
213 AjaxDataHandler.refreshPageTree = function() {
214 if (top.TYPO3 && top.TYPO3.Backend && top.TYPO3.Backend.NavigationContainer && top.TYPO3.Backend.NavigationContainer.PageTree) {
215 top.TYPO3.Backend.NavigationContainer.PageTree.refreshTree();
216 }
217 };
218
219 /**
220 * AJAX call to tce_db.php
221 * returns a jQuery Promise to work with
222 * @private
223 */
224 AjaxDataHandler._call = function(params) {
225 return $.getJSON(TYPO3.settings.ajaxUrls['record_process'], params);
226 };
227
228 /**
229 * Replace the given icon with a spinner icon
230 * @private
231 */
232 AjaxDataHandler._showSpinnerIcon = function($iconElement) {
233 $iconElement.addClass('fa-spin fa-circle-o-notch');
234 };
235
236 /**
237 * Removes the spinner icon classes
238 * @private
239 */
240 AjaxDataHandler._hideSpinnerIcon = function($iconElement) {
241 $iconElement.removeClass('fa-spin fa-circle-o-notch');
242 };
243
244 /**
245 * initialize and return the object
246 */
247 return function() {
248 AjaxDataHandler.initialize();
249
250 // return the object in the global space
251 return AjaxDataHandler;
252 }();
253 });