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