From 1cef02d2937d290029fce5be38d0126198c83f0f Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Tue, 17 Nov 2020 23:46:48 +0000 Subject: [PATCH] MDL-70279 tool_templatelibrary: preserve component search field value. --- .../templatelibrary/amd/build/search.min.js | 2 +- .../amd/build/search.min.js.map | 2 +- admin/tool/templatelibrary/amd/src/search.js | 4 +--- .../classes/output/list_templates_page.php | 18 ++++++++++++++++++ .../templates/list_templates_page.mustache | 12 ++++++------ lib/templates/search_input_auto.mustache | 1 + 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/admin/tool/templatelibrary/amd/build/search.min.js b/admin/tool/templatelibrary/amd/build/search.min.js index 74f8c50e9b3..9645fa6341e 100644 --- a/admin/tool/templatelibrary/amd/build/search.min.js +++ b/admin/tool/templatelibrary/amd/build/search.min.js @@ -1,2 +1,2 @@ -define ("tool_templatelibrary/search",["jquery","core/ajax","core/log","core/notification","core/templates","core/config"],function(a,b,c,d,e,f){var g=function(b){e.render("tool_templatelibrary/search_results",{templates:b}).done(function(b,c){e.replaceNode(a("[data-region=\"searchresults\"]"),b,c)}).fail(d.exception)},h=function(c){var e=a("[data-field=\"component\"]").val(),f=a("[data-region=\"list-templates\"] [data-region=\"input\"]").val();if(""!==f){a("[data-region=\"list-templates\"] [data-action=\"clearsearch\"]").removeClass("d-none")}else{a("[data-region=\"list-templates\"] [data-action=\"clearsearch\"]").addClass("d-none")}document.location.hash=f;b.call([{methodname:"tool_templatelibrary_list_templates",args:{component:e,search:f,themename:c},done:g,fail:d.exception}],!0,!1)},i=null,j=function(a,b){if(null!==i){window.clearTimeout(i)}i=window.setTimeout(function(){a();i=null},b)},k=function(){j(h.bind(this,f.theme),400)};a("[data-region=\"list-templates\"]").on("change","[data-field=\"component\"]",k);a("[data-region=\"list-templates\"]").on("input","[data-region=\"input\"]",k);a("[data-action=\"clearsearch\"]").on("click",function(){a("[data-region=\"input\"]").val("");h(f.theme);a(this).addClass("d-none")});a("[data-region=\"input\"]").val(document.location.hash.replace("#",""));h(f.theme);return{}}); +define ("tool_templatelibrary/search",["jquery","core/ajax","core/log","core/notification","core/templates","core/config"],function(a,b,c,d,e,f){var g=function(b){e.render("tool_templatelibrary/search_results",{templates:b}).done(function(b,c){e.replaceNode(a("[data-region=\"searchresults\"]"),b,c)}).fail(d.exception)},h=function(c){var e=a("[data-field=\"component\"]").val(),f=a("[data-region=\"list-templates\"] [data-region=\"input\"]").val();if(""!==f){a("[data-region=\"list-templates\"] [data-action=\"clearsearch\"]").removeClass("d-none")}else{a("[data-region=\"list-templates\"] [data-action=\"clearsearch\"]").addClass("d-none")}b.call([{methodname:"tool_templatelibrary_list_templates",args:{component:e,search:f,themename:c},done:g,fail:d.exception}],!0,!1)},i=null,j=function(a,b){if(null!==i){window.clearTimeout(i)}i=window.setTimeout(function(){a();i=null},b)},k=function(){j(h.bind(this,f.theme),400)};a("[data-region=\"list-templates\"]").on("change","[data-field=\"component\"]",k);a("[data-region=\"list-templates\"]").on("input","[data-region=\"input\"]",k);a("[data-action=\"clearsearch\"]").on("click",function(){a("[data-region=\"input\"]").val("");h(f.theme);a(this).addClass("d-none")});h(f.theme);return{}}); //# sourceMappingURL=search.min.js.map diff --git a/admin/tool/templatelibrary/amd/build/search.min.js.map b/admin/tool/templatelibrary/amd/build/search.min.js.map index 0245bb86ee5..c16fd851e1d 100644 --- a/admin/tool/templatelibrary/amd/build/search.min.js.map +++ b/admin/tool/templatelibrary/amd/build/search.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/search.js"],"names":["define","$","ajax","log","notification","templates","config","reloadListTemplate","templateList","render","done","result","js","replaceNode","fail","exception","refreshSearch","themename","componentStr","val","searchStr","removeClass","addClass","document","location","hash","call","methodname","args","component","search","throttle","queueRefresh","callback","delay","window","clearTimeout","setTimeout","changeHandler","bind","theme","on","replace"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * This module adds ajax search functions to the template library page.\n *\n * @module tool_templatelibrary/search\n * @package tool_templatelibrary\n * @copyright 2015 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates', 'core/config'],\n function($, ajax, log, notification, templates, config) {\n\n /**\n * The ajax call has returned with a new list of templates.\n *\n * @method reloadListTemplate\n * @param {String[]} templateList List of template ids.\n */\n var reloadListTemplate = function(templateList) {\n templates.render('tool_templatelibrary/search_results', {templates: templateList})\n .done(function(result, js) {\n templates.replaceNode($('[data-region=\"searchresults\"]'), result, js);\n }).fail(notification.exception);\n };\n\n /**\n * Get the current values for the form inputs and refresh the list of matching templates.\n *\n * @method refreshSearch\n * @param {String} themename The naeme of the theme.\n */\n var refreshSearch = function(themename) {\n var componentStr = $('[data-field=\"component\"]').val();\n var searchStr = $('[data-region=\"list-templates\"] [data-region=\"input\"]').val();\n\n if (searchStr !== '') {\n $('[data-region=\"list-templates\"] [data-action=\"clearsearch\"]').removeClass('d-none');\n } else {\n $('[data-region=\"list-templates\"] [data-action=\"clearsearch\"]').addClass('d-none');\n }\n // Trigger the search.\n document.location.hash = searchStr;\n\n ajax.call([\n {methodname: 'tool_templatelibrary_list_templates',\n args: {component: componentStr, search: searchStr, themename: themename},\n done: reloadListTemplate,\n fail: notification.exception}\n ], true, false);\n };\n\n var throttle = null;\n\n /**\n * Call the specified function after a delay. If this function is called again before the function is executed,\n * the function will only be executed once.\n *\n * @method queueRefresh\n * @param {function} callback\n * @param {Number} delay The time in milliseconds to delay.\n */\n var queueRefresh = function(callback, delay) {\n if (throttle !== null) {\n window.clearTimeout(throttle);\n }\n\n throttle = window.setTimeout(function() {\n callback();\n throttle = null;\n }, delay);\n };\n\n var changeHandler = function() {\n queueRefresh(refreshSearch.bind(this, config.theme), 400);\n };\n // Add change handlers to refresh the list.\n $('[data-region=\"list-templates\"]').on('change', '[data-field=\"component\"]', changeHandler);\n $('[data-region=\"list-templates\"]').on('input', '[data-region=\"input\"]', changeHandler);\n $('[data-action=\"clearsearch\"]').on('click', function() {\n $('[data-region=\"input\"]').val('');\n refreshSearch(config.theme);\n $(this).addClass('d-none');\n });\n\n $('[data-region=\"input\"]').val(document.location.hash.replace('#', ''));\n refreshSearch(config.theme);\n return {};\n});\n"],"file":"search.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/search.js"],"names":["define","$","ajax","log","notification","templates","config","reloadListTemplate","templateList","render","done","result","js","replaceNode","fail","exception","refreshSearch","themename","componentStr","val","searchStr","removeClass","addClass","call","methodname","args","component","search","throttle","queueRefresh","callback","delay","window","clearTimeout","setTimeout","changeHandler","bind","theme","on"],"mappings":"AAuBAA,OAAM,+BAAC,CAAC,QAAD,CAAW,WAAX,CAAwB,UAAxB,CAAoC,mBAApC,CAAyD,gBAAzD,CAA2E,aAA3E,CAAD,CACC,SAASC,CAAT,CAAYC,CAAZ,CAAkBC,CAAlB,CAAuBC,CAAvB,CAAqCC,CAArC,CAAgDC,CAAhD,CAAwD,IAQvDC,CAAAA,CAAkB,CAAG,SAASC,CAAT,CAAuB,CAC5CH,CAAS,CAACI,MAAV,CAAiB,qCAAjB,CAAwD,CAACJ,SAAS,CAAEG,CAAZ,CAAxD,EACKE,IADL,CACU,SAASC,CAAT,CAAiBC,CAAjB,CAAqB,CACvBP,CAAS,CAACQ,WAAV,CAAsBZ,CAAC,CAAC,iCAAD,CAAvB,CAA0DU,CAA1D,CAAkEC,CAAlE,CACH,CAHL,EAGOE,IAHP,CAGYV,CAAY,CAACW,SAHzB,CAIH,CAb0D,CAqBvDC,CAAa,CAAG,SAASC,CAAT,CAAoB,IAChCC,CAAAA,CAAY,CAAGjB,CAAC,CAAC,4BAAD,CAAD,CAA8BkB,GAA9B,EADiB,CAEhCC,CAAS,CAAGnB,CAAC,CAAC,0DAAD,CAAD,CAA0DkB,GAA1D,EAFoB,CAIpC,GAAkB,EAAd,GAAAC,CAAJ,CAAsB,CAClBnB,CAAC,CAAC,gEAAD,CAAD,CAAgEoB,WAAhE,CAA4E,QAA5E,CACH,CAFD,IAEO,CACHpB,CAAC,CAAC,gEAAD,CAAD,CAAgEqB,QAAhE,CAAyE,QAAzE,CACH,CAGDpB,CAAI,CAACqB,IAAL,CAAU,CACN,CAACC,UAAU,CAAE,qCAAb,CACEC,IAAI,CAAE,CAACC,SAAS,CAAER,CAAZ,CAA0BS,MAAM,CAAEP,CAAlC,CAA6CH,SAAS,CAAEA,CAAxD,CADR,CAEEP,IAAI,CAAEH,CAFR,CAGEO,IAAI,CAAEV,CAAY,CAACW,SAHrB,CADM,CAAV,OAMH,CAtC0D,CAwCvDa,CAAQ,CAAG,IAxC4C,CAkDvDC,CAAY,CAAG,SAASC,CAAT,CAAmBC,CAAnB,CAA0B,CACzC,GAAiB,IAAb,GAAAH,CAAJ,CAAuB,CACnBI,MAAM,CAACC,YAAP,CAAoBL,CAApB,CACH,CAEDA,CAAQ,CAAGI,MAAM,CAACE,UAAP,CAAkB,UAAW,CACpCJ,CAAQ,GACRF,CAAQ,CAAG,IACd,CAHU,CAGRG,CAHQ,CAId,CA3D0D,CA6DvDI,CAAa,CAAG,UAAW,CAC3BN,CAAY,CAACb,CAAa,CAACoB,IAAd,CAAmB,IAAnB,CAAyB9B,CAAM,CAAC+B,KAAhC,CAAD,CAAyC,GAAzC,CACf,CA/D0D,CAiE3DpC,CAAC,CAAC,kCAAD,CAAD,CAAoCqC,EAApC,CAAuC,QAAvC,CAAiD,4BAAjD,CAA6EH,CAA7E,EACAlC,CAAC,CAAC,kCAAD,CAAD,CAAoCqC,EAApC,CAAuC,OAAvC,CAAgD,yBAAhD,CAAyEH,CAAzE,EACAlC,CAAC,CAAC,+BAAD,CAAD,CAAiCqC,EAAjC,CAAoC,OAApC,CAA6C,UAAW,CACpDrC,CAAC,CAAC,yBAAD,CAAD,CAA2BkB,GAA3B,CAA+B,EAA/B,EACAH,CAAa,CAACV,CAAM,CAAC+B,KAAR,CAAb,CACApC,CAAC,CAAC,IAAD,CAAD,CAAQqB,QAAR,CAAiB,QAAjB,CACH,CAJD,EAMAN,CAAa,CAACV,CAAM,CAAC+B,KAAR,CAAb,CACA,MAAO,EACV,CA5EK,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * This module adds ajax search functions to the template library page.\n *\n * @module tool_templatelibrary/search\n * @package tool_templatelibrary\n * @copyright 2015 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates', 'core/config'],\n function($, ajax, log, notification, templates, config) {\n\n /**\n * The ajax call has returned with a new list of templates.\n *\n * @method reloadListTemplate\n * @param {String[]} templateList List of template ids.\n */\n var reloadListTemplate = function(templateList) {\n templates.render('tool_templatelibrary/search_results', {templates: templateList})\n .done(function(result, js) {\n templates.replaceNode($('[data-region=\"searchresults\"]'), result, js);\n }).fail(notification.exception);\n };\n\n /**\n * Get the current values for the form inputs and refresh the list of matching templates.\n *\n * @method refreshSearch\n * @param {String} themename The naeme of the theme.\n */\n var refreshSearch = function(themename) {\n var componentStr = $('[data-field=\"component\"]').val();\n var searchStr = $('[data-region=\"list-templates\"] [data-region=\"input\"]').val();\n\n if (searchStr !== '') {\n $('[data-region=\"list-templates\"] [data-action=\"clearsearch\"]').removeClass('d-none');\n } else {\n $('[data-region=\"list-templates\"] [data-action=\"clearsearch\"]').addClass('d-none');\n }\n\n // Trigger the search.\n ajax.call([\n {methodname: 'tool_templatelibrary_list_templates',\n args: {component: componentStr, search: searchStr, themename: themename},\n done: reloadListTemplate,\n fail: notification.exception}\n ], true, false);\n };\n\n var throttle = null;\n\n /**\n * Call the specified function after a delay. If this function is called again before the function is executed,\n * the function will only be executed once.\n *\n * @method queueRefresh\n * @param {function} callback\n * @param {Number} delay The time in milliseconds to delay.\n */\n var queueRefresh = function(callback, delay) {\n if (throttle !== null) {\n window.clearTimeout(throttle);\n }\n\n throttle = window.setTimeout(function() {\n callback();\n throttle = null;\n }, delay);\n };\n\n var changeHandler = function() {\n queueRefresh(refreshSearch.bind(this, config.theme), 400);\n };\n // Add change handlers to refresh the list.\n $('[data-region=\"list-templates\"]').on('change', '[data-field=\"component\"]', changeHandler);\n $('[data-region=\"list-templates\"]').on('input', '[data-region=\"input\"]', changeHandler);\n $('[data-action=\"clearsearch\"]').on('click', function() {\n $('[data-region=\"input\"]').val('');\n refreshSearch(config.theme);\n $(this).addClass('d-none');\n });\n\n refreshSearch(config.theme);\n return {};\n});\n"],"file":"search.min.js"} \ No newline at end of file diff --git a/admin/tool/templatelibrary/amd/src/search.js b/admin/tool/templatelibrary/amd/src/search.js index 9caf34416b2..1865457d91c 100644 --- a/admin/tool/templatelibrary/amd/src/search.js +++ b/admin/tool/templatelibrary/amd/src/search.js @@ -52,9 +52,8 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates' } else { $('[data-region="list-templates"] [data-action="clearsearch"]').addClass('d-none'); } - // Trigger the search. - document.location.hash = searchStr; + // Trigger the search. ajax.call([ {methodname: 'tool_templatelibrary_list_templates', args: {component: componentStr, search: searchStr, themename: themename}, @@ -96,7 +95,6 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates' $(this).addClass('d-none'); }); - $('[data-region="input"]').val(document.location.hash.replace('#', '')); refreshSearch(config.theme); return {}; }); diff --git a/admin/tool/templatelibrary/classes/output/list_templates_page.php b/admin/tool/templatelibrary/classes/output/list_templates_page.php index ebd45008bb6..71035d87288 100644 --- a/admin/tool/templatelibrary/classes/output/list_templates_page.php +++ b/admin/tool/templatelibrary/classes/output/list_templates_page.php @@ -40,6 +40,22 @@ use tool_templatelibrary\api; */ class list_templates_page implements renderable, templatable { + /** @var string $component The currently selected component */ + protected $component; + /** @var string $search The current search */ + protected $search; + + /** + * Template page constructor + * + * @param string $component + * @param string $search + */ + public function __construct(string $component = '', string $search = '') { + $this->component = $component; + $this->search = $search; + } + /** * Export this data so it can be used as the context for a mustache template. * @@ -75,6 +91,7 @@ class list_templates_page implements renderable, templatable { $components[$type]->plugins[$component] = (object) [ 'name' => $pluginname, 'component' => $component, + 'selected' => ($component === $this->component), ]; } @@ -87,6 +104,7 @@ class list_templates_page implements renderable, templatable { return (object) [ 'allcomponents' => array_values($components), + 'search' => $this->search, ]; } } diff --git a/admin/tool/templatelibrary/templates/list_templates_page.mustache b/admin/tool/templatelibrary/templates/list_templates_page.mustache index 71d80425a8c..0accf0ac59c 100644 --- a/admin/tool/templatelibrary/templates/list_templates_page.mustache +++ b/admin/tool/templatelibrary/templates/list_templates_page.mustache @@ -72,12 +72,12 @@ {{/label}} {{$element}} - {{#allcomponents}} {{#plugins}} - + {{/plugins}} {{/allcomponents}} @@ -88,10 +88,10 @@ {{< core_form/element-template }} {{$element}} {{< core/search_input_auto }} - {{$label}}{{{ searchstring }}}{{/label}} - {{$placeholder}}{{#str}} - search, core - {{/str}}{{/placeholder}} + {{$label}} + {{#str}} search, tool_templatelibrary {{/str}} + {{/label}} + {{$value}}{{ search }}{{/value}} {{/ core/search_input_auto }} {{/element}} {{/ core_form/element-template }} diff --git a/lib/templates/search_input_auto.mustache b/lib/templates/search_input_auto.mustache index 7e89b09b105..d2cdc48776c 100644 --- a/lib/templates/search_input_auto.mustache +++ b/lib/templates/search_input_auto.mustache @@ -49,6 +49,7 @@ class="form-control withclear" placeholder="{{$placeholder}}{{#str}} search, core {{/str}}{{/placeholder}}" name="search" + value="{{$value}}{{/value}}" autocomplete="off" >