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