diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-06-30 03:36:51 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-06-30 03:44:44 +0200 |
| commit | 97f51a73d4a2e7fb42ccf1107abf07e985cfa13a (patch) | |
| tree | cb4c992d384020d878fe06dac1d4f2fc1905f8e2 /public | |
| parent | efc802b22eae15de5fc18465182628e379caf099 (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.js | 60 | ||||
| -rw-r--r-- | public/stylesheets/admin.css | 44 |
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 | ||
| 522 | table#content th.description { | 544 | table#content th.description { |
