From 5f56fa867f073d8d1aecbfbba4a340ea414cfb0d Mon Sep 17 00:00:00 2001 From: erdgeist Date: Mon, 13 Jul 2026 03:48:28 +0200 Subject: Add loadOnFocus to initSearchPicker; asset search shows recent by default initSearchPicker's input handler has always short-circuited on an empty term -- correct for every existing picker, none of which want results appearing before anything's typed. The asset picker does want exactly that (show the last few uploaded images without requiring a search first), so this adds an opt-in loadOnFocus option instead of changing the shared default: it fires once when the input gains focus with no term yet, reusing the same request/render path a real search uses rather than a separate code path. The AJAX call itself was pulled out into a named runSearch function so both triggers could share it without duplicating the success/render logic. RelatedAssetsController#search now treats a blank term as "show the most recently created, unattached images" (limit 5) rather than returning nothing, matching the new client behavior. A real search term still returns up to 10 name-matched results, unchanged. --- public/javascripts/admin_search.js | 133 ++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 61 deletions(-) (limited to 'public') diff --git a/public/javascripts/admin_search.js b/public/javascripts/admin_search.js index 0c768a3..7604bb7 100644 --- a/public/javascripts/admin_search.js +++ b/public/javascripts/admin_search.js @@ -42,18 +42,76 @@ function initSearchPicker(options) { var inputSelector = options.inputSelector; var resultsSelector = options.resultsSelector; var url = options.url || ADMIN_MENU_SEARCH_URL; - var onSelect = options.onSelect; // omit for a real-navigation search like admin_search - var isActive = options.isActive; // optional guard, checked before every search - var resultsHeaderHtml = options.resultsHeaderHtml; // optional, prepended only when results exist - var renderResults = options.renderResults; // optional, replaces the default per-node rendering entirely + var onSelect = options.onSelect; + var isActive = options.isActive; + var resultsHeaderHtml = options.resultsHeaderHtml; + var renderResults = options.renderResults; + var loadOnFocus = options.loadOnFocus; // optional, fires an initial search on focus with no term typed yet var requestId = 0; var timeout; + var results = $(resultsSelector); + + function runSearch(term) { + var thisRequest = ++requestId; + $.ajax({ + type: "GET", + url: url, + data: "search_term=" + term, + dataType: "json", + success: function(data) { + if (thisRequest !== requestId) return; + results.empty(); + + var found; + if (renderResults) { + found = renderResults(data, results, resultsHeaderHtml); + } else { + if (data.length && resultsHeaderHtml) { + results.append(resultsHeaderHtml); + } + found = false; + for (var i = 0; i < data.length; i++) { + (function(node) { + var link; + if (onSelect) { + link = $( + "

" + node.title + + "" + node.unique_name + "

" + ); + link.find("a").bind("click", function() { + onSelect(node); + results.slideUp(); + results.empty(); + return false; + }); + } else { + link = $( + "

" + node.title + + "" + node.unique_name + "

" + ); + } + results.append(link); + found = true; + })(data[i]); + } + } + + if (found) { + results.slideDown(); + } else { + results.slideUp(); + } + }, + error: function(xhr, status, error) { + console.log("Ajax error:", status, error, xhr.status, xhr.responseText); + } + }); + } $(inputSelector).bind("input", function() { if (isActive && !isActive()) return; var term = $(this).val(); - var results = $(resultsSelector); clearTimeout(timeout); if (!term) { @@ -62,63 +120,16 @@ function initSearchPicker(options) { return; } - timeout = setTimeout(function() { - var thisRequest = ++requestId; - $.ajax({ - type: "GET", - url: url, - data: "search_term=" + term, - dataType: "json", - success: function(data) { - if (thisRequest !== requestId) return; - results.empty(); - - var found; - if (renderResults) { - found = renderResults(data, results, resultsHeaderHtml); - } else { - if (data.length && resultsHeaderHtml) { - results.append(resultsHeaderHtml); - } - found = false; - for (var i = 0; i < data.length; i++) { - (function(node) { - var link; - if (onSelect) { - link = $( - "

" + node.title + - "" + node.unique_name + "

" - ); - link.find("a").bind("click", function() { - onSelect(node); - results.slideUp(); - results.empty(); - return false; - }); - } else { - link = $( - "

" + node.title + - "" + node.unique_name + "

" - ); - } - results.append(link); - found = true; - })(data[i]); - } - } - - if (found) { - results.slideDown(); - } else { - results.slideUp(); - } - }, - error: function(xhr, status, error) { - console.log("Ajax error:", status, error, xhr.status, xhr.responseText); - } - }); - }, 250); + timeout = setTimeout(function() { runSearch(term); }, 250); }); + + if (loadOnFocus) { + $(inputSelector).bind("focus", function() { + if (isActive && !isActive()) return; + if ($(this).val()) return; // the input handler above already covers a real term + runSearch(""); + }); + } } dashboard_search = { -- cgit v1.3