MDL-67917 core: Add custom template support to autocomplete
authorAndrew Nicols <andrew@nicols.co.uk>
Thu, 26 Mar 2020 00:54:46 +0000 (08:54 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Wed, 27 May 2020 02:49:43 +0000 (10:49 +0800)
Part of MDL-67743

lib/amd/build/form-autocomplete.min.js
lib/amd/build/form-autocomplete.min.js.map
lib/amd/src/form-autocomplete.js
lib/templates/form_autocomplete_layout.mustache [new file with mode: 0644]

index 154a606..8ef27f0 100644 (file)
Binary files a/lib/amd/build/form-autocomplete.min.js and b/lib/amd/build/form-autocomplete.min.js differ
index 944df5c..77c999b 100644 (file)
Binary files a/lib/amd/build/form-autocomplete.min.js.map and b/lib/amd/build/form-autocomplete.min.js.map differ
index 035f94e..b91c5fb 100644 (file)
@@ -114,7 +114,7 @@ function($, log, str, templates, notification, LoadingIcon) {
         });
         var context = $.extend({items: items}, options, state);
         // Render the template.
-        return templates.render('core/form_autocomplete_selection_items', context)
+        return templates.render(options.templates.items, context)
         .then(function(html, js) {
             // Add it to the page.
             templates.replaceNodeContents(newSelection, html, js);
@@ -970,10 +970,11 @@ function($, log, str, templates, notification, LoadingIcon) {
          * @param {Boolean} showSuggestions - If suggestions should be shown
          * @param {String} noSelectionString - Text to display when there is no selection
          * @param {Boolean} closeSuggestionsOnSelect - Whether to close the suggestions immediately after making a selection.
+         * @param {Object} templateOverrides A set of templates to use instead of the standard templates
          * @return {Promise}
          */
         enhance: function(selector, tags, ajax, placeholder, caseSensitive, showSuggestions, noSelectionString,
-                          closeSuggestionsOnSelect) {
+                          closeSuggestionsOnSelect, templateOverrides) {
             // Set some default values.
             var options = {
                 selector: selector,
@@ -982,7 +983,14 @@ function($, log, str, templates, notification, LoadingIcon) {
                 placeholder: placeholder,
                 caseSensitive: false,
                 showSuggestions: true,
-                noSelectionString: noSelectionString
+                noSelectionString: noSelectionString,
+                templates: $.extend({
+                        input: 'core/form_autocomplete_input',
+                        items: 'core/form_autocomplete_selection_items',
+                        layout: 'core/form_autocomplete_layout',
+                        selection: 'core/form_autocomplete_selection',
+                        suggestions: 'core/form_autocomplete_suggestions',
+                    }, templateOverrides),
             };
             var pendingKey = 'autocomplete-setup-' + selector;
             M.util.js_pending(pendingKey);
@@ -1058,27 +1066,35 @@ function($, log, str, templates, notification, LoadingIcon) {
             // Collect rendered inline JS to be executed once the HTML is shown.
             var collectedjs = '';
 
-            var renderInput = templates.render('core/form_autocomplete_input', context).then(function(html, js) {
+            var renderLayout = templates.render(options.templates.layout, {})
+            .then(function(html) {
+                return $(html);
+            });
+
+            var renderInput = templates.render(options.templates.input, context).then(function(html, js) {
                 collectedjs += js;
-                return html;
+                return $(html);
             });
 
-            var renderDatalist = templates.render('core/form_autocomplete_suggestions', context).then(function(html, js) {
+            var renderDatalist = templates.render(options.templates.suggestions, context).then(function(html, js) {
                 collectedjs += js;
-                return html;
+                return $(html);
             });
 
-            var renderSelection = templates.render('core/form_autocomplete_selection', context).then(function(html, js) {
+            var renderSelection = templates.render(options.templates.selection, context).then(function(html, js) {
                 collectedjs += js;
-                return html;
+                return $(html);
             });
 
-            return $.when(renderInput, renderDatalist, renderSelection)
-            .then(function(input, suggestions, selection) {
+            return $.when(renderLayout, renderInput, renderDatalist, renderSelection)
+            .then(function(layout, input, suggestions, selection) {
                 originalSelect.hide();
-                originalSelect.after(suggestions);
-                originalSelect.after(input);
-                originalSelect.after(selection);
+                var container = originalSelect.parent();
+
+                container.append(layout);
+                container.find('[data-region="form_autocomplete-input"]').replaceWith(input);
+                container.find('[data-region="form_autocomplete-suggestions"]').replaceWith(suggestions);
+                container.find('[data-region="form_autocomplete-selection"]').replaceWith(selection);
 
                 templates.runTemplateJS(collectedjs);
 
diff --git a/lib/templates/form_autocomplete_layout.mustache b/lib/templates/form_autocomplete_layout.mustache
new file mode 100644 (file)
index 0000000..f224fa8
--- /dev/null
@@ -0,0 +1,38 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template core/form_autocomplete_layout
+
+    Moodle template for the layout of autocomplete elements.
+
+    Classes required for JS:
+    * none
+
+    Data attributes required for JS:
+    * data-region="form_autocomplete-input"
+    * data-region="form_autocomplete-suggestions"
+    * data-region="form_autocomplete-selection"
+
+    Context variables required for this template:
+    * none
+
+    Example context (json):
+    {}
+}}
+<div data-region="form_autocomplete-selection"></div>
+<div data-region="form_autocomplete-input"></div>
+<div data-region="form_autocomplete-suggestions"></div>