Skip to content

Commit eac3614

Browse files
Merge pull request #19550 from MauricioFauth/jquery-ui
Replace jQuery UI's tooltip with Bootstrap's Tooltip
2 parents 1ee682d + 887cd54 commit eac3614

16 files changed

Lines changed: 84 additions & 143 deletions

File tree

‎public/themes/bootstrap/scss/_bootstrap.scss‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
@import "../../../../node_modules/bootstrap/scss/close";
3434
//@import "../../../../node_modules/bootstrap/scss/toasts";
3535
@import "../../../../node_modules/bootstrap/scss/modal";
36-
//@import "../../../../node_modules/bootstrap/scss/tooltip";
36+
@import "../../../../node_modules/bootstrap/scss/tooltip";
3737
//@import "../../../../node_modules/bootstrap/scss/popover";
3838
//@import "../../../../node_modules/bootstrap/scss/carousel";
3939
@import "../../../../node_modules/bootstrap/scss/spinners";

‎public/themes/bootstrap/scss/_common.scss‎

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,23 +1275,6 @@ input#auto_increment_opt {
12751275
position: absolute;
12761276
}
12771277

1278-
.tooltip {
1279-
background: #333 !important;
1280-
opacity: 0.8 !important;
1281-
z-index: 9999;
1282-
border: 1px solid $black !important;
1283-
border-radius: 0.3em !important;
1284-
text-shadow: -1px -1px $black !important;
1285-
font-size: 0.8em !important;
1286-
font-weight: bold !important;
1287-
padding: 1px 3px !important;
1288-
1289-
* {
1290-
background: none !important;
1291-
color: $white !important;
1292-
}
1293-
}
1294-
12951278
.cDrop {
12961279
right: 0;
12971280
position: absolute;

‎resources/js/global.d.ts‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,6 @@ interface JQuery {
2323

2424
filterByValue: (value: any) => any;
2525

26-
uiTooltip(): JQuery;
27-
uiTooltip(methodName: 'destroy'): void;
28-
uiTooltip(methodName: 'disable'): void;
29-
uiTooltip(methodName: 'enable'): void;
30-
uiTooltip(methodName: 'open'): void;
31-
uiTooltip(methodName: 'close'): void;
32-
uiTooltip(methodName: 'widget'): JQuery;
33-
uiTooltip(methodName: string): JQuery;
34-
uiTooltip(options: JQueryUI.TooltipOptions): JQuery;
35-
uiTooltip(optionLiteral: string, optionName: string): any;
36-
uiTooltip(optionLiteral: string, options: JQueryUI.TooltipOptions): any;
37-
uiTooltip(optionLiteral: string, optionName: string, optionValue: any): JQuery;
38-
3926
tablesorter: any;
4027
}
4128

‎resources/js/src/database/structure.ts‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { AJAX } from '../modules/ajax.ts';
33
import { getForeignKeyCheckboxLoader, loadForeignKeyCheckbox } from '../modules/functions.ts';
44
import { Navigation } from '../modules/navigation.ts';
55
import { CommonParams } from '../modules/common.ts';
6-
import tooltip from '../modules/tooltip.ts';
76
import { ajaxRemoveMessage, ajaxShowMessage } from '../modules/ajax-message.ts';
87
import getJsConfirmCommonParam from '../modules/functions/getJsConfirmCommonParam.ts';
98
import { escapeHtml, escapeJsString } from '../modules/functions/escape.ts';
@@ -85,6 +84,12 @@ function fetchRealRowCount ($target) {
8584
});
8685
}
8786

87+
function addTooltipToFavoriteIcons (): void {
88+
document.querySelectorAll('.favorite_table_anchor').forEach((favoriteTableAnchor: HTMLElement): void => {
89+
new window.bootstrap.Tooltip(favoriteTableAnchor);
90+
});
91+
}
92+
8893
AJAX.registerOnload('database/structure.js', function () {
8994
/**
9095
* Event handler on select of "Make consistent with central list"
@@ -304,10 +309,7 @@ AJAX.registerOnload('database/structure.js', function () {
304309
}, loadForeignKeyCheckbox);
305310
}); // end of Drop Table Ajax action
306311

307-
// Add tooltip to favorite icons.
308-
$('.favorite_table_anchor').each(function () {
309-
tooltip($(this), 'a', $(this).attr('title'));
310-
});
312+
addTooltipToFavoriteIcons();
311313

312314
// Get real row count via Ajax.
313315
$('a.real_row_count').on('click', function (event) {

‎resources/js/src/makegrid.ts‎

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
updateCode
1111
} from './modules/functions.ts';
1212
import { CommonParams } from './modules/common.ts';
13-
import tooltip from './modules/tooltip.ts';
1413
import highlightSql from './modules/sql-highlight.ts';
1514
import { ajaxShowMessage } from './modules/ajax-message.ts';
1615
import { escapeHtml } from './modules/functions/escape.ts';
@@ -1761,9 +1760,9 @@ const makeGrid = function (t, enableResize = undefined, enableReorder = undefine
17611760
})
17621761
.on('mouseleave', function () {
17631762
g.showReorderHint = false;
1764-
$(this).uiTooltip('option', {
1765-
content: g.updateHint()
1766-
});
1763+
1764+
window.bootstrap.Tooltip.getOrCreateInstance(this, { title: g.updateHint(), html: true })
1765+
.setContent({ '.tooltip-inner': g.updateHint() });
17671766
})
17681767
.on('dblclick', function (e) {
17691768
e.preventDefault();
@@ -1835,8 +1834,13 @@ const makeGrid = function (t, enableResize = undefined, enableReorder = undefine
18351834

18361835
// make sure we have more than one column
18371836
if ($firstRowCols.length > 1) {
1838-
var $colVisibTh = $(g.t).find('th:not(.draggable)').slice(0, 1);
1839-
tooltip($colVisibTh, 'th', window.Messages.strColVisibHint);
1837+
const colVisibTh = g.t.querySelectorAll('th:not(.draggable)');
1838+
const $colVisibTh = $(colVisibTh).slice(0, 1);
1839+
1840+
colVisibTh.forEach((tableHeader: HTMLElement) => {
1841+
window.bootstrap.Tooltip.getOrCreateInstance(tableHeader, { title: window.Messages.strColVisibHint })
1842+
.setContent({ '.tooltip-inner': window.Messages.strColVisibHint });
1843+
});
18401844

18411845
// create column visibility drop-down arrow(s)
18421846
$colVisibTh.each(function () {
@@ -2278,10 +2282,13 @@ const makeGrid = function (t, enableResize = undefined, enableReorder = undefine
22782282
$(g.gDiv).append(g.cEditTextarea);
22792283

22802284
// add hint for grid editing feature when hovering "Edit" link in each table row
2281-
const editRowAnchor = $(g.t).find('.edit_row_anchor');
2282-
if (editRowAnchor.attr('data-grid-edit-config') !== 'disabled') {
2283-
editRowAnchor.find('a').tooltip();
2284-
}
2285+
g.t.querySelectorAll('.edit_row_anchor').forEach((editRowAnchor: HTMLElement) => {
2286+
if (editRowAnchor.dataset.gridEditConfig === 'disabled') {
2287+
return;
2288+
}
2289+
2290+
window.bootstrap.Tooltip.getOrCreateInstance(editRowAnchor.querySelector('a'));
2291+
});
22852292
}
22862293
};
22872294

@@ -2374,22 +2381,29 @@ const makeGrid = function (t, enableResize = undefined, enableReorder = undefine
23742381
}
23752382

23762383
// create tooltip for each <th> with draggable class
2377-
tooltip($(t).find('th.draggable'), 'th', g.updateHint());
2384+
t.querySelectorAll('th.draggable').forEach((tableHeader: HTMLElement) => {
2385+
window.bootstrap.Tooltip.getOrCreateInstance(tableHeader, { title: g.updateHint(), html: true })
2386+
.setContent({ '.tooltip-inner': g.updateHint() });
2387+
});
23782388

23792389
// register events for hint tooltip (anchors inside draggable th)
23802390
$(t).find('th.draggable a')
23812391
.on('mouseenter', function () {
23822392
g.showSortHint = true;
23832393
g.showMultiSortHint = true;
2384-
$(t).find('th.draggable').uiTooltip('option', {
2385-
content: g.updateHint()
2394+
2395+
t.querySelectorAll('th.draggable').forEach((tableHeader: HTMLElement) => {
2396+
window.bootstrap.Tooltip.getOrCreateInstance(tableHeader, { title: g.updateHint(), html: true })
2397+
.setContent({ '.tooltip-inner': g.updateHint() });
23862398
});
23872399
})
23882400
.on('mouseleave', function () {
23892401
g.showSortHint = false;
23902402
g.showMultiSortHint = false;
2391-
$(t).find('th.draggable').uiTooltip('option', {
2392-
content: g.updateHint()
2403+
2404+
t.querySelectorAll('th.draggable').forEach((tableHeader: HTMLElement) => {
2405+
window.bootstrap.Tooltip.getOrCreateInstance(tableHeader, { title: g.updateHint(), html: true })
2406+
.setContent({ '.tooltip-inner': g.updateHint() });
23932407
});
23942408
});
23952409

‎resources/js/src/modules/ajax-message.ts‎

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import $ from 'jquery';
2-
import tooltip from './tooltip.ts';
32
import highlightSql from './sql-highlight.ts';
43

54
/**
@@ -115,9 +114,7 @@ const ajaxShowMessage = function (message = null, timeout = null, type = null) {
115114
$retval
116115
.delay(newTimeOut)
117116
.fadeOut('medium', function () {
118-
if ($(this).is(':data(tooltip)')) {
119-
$(this).uiTooltip('destroy');
120-
}
117+
window.bootstrap.Tooltip.getInstance(this)?.dispose();
121118

122119
// Remove the notification
123120
$(this).remove();
@@ -132,7 +129,8 @@ const ajaxShowMessage = function (message = null, timeout = null, type = null) {
132129
* Add a tooltip to the notification to let the user know that they
133130
* can dismiss the ajax notification by clicking on it.
134131
*/
135-
tooltip($retval, 'span', window.Messages.strDismiss);
132+
window.bootstrap.Tooltip.getOrCreateInstance($retval.get(0), { title: window.Messages.strDismiss })
133+
.setContent({ '.tooltip-inner': window.Messages.strDismiss });
136134
}
137135

138136
// Hide spinner if this is not a loading message
@@ -152,15 +150,13 @@ const ajaxShowMessage = function (message = null, timeout = null, type = null) {
152150
*/
153151
const ajaxRemoveMessage = function ($thisMessageBox: JQuery | boolean): void {
154152
if ($thisMessageBox !== undefined && typeof $thisMessageBox !== 'boolean' && $thisMessageBox instanceof $) {
153+
window.bootstrap.Tooltip.getInstance($thisMessageBox.get(0))?.dispose();
154+
155155
$thisMessageBox
156156
.stop(true, true)
157157
.fadeOut('medium');
158158

159-
if ($thisMessageBox.is(':data(tooltip)')) {
160-
$thisMessageBox.uiTooltip('destroy');
161-
} else {
162-
$thisMessageBox.remove();
163-
}
159+
$thisMessageBox.remove();
164160
}
165161
};
166162

‎resources/js/src/modules/functions.ts‎

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import $ from 'jquery';
22
import { AJAX } from './ajax.ts';
33
import { Navigation } from './navigation.ts';
44
import { CommonParams } from './common.ts';
5-
import tooltip from './tooltip.ts';
65
import highlightSql from './sql-highlight.ts';
76
import { ajaxRemoveMessage, ajaxShowMessage } from './ajax-message.ts';
87
import { escapeHtml } from './functions/escape.ts';
@@ -123,11 +122,13 @@ export function addDatepicker ($thisElement, type = undefined, options = undefin
123122
// Fix wrong timepicker z-index, doesn't work without timeout
124123
$('#ui-timepicker-div').css('z-index', $('#ui-datepicker-div').css('z-index'));
125124
// Integrate tooltip text into dialog
126-
var tooltip = $thisElement.uiTooltip('instance');
127-
if (typeof tooltip !== 'undefined') {
128-
tooltip.disable();
129-
var $note = $('<p class="note"></div>');
130-
$note.text(tooltip.option('content'));
125+
if ($thisElement.hasClass('timefield')) {
126+
const $note = $('<p class="note"></div>');
127+
$note.text(window.Messages.strMysqlAllowedValuesTipTime);
128+
$('div.ui-datepicker').append($note);
129+
} else if ($thisElement.hasClass('datefield')) {
130+
const $note = $('<p class="note"></div>');
131+
$note.text(window.Messages.strMysqlAllowedValuesTipDate);
131132
$('div.ui-datepicker').append($note);
132133
}
133134
}, 0);
@@ -141,17 +142,13 @@ export function addDatepicker ($thisElement, type = undefined, options = undefin
141142
if (typeof $thisElement.data('datepicker') !== 'undefined') {
142143
$thisElement.data('datepicker').inline = false;
143144
}
144-
145-
var tooltip = $thisElement.uiTooltip('instance');
146-
if (typeof tooltip !== 'undefined') {
147-
tooltip.enable();
148-
}
149145
}
150146
};
151147
if (type === 'time') {
152148
$thisElement.timepicker($.extend(defaultOptions, options));
153149
// Add a tip regarding entering MySQL allowed-values for TIME data-type
154-
tooltip($thisElement, 'input', window.Messages.strMysqlAllowedValuesTipTime);
150+
window.bootstrap.Tooltip.getOrCreateInstance($thisElement.get(0), { title: window.Messages.strMysqlAllowedValuesTipTime })
151+
.setContent({ '.tooltip-inner': window.Messages.strMysqlAllowedValuesTipTime });
155152
} else {
156153
$thisElement.datetimepicker($.extend(defaultOptions, options));
157154
}
@@ -198,12 +195,13 @@ export function addDateTimePicker () {
198195
firstDay: window.firstDayOfCalendar
199196
});
200197

201-
// Add a tip regarding entering MySQL allowed-values
202-
// for TIME and DATE data-type
203-
if ($(this).hasClass('timefield')) {
204-
tooltip($(this), 'input', window.Messages.strMysqlAllowedValuesTipTime);
205-
} else if ($(this).hasClass('datefield')) {
206-
tooltip($(this), 'input', window.Messages.strMysqlAllowedValuesTipDate);
198+
// Add a tip regarding entering MySQL allowed-values for TIME and DATE data-type
199+
if (this.classList.contains('timefield')) {
200+
window.bootstrap.Tooltip.getOrCreateInstance(this, { title: window.Messages.strMysqlAllowedValuesTipTime })
201+
.setContent({ '.tooltip-inner': window.Messages.strMysqlAllowedValuesTipTime });
202+
} else if (this.classList.contains('datefield')) {
203+
window.bootstrap.Tooltip.getOrCreateInstance(this, { title: window.Messages.strMysqlAllowedValuesTipDate })
204+
.setContent({ '.tooltip-inner': window.Messages.strMysqlAllowedValuesTipDate });
207205
}
208206
});
209207
}
@@ -1507,22 +1505,6 @@ export function dismissNotifications () {
15071505
}
15081506
});
15091507

1510-
/**
1511-
* The below two functions hide the "Dismiss notification" tooltip when a user
1512-
* is hovering a link or button that is inside an ajax message
1513-
*/
1514-
$(document).on('mouseover', 'span.ajax_notification a, span.ajax_notification button, span.ajax_notification input', function () {
1515-
if ($(this).parents('span.ajax_notification').is(':data(tooltip)')) {
1516-
$(this).parents('span.ajax_notification').uiTooltip('disable');
1517-
}
1518-
});
1519-
1520-
$(document).on('mouseout', 'span.ajax_notification a, span.ajax_notification button, span.ajax_notification input', function () {
1521-
if ($(this).parents('span.ajax_notification').is(':data(tooltip)')) {
1522-
$(this).parents('span.ajax_notification').uiTooltip('enable');
1523-
}
1524-
});
1525-
15261508
$(document).on('click', 'a.copyQueryBtn', function (event) {
15271509
event.preventDefault();
15281510
var copyStatus = copyToClipboard($(this).attr('data-text'));
@@ -1536,11 +1518,8 @@ export function dismissNotifications () {
15361518
message = $(this).hasClass('copyQueryBtn') ? window.Messages.strCopyToClipboard : window.Messages.strEditQuery;
15371519
}
15381520

1539-
tooltip(
1540-
$('.ajax_notification'),
1541-
'span',
1542-
message
1543-
);
1521+
window.bootstrap.Tooltip.getOrCreateInstance('.ajax_notification', { title: message })
1522+
.setContent({ '.tooltip-inner': message });
15441523
});
15451524

15461525
$(document).on('mouseup', '.ajax_notification a', function (event) {
@@ -2846,13 +2825,19 @@ export function showIndexEditDialog ($outer) {
28462825
* in the whole body
28472826
**/
28482827
export function showHints ($div: JQuery<HTMLElement> | undefined = undefined) {
2828+
if ($('#no_hint').length > 0) {
2829+
return;
2830+
}
2831+
28492832
var $newDiv = $div;
28502833
if ($newDiv === undefined || ! ($newDiv instanceof $) || $newDiv.length === 0) {
28512834
$newDiv = $('body');
28522835
}
28532836

2854-
$newDiv.find('.pma_hint').each(function () {
2855-
tooltip($(this).children('img'), 'img', $(this).children('span').html());
2837+
$newDiv.get(0).querySelectorAll('.pma_hint').forEach((hintElement: HTMLElement): void => {
2838+
const content = hintElement.querySelector('span').textContent;
2839+
window.bootstrap.Tooltip.getOrCreateInstance(hintElement, { title: content })
2840+
.setContent({ '.tooltip-inner': content });
28562841
});
28572842
}
28582843

‎resources/js/src/modules/navigation/event-loader.ts‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ import { Navigation } from '../navigation.ts';
44
import handleCreateViewModal from '../functions/handleCreateViewModal.ts';
55
import { ajaxRemoveMessage, ajaxShowMessage } from '../ajax-message.ts';
66
import isStorageSupported from '../functions/isStorageSupported.ts';
7-
import tooltip from '../tooltip.ts';
7+
8+
function updateFavoriteTableButton (buttonId: string, htmlContent: string): void {
9+
const currentButton = document.getElementById(buttonId);
10+
// Remove current tooltip before changing the button
11+
window.bootstrap.Tooltip.getInstance(currentButton)?.dispose();
12+
currentButton.outerHTML = htmlContent;
13+
// Enable tooltip of the new button
14+
new window.bootstrap.Tooltip(document.getElementById(buttonId));
15+
}
816

917
/**
1018
* @return {function}
@@ -260,7 +268,6 @@ export default function onloadNavigation () {
260268
$(document).on('click', '.favorite_table_anchor', function (event) {
261269
event.preventDefault();
262270
var $self = $(this);
263-
var anchorId = $self.attr('id');
264271
if ($self.data('favtargetn') !== null) {
265272
var $dataFavTargets = $('a[data-favtargets="' + $self.data('favtargetn') + '"]');
266273
if ($dataFavTargets.length > 0) {
@@ -283,8 +290,10 @@ export default function onloadNavigation () {
283290
success: function (data) {
284291
if (data.changes) {
285292
$('#favoriteTableList').html(data.list);
286-
$('#' + anchorId).parent().html(data.anchor);
287-
tooltip($('#' + anchorId), 'a', $('#' + anchorId).attr('title'));
293+
if ($self.attr('id')) {
294+
updateFavoriteTableButton($self.attr('id'), data.anchor);
295+
}
296+
288297
// Update localStorage.
289298
if (isStorageSupported('localStorage')) {
290299
window.localStorage.favoriteTables = data.favoriteTables;

0 commit comments

Comments
 (0)