-
Notifications
You must be signed in to change notification settings - Fork 639
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TASK] Migrate LiveSearch to TypeScript
Resolves: #82592 Releases: master Change-Id: I1d07106cf79d552b62b4e9dedd61d4d1f7de007f Reviewed-on: https://review.typo3.org/55999 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Mathias Schreiber <mathias.schreiber@typo3.com> Tested-by: Mathias Schreiber <mathias.schreiber@typo3.com> Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: Benni Mack <benni@typo3.org>
- Loading branch information
1 parent
1c22987
commit e10bee1
Showing
3 changed files
with
205 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
201 changes: 201 additions & 0 deletions
201
typo3/sysext/backend/Resources/Private/TypeScript/LiveSearch.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
/* | ||
* This file is part of the TYPO3 CMS project. | ||
* | ||
* It is free software; you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License, either version 2 | ||
* of the License, or any later version. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
* | ||
* The TYPO3 project - inspiring people to share! | ||
*/ | ||
|
||
import * as $ from 'jquery'; | ||
import Viewport = require('./Viewport'); | ||
import Icons = require('./Icons'); | ||
import 'jquery/autocomplete'; | ||
import 'TYPO3/CMS/Backend/jquery.clearable'; | ||
|
||
enum Identifiers { | ||
containerSelector = '#typo3-cms-backend-backend-toolbaritems-livesearchtoolbaritem', | ||
toolbarItem = '.t3js-toolbar-item-search', | ||
dropdownToggle = '.t3js-toolbar-search-dropdowntoggle', | ||
searchFieldSelector = '.t3js-topbar-navigation-search-field', | ||
formSelector = '.t3js-topbar-navigation-search' | ||
} | ||
|
||
interface ResultItem { | ||
editLink: string; | ||
iconHTML: string; | ||
id: string; | ||
pageId: number; | ||
title: string; | ||
typeLabel: string; | ||
} | ||
|
||
interface Suggestion { | ||
data: ResultItem; | ||
value: string; | ||
} | ||
|
||
/** | ||
* Module: TYPO3/CMS/Backend/LiveSearch | ||
* Global search to deal with everything in the backend that is search-related | ||
* @exports TYPO3/CMS/Backend/LiveSearch | ||
*/ | ||
class LiveSearch { | ||
private url: string = TYPO3.settings.ajaxUrls.livesearch; | ||
|
||
constructor() { | ||
Viewport.Topbar.Toolbar.registerEvent((): void => { | ||
this.registerAutocomplete(); | ||
this.registerEvents(); | ||
|
||
// Unset height, width and z-index | ||
$(Identifiers.toolbarItem).removeAttr('style'); | ||
|
||
$(Identifiers.searchFieldSelector).clearable({ | ||
onClear: (): void => { | ||
if ($(Identifiers.toolbarItem).hasClass('open')) { | ||
$(Identifiers.dropdownToggle).dropdown('toggle'); | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
private registerAutocomplete(): void { | ||
$(Identifiers.searchFieldSelector).autocomplete({ | ||
// ajax options | ||
serviceUrl: this.url, | ||
paramName: 'q', | ||
dataType: 'json', | ||
minChars: 2, | ||
width: '100%', | ||
groupBy: 'typeLabel', | ||
containerClass: Identifiers.toolbarItem.substr(1, Identifiers.toolbarItem.length), | ||
appendTo: Identifiers.containerSelector + ' .dropdown-menu', | ||
forceFixPosition: false, | ||
preserveInput: true, | ||
showNoSuggestionNotice: true, | ||
triggerSelectOnValidInput: false, | ||
preventBadQueries: false, | ||
noSuggestionNotice: '<h3 class="dropdown-headline">' + TYPO3.lang.liveSearch_listEmptyText + '</h3>' | ||
+ '<p>' + TYPO3.lang.liveSearch_helpTitle + '</p>' | ||
+ '<hr>' | ||
+ '<p>' + TYPO3.lang.liveSearch_helpDescription + '<br>' + TYPO3.lang.liveSearch_helpDescriptionPages + '</p>', | ||
// put the AJAX results in the right format | ||
transformResult: (response: Array<ResultItem>): { [key: string]: Array<Suggestion> } => { | ||
return { | ||
suggestions: $.map(response, (dataItem: ResultItem): Suggestion => { | ||
return {value: dataItem.title, data: dataItem}; | ||
}) | ||
}; | ||
}, | ||
formatGroup: (suggestion: Suggestion, category: string, i: number): string => { | ||
let html = ''; | ||
// add a divider if it's not the first group | ||
if (i > 0) { | ||
html = '<hr>'; | ||
} | ||
return html + '<h3 class="dropdown-headline">' + category + '</h3>'; | ||
}, | ||
// Rendering of each item | ||
formatResult: (suggestion: Suggestion): string => { | ||
return '' | ||
+ '<div class="dropdown-table">' | ||
+ '<div class="dropdown-table-row">' | ||
+ '<div class="dropdown-table-column dropdown-table-icon">' + suggestion.data.iconHTML + '</div>' | ||
+ '<div class="dropdown-table-column dropdown-table-title">' | ||
+ '<a class="dropdown-table-title-ellipsis dropdown-list-link"' | ||
+ ' href="#" data-pageid="' + suggestion.data.pageId + '" data-target="' + suggestion.data.editLink + '">' | ||
+ suggestion.data.title | ||
+ '</a>' | ||
+ '</div>' | ||
+ '</div>' | ||
+ '</div>' | ||
+ ''; | ||
}, | ||
onSearchStart: (): void => { | ||
const $toolbarItem = $(Identifiers.toolbarItem); | ||
if (!$toolbarItem.hasClass('loading')) { | ||
$toolbarItem.addClass('loading'); | ||
Icons.getIcon( | ||
'spinner-circle-light', | ||
Icons.sizes.small, | ||
'', | ||
Icons.states.default, | ||
Icons.markupIdentifiers.inline | ||
).done((markup: string): void => { | ||
$toolbarItem.find('.icon-apps-toolbar-menu-search').replaceWith(markup); | ||
}); | ||
} | ||
}, | ||
onSearchComplete: (): void => { | ||
const $toolbarItem = $(Identifiers.toolbarItem); | ||
const $searchField = $(Identifiers.searchFieldSelector); | ||
if (!$toolbarItem.hasClass('open') && $searchField.val().length > 1) { | ||
$(Identifiers.dropdownToggle).dropdown('toggle'); | ||
$searchField.focus(); | ||
} | ||
if ($toolbarItem.hasClass('loading')) { | ||
$toolbarItem.removeClass('loading'); | ||
Icons.getIcon( | ||
'apps-toolbar-menu-search', | ||
Icons.sizes.small, | ||
'', | ||
Icons.states.default, | ||
Icons.markupIdentifiers.inline | ||
).done((markup: string): void => { | ||
$toolbarItem.find('.icon-spinner-circle-light').replaceWith(markup); | ||
}); | ||
} | ||
}, | ||
beforeRender: (container: JQuery): void => { | ||
container.append('<hr><div>' + | ||
'<a href="#" class="btn btn-primary pull-right t3js-live-search-show-all">' + | ||
TYPO3.lang.liveSearch_showAllResults + | ||
'</a>' + | ||
'</div>'); | ||
if (!$(Identifiers.toolbarItem).hasClass('open')) { | ||
$(Identifiers.dropdownToggle).dropdown('toggle'); | ||
$(Identifiers.searchFieldSelector).focus(); | ||
} | ||
}, | ||
onHide: (): void => { | ||
if ($(Identifiers.toolbarItem).hasClass('open')) { | ||
$(Identifiers.dropdownToggle).dropdown('toggle'); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
private registerEvents(): void { | ||
const $searchField = $(Identifiers.searchFieldSelector); | ||
const $autocompleteContainer = $('.' + $searchField.autocomplete().options.containerClass); | ||
|
||
$(Identifiers.containerSelector).on('click', '.t3js-live-search-show-all', (evt: JQueryEventObject): void => { | ||
evt.preventDefault(); | ||
|
||
TYPO3.ModuleMenu.App.showModule('web_list', 'id=0&search_levels=-1&search_field=' + encodeURIComponent($searchField.val())); | ||
$searchField.val('').trigger('change'); | ||
}); | ||
if ($searchField.length) { | ||
$autocompleteContainer.on('click.autocomplete', '.dropdown-list-link', (evt: JQueryEventObject): void => { | ||
evt.preventDefault(); | ||
|
||
const $me = $(evt.currentTarget); | ||
top.jump($me.data('target'), 'web_list', 'web', $me.data('pageid')); | ||
$searchField.val('').trigger('change'); | ||
}); | ||
} | ||
|
||
// Prevent submitting the search form | ||
$(Identifiers.formSelector).on('submit', (evt: JQueryEventObject): void => { | ||
evt.preventDefault(); | ||
}); | ||
} | ||
} | ||
|
||
export = new LiveSearch(); |
144 changes: 1 addition & 143 deletions
144
typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.