[TASK] Migrate LiveSearch to TypeScript 99/55999/4
authorAndreas Fernandez <a.fernandez@scripting-base.de>
Sun, 4 Mar 2018 15:04:10 +0000 (16:04 +0100)
committerBenni Mack <benni@typo3.org>
Wed, 7 Mar 2018 08:55:54 +0000 (09:55 +0100)
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>
Build/types/TYPO3/index.d.ts
typo3/sysext/backend/Resources/Private/TypeScript/LiveSearch.ts [new file with mode: 0644]
typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js

index 4ce0c03..65b084e 100644 (file)
@@ -56,6 +56,7 @@ interface Window {
   };
   rawurlencode: Function;
   list_frame: Window;
+  jump: Function;
 }
 
 /**
@@ -99,4 +100,6 @@ interface JQuery {
 
   // To be able to use twbs/bootstrap-slider we have to override the definition of jquerui
   slider(options: { [key: string]: any }): any;
+  // To be able to use jquery/autocomplete-slider we have to override the definition of jquerui
+  autocomplete(options?: { [key: string]: any }): any;
 }
diff --git a/typo3/sysext/backend/Resources/Private/TypeScript/LiveSearch.ts b/typo3/sysext/backend/Resources/Private/TypeScript/LiveSearch.ts
new file mode 100644 (file)
index 0000000..12acc50
--- /dev/null
@@ -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();
index 343cc22..c02a5ea 100644 (file)
  *
  * The TYPO3 project - inspiring people to share!
  */
-
-/**
- * Module: TYPO3/CMS/Backend/LiveSearch
- * Global search to deal with everything in the backend that is search-related
- * @exports TYPO3/CMS/Backend/LiveSearch
- */
-define([
-  'jquery',
-  'TYPO3/CMS/Backend/Viewport',
-  'TYPO3/CMS/Backend/Icons',
-  'jquery/autocomplete',
-  'TYPO3/CMS/Backend/jquery.clearable'
-], function($, Viewport, Icons) {
-  'use strict';
-
-  var containerSelector = '#typo3-cms-backend-backend-toolbaritems-livesearchtoolbaritem';
-  var toolbarItem = '.t3js-toolbar-item-search';
-  var dropdownToggle = '.t3js-toolbar-search-dropdowntoggle';
-  var searchFieldSelector = '.t3js-topbar-navigation-search-field';
-  var formSelector = '.t3js-topbar-navigation-search';
-  var url = TYPO3.settings.ajaxUrls['livesearch'];
-
-  Viewport.Topbar.Toolbar.registerEvent(function() {
-    $(searchFieldSelector).autocomplete({
-      // ajax options
-      serviceUrl: url,
-      paramName: 'q',
-      dataType: 'json',
-      minChars: 2,
-      width: '100%',
-      groupBy: 'typeLabel',
-      containerClass: toolbarItem.substr(1, toolbarItem.length),
-      appendTo: 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: function(response) {
-        return {
-          suggestions: $.map(response, function(dataItem) {
-            return {value: dataItem.title, data: dataItem};
-          })
-        };
-      },
-      formatGroup: function(suggestion, category, i) {
-        var 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: function(suggestion, value, i) {
-        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: function() {
-        if (!$(toolbarItem).hasClass('loading')) {
-          $(toolbarItem).addClass('loading');
-          Icons.getIcon('spinner-circle-light', Icons.sizes.small, '', 'default', 'inline').done(function(markup) {
-            $(toolbarItem).find('.icon-apps-toolbar-menu-search').replaceWith(markup)
-          });
-        }
-      },
-      onSearchComplete: function(query, suggestions) {
-        if (!$(toolbarItem).hasClass('open') && $(searchFieldSelector).val().length > 1) {
-          $(dropdownToggle).dropdown('toggle');
-          $(searchFieldSelector).focus();
-        }
-        if ($(toolbarItem).hasClass('loading')) {
-          $(toolbarItem).removeClass('loading');
-          Icons.getIcon('apps-toolbar-menu-search', Icons.sizes.small, '', 'default', 'inline').done(function(markup) {
-            $(toolbarItem).find('.icon-spinner-circle-light').replaceWith(markup)
-          });
-        }
-      },
-      beforeRender: function(container) {
-        container.append('<hr><div>' +
-          '<a href="#" class="btn btn-primary pull-right t3js-live-search-show-all">' +
-          TYPO3.lang['liveSearch_showAllResults'] +
-          '</a>' +
-          '</div>');
-        if (!$(toolbarItem).hasClass('open')) {
-          $(dropdownToggle).dropdown('toggle');
-          $(searchFieldSelector).focus();
-        }
-      },
-      onHide: function() {
-        if ($(toolbarItem).hasClass('open')) {
-          $(dropdownToggle).dropdown('toggle');
-        }
-      }
-    });
-
-    // set up the events
-    $(containerSelector).on('click', '.t3js-live-search-show-all', function(evt) {
-      evt.preventDefault();
-      TYPO3.ModuleMenu.App.showModule('web_list', 'id=0&search_levels=-1&search_field=' + encodeURIComponent($(searchFieldSelector).val()));
-      $(searchFieldSelector).val('').trigger('change');
-    });
-    if ($(searchFieldSelector).length) {
-      $('.' + $(searchFieldSelector).autocomplete().options.containerClass).on('click.autocomplete', '.dropdown-list-link', function(evt) {
-        evt.preventDefault();
-        jump($(this).data('target'), 'web_list', 'web', $(this).data('pageid'));
-        $(searchFieldSelector).val('').trigger('change');
-      });
-    }
-
-    // Unset height, width and z-index
-    $(toolbarItem).removeAttr('style');
-
-    $(searchFieldSelector).clearable({
-      onClear: function() {
-        if ($(toolbarItem).hasClass('open')) {
-          $(dropdownToggle).dropdown('toggle');
-        }
-      }
-    });
-
-    // Prevent submitting the search form
-    $(formSelector).submit(function(evt) {
-      evt.preventDefault();
-    });
-  });
-
-});
+define(["require","exports","jquery","./Viewport","./Icons","jquery/autocomplete","TYPO3/CMS/Backend/jquery.clearable"],function(e,t,o,a,r){"use strict";var n,l;return(l=n||(n={})).containerSelector="#typo3-cms-backend-backend-toolbaritems-livesearchtoolbaritem",l.toolbarItem=".t3js-toolbar-item-search",l.dropdownToggle=".t3js-toolbar-search-dropdowntoggle",l.searchFieldSelector=".t3js-topbar-navigation-search-field",l.formSelector=".t3js-topbar-navigation-search",new(function(){function e(){var e=this;this.url=TYPO3.settings.ajaxUrls.livesearch,a.Topbar.Toolbar.registerEvent(function(){e.registerAutocomplete(),e.registerEvents(),o(n.toolbarItem).removeAttr("style"),o(n.searchFieldSelector).clearable({onClear:function(){o(n.toolbarItem).hasClass("open")&&o(n.dropdownToggle).dropdown("toggle")}})})}return e.prototype.registerAutocomplete=function(){o(n.searchFieldSelector).autocomplete({serviceUrl:this.url,paramName:"q",dataType:"json",minChars:2,width:"100%",groupBy:"typeLabel",containerClass:n.toolbarItem.substr(1,n.toolbarItem.length),appendTo:n.containerSelector+" .dropdown-menu",forceFixPosition:!1,preserveInput:!0,showNoSuggestionNotice:!0,triggerSelectOnValidInput:!1,preventBadQueries:!1,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>",transformResult:function(e){return{suggestions:o.map(e,function(e){return{value:e.title,data:e}})}},formatGroup:function(e,t,o){var a="";return o>0&&(a="<hr>"),a+'<h3 class="dropdown-headline">'+t+"</h3>"},formatResult:function(e){return'<div class="dropdown-table"><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+e.data.iconHTML+'</div><div class="dropdown-table-column dropdown-table-title"><a class="dropdown-table-title-ellipsis dropdown-list-link" href="#" data-pageid="'+e.data.pageId+'" data-target="'+e.data.editLink+'">'+e.data.title+"</a></div></div></div>"},onSearchStart:function(){var e=o(n.toolbarItem);e.hasClass("loading")||(e.addClass("loading"),r.getIcon("spinner-circle-light",r.sizes.small,"",r.states.default,r.markupIdentifiers.inline).done(function(t){e.find(".icon-apps-toolbar-menu-search").replaceWith(t)}))},onSearchComplete:function(){var e=o(n.toolbarItem),t=o(n.searchFieldSelector);!e.hasClass("open")&&t.val().length>1&&(o(n.dropdownToggle).dropdown("toggle"),t.focus()),e.hasClass("loading")&&(e.removeClass("loading"),r.getIcon("apps-toolbar-menu-search",r.sizes.small,"",r.states.default,r.markupIdentifiers.inline).done(function(t){e.find(".icon-spinner-circle-light").replaceWith(t)}))},beforeRender:function(e){e.append('<hr><div><a href="#" class="btn btn-primary pull-right t3js-live-search-show-all">'+TYPO3.lang.liveSearch_showAllResults+"</a></div>"),o(n.toolbarItem).hasClass("open")||(o(n.dropdownToggle).dropdown("toggle"),o(n.searchFieldSelector).focus())},onHide:function(){o(n.toolbarItem).hasClass("open")&&o(n.dropdownToggle).dropdown("toggle")}})},e.prototype.registerEvents=function(){var e=o(n.searchFieldSelector),t=o("."+e.autocomplete().options.containerClass);o(n.containerSelector).on("click",".t3js-live-search-show-all",function(t){t.preventDefault(),TYPO3.ModuleMenu.App.showModule("web_list","id=0&search_levels=-1&search_field="+encodeURIComponent(e.val())),e.val("").trigger("change")}),e.length&&t.on("click.autocomplete",".dropdown-list-link",function(t){t.preventDefault();var a=o(t.currentTarget);top.jump(a.data("target"),"web_list","web",a.data("pageid")),e.val("").trigger("change")}),o(n.formSelector).on("submit",function(e){e.preventDefault()})},e}())});
\ No newline at end of file