summaryrefslogtreecommitdiff
path: root/public
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-06-30 03:36:51 +0200
committererdgeist <erdgeist@erdgeist.org>2026-06-30 03:44:44 +0200
commit97f51a73d4a2e7fb42ccf1107abf07e985cfa13a (patch)
treecb4c992d384020d878fe06dac1d4f2fc1905f8e2 /public
parentefc802b22eae15de5fc18465182628e379caf099 (diff)
Improve admin search overlay layout and behaviour
- Widen overlay (300px -> min(520px, 90vw)), centre instead of hardcoded left:400px, so it scales from mobile to desktop - Split title and unique_name into separate JSON fields and DOM elements; two-line result layout (bold title, small grey monospace path) instead of "Title (path)" wrapping awkwardly - Add small margin between title and path line - Fix event handler stacking: keyup/escape/outside-click handlers were being rebound on every display_toggle call. Moved all bindings to initialize(), display_toggle() now only shows/hides - Switch search input from keyup to input event, catching paste and cut via mouse which keyup misses - Add Escape key and outside-click to dismiss the overlay - Stop clearing search box and results on close; reopening now preserves prior search, matching standard search UI behaviour - Link search results to node_path instead of edit_node_path, since opening edit auto-locks the node - Add "press Enter to see all results" hint in dropdown - Disable browser autocomplete on search input
Diffstat (limited to 'public')
-rw-r--r--public/javascripts/admin_search.js60
-rw-r--r--public/stylesheets/admin.css44
2 files changed, 74 insertions, 30 deletions
diff --git a/public/javascripts/admin_search.js b/public/javascripts/admin_search.js
index 37c46cc..9bf878b 100644
--- a/public/javascripts/admin_search.js
+++ b/public/javascripts/admin_search.js
@@ -5,46 +5,68 @@ admin_search = {
5 admin_search.display_toggle(); 5 admin_search.display_toggle();
6 return false; 6 return false;
7 }); 7 });
8 },
9 8
10 display_toggle : function() { 9 $(document).bind("keydown", function(e) {
11 if ($('#search_widget').css("display") != "none") { 10 if (e.key === "Escape" && $('#search_widget').is(':visible')) {
12 $('#search_widget').fadeOut(); 11 $('#search_widget').fadeOut();
13 } 12 }
14 else { 13 });
15 $('#search_widget').fadeIn(); 14
16 $('#search_term').attr("value", ""); 15 $(document).bind("click", function(e) {
17 $('#search_term').focus(); 16 if ($('#search_widget').is(':visible') &&
18 } 17 !$(e.target).closest('#search_widget').length &&
18 !$(e.target).closest('a[onclick*="display_toggle"]').length) {
19 $('#search_widget').fadeOut();
20 }
21 });
19 22
20 $("#search_term").bind("keyup", function() { 23 $("#search_term").bind("input", function() {
24 if (!$('#search_widget').is(':visible')) return;
21 if ($(this).val()) { 25 if ($(this).val()) {
22 $.ajax({ 26 $.ajax({
23 type: "GET", 27 type: "GET",
24 url: ADMIN_SEARCH_URL, 28 url: ADMIN_SEARCH_URL,
25 data: "search_term=" + $(this).val(), 29 data: "search_term=" + $(this).val(),
26 dataType: "json", 30 dataType: "json",
27 success : function(results) { 31 success: function(results) {
28 admin_search.show_results(results); 32 admin_search.show_results(results);
29 }, 33 },
30 error: function(xhr, status, error) { 34 error: function(xhr, status, error) {
31 console.log("Ajax error:", status, error, xhr.status, xhr.responseText); 35 console.log("Ajax error:", status, error, xhr.status, xhr.responseText);
32 } 36 }
33 }); 37 });
34 } 38 } else {
35 else {
36 $('#search_results').slideUp(); 39 $('#search_results').slideUp();
37 $('#search_results').empty(); 40 $('#search_results').empty();
38 } 41 }
39 }); 42 });
40 }, 43 },
41 44
45 display_toggle : function() {
46 if ($('#search_widget').is(':visible')) {
47 $('#search_widget').fadeOut();
48 } else {
49 $('#search_widget').fadeIn();
50 $('#search_term').focus();
51 }
52 },
53
42 show_results : function(results) { 54 show_results : function(results) {
43 $('#search_results').empty(); 55 $('#search_results').empty();
44 for (result in results) { 56 if (results.length) {
45 $('#search_results').append("<p><a href='"+ results[result].edit_path + "'>" + results[result].title + "</a></p>"); 57 $('#search_results').append(
46 } 58 "<p class='search_more'>Press Enter to see all results ⏎</p>"
47 $('#search_results').slideDown(); 59 );
60 }
61 for (result in results) {
62 $('#search_results').append(
63 "<p><a href='" + results[result].node_path + "'>" +
64 results[result].title +
65 "<span class='result_path'>" + results[result].unique_name + "</span>" +
66 "</a></p>"
67 );
68 }
69 $('#search_results').slideDown();
48 } 70 }
49}; 71};
50 72
diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css
index 4b08356..c9ef173 100644
--- a/public/stylesheets/admin.css
+++ b/public/stylesheets/admin.css
@@ -495,28 +495,50 @@ table tr.header {
495#search_widget { 495#search_widget {
496 position: absolute; 496 position: absolute;
497 top: 20px; 497 top: 20px;
498 left: 400px; 498 left: 50%;
499 width: 300px; 499 transform: translateX(-50%);
500 width: min(520px, 90vw);
500 border: 1px solid #000000; 501 border: 1px solid #000000;
501 -webkit-box-shadow: 3px 3px 5px #b1b1b1; 502 -webkit-box-shadow: 3px 3px 5px #b1b1b1;
502 -moz-box-shadow: 10px 10px 5px #888, 10px 10px 30px rgba(0,0,0,0.4); 503 box-shadow: 3px 3px 5px #b1b1b1;
503 background-color: #ffffff; 504 background-color: #ffffff;
504 padding: 3px; 505 padding: 3px;
505 text-align: center; 506 z-index: 100;
506} 507}
507 508
508#search_widget span { 509#search_widget input {
510 width: calc(100% - 70px);
509 font-size: 18px; 511 font-size: 18px;
510} 512}
511 513
512#search_widget input { 514#search_results p {
513 width: 210px; 515 margin: 0;
514 font-size: 18px; 516 padding: 4px 4px 0 4px;
517 border-bottom: 1px solid #e8e8e8;
515} 518}
516 519
517#search_widget #search_results { 520#search_results p a {
518 padding: 4px; 521 display: block;
519 text-align: left; 522 font-weight: bold;
523 font-size: 0.95rem;
524}
525
526#search_results p span.result_path {
527 display: block;
528 margin-top: 2px;
529 font-size: 0.75rem;
530 font-family: monospace;
531 color: #969696;
532 padding-bottom: 4px;
533}
534
535#search_results p.search_more {
536 margin: 0;
537 padding: 6px 4px;
538 font-size: 0.8rem;
539 color: #969696;
540 font-style: italic;
541 border-bottom: none;
520} 542}
521 543
522table#content th.description { 544table#content th.description {