diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-07-12 13:58:36 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-07-12 13:58:36 +0200 |
| commit | 19e0ee821d5b2b6d3397a81411f4f3a4cbd2fa83 (patch) | |
| tree | 952551d861bb8348d436367e8f048c5f85853cf5 | |
| parent | 45bf65d04d046c0ea4a1150096b2a9b846d6c0b8 (diff) | |
Unify the four field-level pickers, fix search visibility
menu_items/parent_search/move_to_search/event_search each duplicated
their own debounce-free AJAX call and result rendering. Replaced with
one shared initSearchPicker, taking each picker's distinctive
behavior (parent_search's live path preview, event_search's title
hint) as a callback rather than a whole reimplementation. Adds a real
debounce with an out-of-order-response guard -- none of the four had
either before. admin_search (the Alt+F top-bar search) now shares the
same function via its own url/isActive/header options, gaining the
same guard and fixing an inconsistency of its own (it previously
always slid its panel open, even on zero results).
Each picker's results container gets its own id instead of sharing
was ever supposed to be on screen at once, an assumption with no
actual enforcement behind it. Styling moved from an id-pair
(#menu_search_results, #search_results) to a shared .search_results
class so a future picker never needs this file touched again.
menu_search and the admin top-bar search now call Node.editor_search
instead of the public, head-only Node.search -- both are admin-only,
authenticated views, and had no reason to inherit the public search's
"can't find a draft" limitation. The always-ignored :per_page => 1000
on the latter is gone too; Node.search's second argument was never
read by the method at all.
Also removed a stale #metadata a { text-transform: lowercase } rule,
found while verifying the above -- written for the pre-subnav-removal
expand-toggle, which no longer exists; it had been silently
lowercasing nodes#edit's own, unrelated #metadata div (including
move_to_search's results) by id coincidence ever since. #main_navigation
and #overview_toggle intentionally left capitalized rather than
special-cased -- both belong to the nav bar already slated to shrink
to three icons, not worth polishing on the way out.
| -rw-r--r-- | app/controllers/admin_controller.rb | 4 | ||||
| -rw-r--r-- | app/views/events/edit.html.erb | 4 | ||||
| -rw-r--r-- | app/views/events/new.html.erb | 2 | ||||
| -rw-r--r-- | app/views/layouts/admin.html.erb | 4 | ||||
| -rw-r--r-- | app/views/menu_items/edit.html.erb | 2 | ||||
| -rw-r--r-- | app/views/menu_items/new.html.erb | 4 | ||||
| -rw-r--r-- | app/views/nodes/edit.html.erb | 14 | ||||
| -rw-r--r-- | app/views/nodes/new.html.erb | 2 | ||||
| -rw-r--r-- | public/javascripts/admin_search.js | 351 | ||||
| -rw-r--r-- | public/stylesheets/admin.css | 13 |
10 files changed, 135 insertions, 265 deletions
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 435df57b..3c45c496 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb | |||
| @@ -31,7 +31,7 @@ class AdminController < ApplicationController | |||
| 31 | end | 31 | end |
| 32 | 32 | ||
| 33 | def search | 33 | def search |
| 34 | @results = Node.search params[:search_term], :per_page => 1000 | 34 | @results = Node.editor_search(params[:search_term]) |
| 35 | 35 | ||
| 36 | respond_to do |format| | 36 | respond_to do |format| |
| 37 | format.html do | 37 | format.html do |
| @@ -53,7 +53,7 @@ class AdminController < ApplicationController | |||
| 53 | if params[:search_term] == "Root" | 53 | if params[:search_term] == "Root" |
| 54 | @results = [Node.root] | 54 | @results = [Node.root] |
| 55 | else | 55 | else |
| 56 | @results = Node.search params[:search_term] | 56 | @results = Node.editor_search(params[:search_term]) |
| 57 | end | 57 | end |
| 58 | 58 | ||
| 59 | respond_to do |format| | 59 | respond_to do |format| |
diff --git a/app/views/events/edit.html.erb b/app/views/events/edit.html.erb index 6cb04bd7..45b084f0 100644 --- a/app/views/events/edit.html.erb +++ b/app/views/events/edit.html.erb | |||
| @@ -19,12 +19,12 @@ | |||
| 19 | <details> | 19 | <details> |
| 20 | <summary>Change node</summary> | 20 | <summary>Change node</summary> |
| 21 | <%= text_field_tag :event_node_search_term %> | 21 | <%= text_field_tag :event_node_search_term %> |
| 22 | <div id="search_results"></div> | 22 | <div id="event_search_results" class="search_results"></div> |
| 23 | <span class="field_hint">This will re-link the event to a different node — rarely needed.</span> | 23 | <span class="field_hint">This will re-link the event to a different node — rarely needed.</span> |
| 24 | </details> | 24 | </details> |
| 25 | <% else %> | 25 | <% else %> |
| 26 | <%= text_field_tag :event_node_search_term %> | 26 | <%= text_field_tag :event_node_search_term %> |
| 27 | <div id="search_results"></div> | 27 | <div id="event_search_results" class="search_results"></div> |
| 28 | <span class="field_hint">Optional — search and pick a node to associate this event with a page.</span> | 28 | <span class="field_hint">Optional — search and pick a node to associate this event with a page.</span> |
| 29 | <% end %> | 29 | <% end %> |
| 30 | <%= f.hidden_field :node_id %> | 30 | <%= f.hidden_field :node_id %> |
diff --git a/app/views/events/new.html.erb b/app/views/events/new.html.erb index b20fe488..7a1ee7a3 100644 --- a/app/views/events/new.html.erb +++ b/app/views/events/new.html.erb | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | <div class="node_description">Node</div> | 10 | <div class="node_description">Node</div> |
| 11 | <div class="node_content"> | 11 | <div class="node_content"> |
| 12 | <%= text_field_tag :event_node_search_term %> | 12 | <%= text_field_tag :event_node_search_term %> |
| 13 | <div id="search_results"></div> | 13 | <div id="event_search_results" class="search_results"></div> |
| 14 | <%= f.hidden_field :node_id %> | 14 | <%= f.hidden_field :node_id %> |
| 15 | <span class="field_hint">Optional — search and pick a node to associate this event with a page.</span> | 15 | <span class="field_hint">Optional — search and pick a node to associate this event with a page.</span> |
| 16 | </div> | 16 | </div> |
diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb index e714c281..079346b2 100644 --- a/app/views/layouts/admin.html.erb +++ b/app/views/layouts/admin.html.erb | |||
| @@ -56,9 +56,7 @@ | |||
| 56 | <span>Search: </span><%= text_field_tag :search_term, nil, autocomplete: "off" %> | 56 | <span>Search: </span><%= text_field_tag :search_term, nil, autocomplete: "off" %> |
| 57 | <% end %> | 57 | <% end %> |
| 58 | </div> | 58 | </div> |
| 59 | <div id="menu_search_results" style="display: none"> | 59 | <div id="menu_search_results" class="search_results" style="display: none"></div> |
| 60 | |||
| 61 | </div> | ||
| 62 | </div> | 60 | </div> |
| 63 | </body> | 61 | </body> |
| 64 | </html> | 62 | </html> |
diff --git a/app/views/menu_items/edit.html.erb b/app/views/menu_items/edit.html.erb index dc5e8f97..44e5a791 100644 --- a/app/views/menu_items/edit.html.erb +++ b/app/views/menu_items/edit.html.erb | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | <div class="node_description">Search</div> | 6 | <div class="node_description">Search</div> |
| 7 | <div class="node_content"> | 7 | <div class="node_content"> |
| 8 | <%= text_field_tag :menu_search_term %> | 8 | <%= text_field_tag :menu_search_term %> |
| 9 | <div id="search_results"></div> | 9 | <div id="menu_item_search_results" class="search_results"></div> |
| 10 | </div> | 10 | </div> |
| 11 | 11 | ||
| 12 | <div class="node_description">Node Id</div> | 12 | <div class="node_description">Node Id</div> |
diff --git a/app/views/menu_items/new.html.erb b/app/views/menu_items/new.html.erb index 68081d0f..223cb8ec 100644 --- a/app/views/menu_items/new.html.erb +++ b/app/views/menu_items/new.html.erb | |||
| @@ -7,9 +7,7 @@ | |||
| 7 | <td class="description">Search</td> | 7 | <td class="description">Search</td> |
| 8 | <td> | 8 | <td> |
| 9 | <%= text_field_tag :menu_search_term %> | 9 | <%= text_field_tag :menu_search_term %> |
| 10 | <div id="search_results"> | 10 | <div id="menu_item_search_results" class="search_results"></div> |
| 11 | |||
| 12 | </div> | ||
| 13 | </td> | 11 | </td> |
| 14 | </tr> | 12 | </tr> |
| 15 | <tr> | 13 | <tr> |
diff --git a/app/views/nodes/edit.html.erb b/app/views/nodes/edit.html.erb index 1c194101..13b78fca 100644 --- a/app/views/nodes/edit.html.erb +++ b/app/views/nodes/edit.html.erb | |||
| @@ -45,14 +45,12 @@ | |||
| 45 | <div class="node_description">parent</div> | 45 | <div class="node_description">parent</div> |
| 46 | <div class="node_content"> | 46 | <div class="node_content"> |
| 47 | <%= text_field_tag :move_to_search_term, @node.parent.title rescue "" %> | 47 | <%= text_field_tag :move_to_search_term, @node.parent.title rescue "" %> |
| 48 | <div id="search_results"> | 48 | <div id="move_to_search_results" class="search_results"></div> |
| 49 | 49 | <%= f.hidden_field( | |
| 50 | </div> | 50 | :staged_parent_id, |
| 51 | <%= f.hidden_field( | 51 | :value => @node.staged_parent_id || @node.parent_id |
| 52 | :staged_parent_id, | 52 | ) |
| 53 | :value => @node.staged_parent_id || @node.parent_id | 53 | %> |
| 54 | ) | ||
| 55 | %> | ||
| 56 | </div> | 54 | </div> |
| 57 | 55 | ||
| 58 | <%= fields_for @page do |d| %> | 56 | <%= fields_for @page do |d| %> |
diff --git a/app/views/nodes/new.html.erb b/app/views/nodes/new.html.erb index afc632f9..bb7e078a 100644 --- a/app/views/nodes/new.html.erb +++ b/app/views/nodes/new.html.erb | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | <div class="node_content"> | 34 | <div class="node_content"> |
| 35 | <%= text_field_tag :parent_search_term, @parent_name %> | 35 | <%= text_field_tag :parent_search_term, @parent_name %> |
| 36 | <%= hidden_field_tag :parent_id, @parent_id %> | 36 | <%= hidden_field_tag :parent_id, @parent_id %> |
| 37 | <div id="search_results"></div> | 37 | <div id="parent_search_results" class="search_results"></div> |
| 38 | </div> | 38 | </div> |
| 39 | </div> | 39 | </div> |
| 40 | 40 | ||
diff --git a/public/javascripts/admin_search.js b/public/javascripts/admin_search.js index 0e708458..f553334d 100644 --- a/public/javascripts/admin_search.js +++ b/public/javascripts/admin_search.js | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | admin_search = { | 1 | admin_search = { |
| 2 | |||
| 3 | initialize : function() { | 2 | initialize : function() { |
| 4 | $(document).bind("keydown", 'Alt+f', function(){ | 3 | $(document).bind("keydown", 'Alt+f', function(){ |
| 5 | admin_search.display_toggle(); | 4 | admin_search.display_toggle(); |
| @@ -20,25 +19,12 @@ admin_search = { | |||
| 20 | } | 19 | } |
| 21 | }); | 20 | }); |
| 22 | 21 | ||
| 23 | $("#search_term").bind("input", function() { | 22 | initSearchPicker({ |
| 24 | if (!$('#search_widget').is(':visible')) return; | 23 | inputSelector: "#search_term", |
| 25 | if ($(this).val()) { | 24 | resultsSelector: "#menu_search_results", |
| 26 | $.ajax({ | 25 | url: ADMIN_SEARCH_URL, |
| 27 | type: "GET", | 26 | isActive: function() { return $('#search_widget').is(':visible'); }, |
| 28 | url: ADMIN_SEARCH_URL, | 27 | resultsHeaderHtml: "<p class='search_more'>Press Enter to see all results ⏎</p>" |
| 29 | data: "search_term=" + $(this).val(), | ||
| 30 | dataType: "json", | ||
| 31 | success: function(results) { | ||
| 32 | admin_search.show_results(results); | ||
| 33 | }, | ||
| 34 | error: function(xhr, status, error) { | ||
| 35 | console.log("Ajax error:", status, error, xhr.status, xhr.responseText); | ||
| 36 | } | ||
| 37 | }); | ||
| 38 | } else { | ||
| 39 | $('#menu_search_results').slideUp(); | ||
| 40 | $('#menu_search_results').empty(); | ||
| 41 | } | ||
| 42 | }); | 28 | }); |
| 43 | }, | 29 | }, |
| 44 | 30 | ||
| @@ -49,75 +35,97 @@ admin_search = { | |||
| 49 | $('#search_widget').fadeIn(); | 35 | $('#search_widget').fadeIn(); |
| 50 | $('#search_term').focus(); | 36 | $('#search_term').focus(); |
| 51 | } | 37 | } |
| 52 | }, | ||
| 53 | |||
| 54 | show_results : function(results) { | ||
| 55 | $('#menu_search_results').empty(); | ||
| 56 | if (results.length) { | ||
| 57 | $('#menu_search_results').append( | ||
| 58 | "<p class='search_more'>Press Enter to see all results ⏎</p>" | ||
| 59 | ); | ||
| 60 | } | ||
| 61 | for (result in results) { | ||
| 62 | $('#menu_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 | $('#menu_search_results').slideDown(); | ||
| 70 | } | 38 | } |
| 71 | }; | 39 | }; |
| 72 | 40 | ||
| 73 | menu_items = { | 41 | function initSearchPicker(options) { |
| 42 | var inputSelector = options.inputSelector; | ||
| 43 | var resultsSelector = options.resultsSelector; | ||
| 44 | var url = options.url || ADMIN_MENU_SEARCH_URL; | ||
| 45 | var onSelect = options.onSelect; // omit for a real-navigation search like admin_search | ||
| 46 | var isActive = options.isActive; // optional guard, checked before every search | ||
| 47 | var resultsHeaderHtml = options.resultsHeaderHtml; // optional, prepended only when results exist | ||
| 48 | var requestId = 0; | ||
| 49 | var timeout; | ||
| 74 | 50 | ||
| 75 | initialize_search : function() { | 51 | $(inputSelector).bind("input", function() { |
| 76 | $("#menu_search_term").bind("input", function() { | 52 | if (isActive && !isActive()) return; |
| 77 | if ($(this).val()) { | ||
| 78 | $.ajax({ | ||
| 79 | type: "GET", | ||
| 80 | url: ADMIN_MENU_SEARCH_URL, | ||
| 81 | data: "search_term=" + $(this).val(), | ||
| 82 | dataType: "json", | ||
| 83 | success : function(results) { | ||
| 84 | menu_items.show_results(results); | ||
| 85 | } | ||
| 86 | }); | ||
| 87 | } | ||
| 88 | else { | ||
| 89 | $('#search_results').slideUp(); | ||
| 90 | $('#search_results').empty(); | ||
| 91 | } | ||
| 92 | }); | ||
| 93 | }, | ||
| 94 | |||
| 95 | show_results : function(results) { | ||
| 96 | $("#search_results").empty(); | ||
| 97 | for (result in results) { | ||
| 98 | var link = $(("<a href='#'>"+ results[result].title + "</a>")); | ||
| 99 | $(link).bind("click", menu_items.link_closure(results[result])); | ||
| 100 | 53 | ||
| 54 | var term = $(this).val(); | ||
| 55 | var results = $(resultsSelector); | ||
| 56 | clearTimeout(timeout); | ||
| 101 | 57 | ||
| 102 | // Sometimes I don't get jquery; wrap() didn't work *sigh* | 58 | if (!term) { |
| 103 | // Guess I'll need a book someday or another framework | 59 | results.slideUp(); |
| 104 | var wrapper = $("<div></div>"); | 60 | results.empty(); |
| 105 | $(wrapper).append(link) | 61 | return; |
| 106 | |||
| 107 | $("#search_results").append(wrapper); | ||
| 108 | |||
| 109 | } | 62 | } |
| 110 | }, | ||
| 111 | 63 | ||
| 112 | link_closure : function(node) { | 64 | timeout = setTimeout(function() { |
| 113 | var barf = function(){ | 65 | var thisRequest = ++requestId; |
| 114 | $("#menu_item_node_id").val(node.node_id); | 66 | $.ajax({ |
| 115 | $("#menu_item_path").val("/" + node.unique_name); | 67 | type: "GET", |
| 116 | $("#menu_item_title").val(node.title); | 68 | url: url, |
| 117 | return false; | 69 | data: "search_term=" + term, |
| 118 | } | 70 | dataType: "json", |
| 71 | success: function(nodes) { | ||
| 72 | if (thisRequest !== requestId) return; | ||
| 73 | results.empty(); | ||
| 74 | if (nodes.length && resultsHeaderHtml) { | ||
| 75 | results.append(resultsHeaderHtml); | ||
| 76 | } | ||
| 77 | var found = false; | ||
| 78 | for (var i = 0; i < nodes.length; i++) { | ||
| 79 | (function(node) { | ||
| 80 | var link; | ||
| 81 | if (onSelect) { | ||
| 82 | link = $( | ||
| 83 | "<p><a href='#'>" + node.title + | ||
| 84 | "<span class='result_path'>" + node.unique_name + "</span>" + | ||
| 85 | "</a></p>" | ||
| 86 | ); | ||
| 87 | link.find("a").bind("click", function() { | ||
| 88 | onSelect(node); | ||
| 89 | results.slideUp(); | ||
| 90 | results.empty(); | ||
| 91 | return false; | ||
| 92 | }); | ||
| 93 | } else { | ||
| 94 | link = $( | ||
| 95 | "<p><a href='" + node.node_path + "'>" + node.title + | ||
| 96 | "<span class='result_path'>" + node.unique_name + "</span>" + | ||
| 97 | "</a></p>" | ||
| 98 | ); | ||
| 99 | } | ||
| 100 | results.append(link); | ||
| 101 | found = true; | ||
| 102 | })(nodes[i]); | ||
| 103 | } | ||
| 104 | if (found) { | ||
| 105 | results.slideDown(); | ||
| 106 | } else { | ||
| 107 | results.slideUp(); | ||
| 108 | } | ||
| 109 | }, | ||
| 110 | error: function(xhr, status, error) { | ||
| 111 | console.log("Ajax error:", status, error, xhr.status, xhr.responseText); | ||
| 112 | } | ||
| 113 | }); | ||
| 114 | }, 250); | ||
| 115 | }); | ||
| 116 | } | ||
| 119 | 117 | ||
| 120 | return barf; | 118 | menu_items = { |
| 119 | initialize_search : function() { | ||
| 120 | initSearchPicker({ | ||
| 121 | inputSelector: "#menu_search_term", | ||
| 122 | resultsSelector: "#menu_item_search_results", | ||
| 123 | onSelect: function(node) { | ||
| 124 | $("#menu_item_node_id").val(node.node_id); | ||
| 125 | $("#menu_item_path").val("/" + node.unique_name); | ||
| 126 | $("#menu_item_title").val(node.title); | ||
| 127 | } | ||
| 128 | }); | ||
| 121 | } | 129 | } |
| 122 | }; | 130 | }; |
| 123 | 131 | ||
| @@ -125,21 +133,13 @@ parent_search = { | |||
| 125 | initialize_search : function() { | 133 | initialize_search : function() { |
| 126 | parent_search.initialize_radio_buttons(); | 134 | parent_search.initialize_radio_buttons(); |
| 127 | 135 | ||
| 128 | $("#parent_search_term").bind("input", function() { | 136 | initSearchPicker({ |
| 129 | if ($(this).val()) { | 137 | inputSelector: "#parent_search_term", |
| 130 | $.ajax({ | 138 | resultsSelector: "#parent_search_results", |
| 131 | type: "GET", | 139 | onSelect: function(node) { |
| 132 | url: ADMIN_MENU_SEARCH_URL, | 140 | $("#parent_search_term").val(node.title); |
| 133 | data: "search_term=" + $(this).val(), | 141 | $("#parent_id").val(node.node_id).attr("data-unique-name", node.unique_name); |
| 134 | dataType: "json", | 142 | parent_search.update_resulting_path(); |
| 135 | success : function(results) { | ||
| 136 | parent_search.show_results(results); | ||
| 137 | } | ||
| 138 | }); | ||
| 139 | } | ||
| 140 | else { | ||
| 141 | $('#search_results').slideUp(); | ||
| 142 | $('#search_results').empty(); | ||
| 143 | } | 143 | } |
| 144 | }); | 144 | }); |
| 145 | 145 | ||
| @@ -154,38 +154,6 @@ parent_search = { | |||
| 154 | }); | 154 | }); |
| 155 | }, | 155 | }, |
| 156 | 156 | ||
| 157 | show_results : function(results) { | ||
| 158 | $("#search_results").empty(); | ||
| 159 | var found = false; | ||
| 160 | for (result in results) { | ||
| 161 | |||
| 162 | var link = $(( | ||
| 163 | "<p><a href='#'>" + results[result].title + | ||
| 164 | "<span class='result_path'>" + results[result].unique_name + "</span>" + | ||
| 165 | "</a></p>")); | ||
| 166 | |||
| 167 | $(link).bind("click", parent_search.link_closure(results[result])); | ||
| 168 | |||
| 169 | $("#search_results").append(link); | ||
| 170 | found = true; | ||
| 171 | } | ||
| 172 | if (found) | ||
| 173 | $('#search_results').slideDown(); | ||
| 174 | }, | ||
| 175 | |||
| 176 | link_closure : function(node) { | ||
| 177 | var barf = function(){ | ||
| 178 | $("#parent_search_term").val(node.title); | ||
| 179 | $("#parent_id").val(node.node_id).attr("data-unique-name", node.unique_name); | ||
| 180 | $('#search_results').slideUp(); | ||
| 181 | $('#search_results').empty(); | ||
| 182 | parent_search.update_resulting_path(); | ||
| 183 | return false; | ||
| 184 | } | ||
| 185 | |||
| 186 | return barf; | ||
| 187 | }, | ||
| 188 | |||
| 189 | update_resulting_path : function() { | 157 | update_resulting_path : function() { |
| 190 | var kind = $("input[name='kind']:checked"); | 158 | var kind = $("input[name='kind']:checked"); |
| 191 | var title = $("#title").val(); | 159 | var title = $("#title").val(); |
| @@ -223,122 +191,35 @@ parent_search = { | |||
| 223 | $("#parent_search_field").hide(); | 191 | $("#parent_search_field").hide(); |
| 224 | } | 192 | } |
| 225 | } | 193 | } |
| 226 | } | 194 | }; |
| 227 | 195 | ||
| 228 | move_to_search = { | 196 | move_to_search = { |
| 229 | initialize_search : function() { | 197 | initialize_search : function() { |
| 230 | $("#move_to_search_term").bind("input", function() {move_to_search.do_search($(this))}); | 198 | initSearchPicker({ |
| 231 | }, | 199 | inputSelector: "#move_to_search_term", |
| 232 | 200 | resultsSelector: "#move_to_search_results", | |
| 233 | do_search : function(_this) { | 201 | onSelect: function(node) { |
| 234 | if (_this.val()) { | 202 | $("#move_to_search_term").val(node.title); |
| 235 | $.ajax({ | 203 | $("#node_staged_parent_id").val(node.node_id); |
| 236 | type: "GET", | 204 | } |
| 237 | url: ADMIN_MENU_SEARCH_URL, | 205 | }); |
| 238 | data: "search_term=" + _this.val(), | ||
| 239 | dataType: "json", | ||
| 240 | success : function(results) { | ||
| 241 | move_to_search.show_results(results); | ||
| 242 | } | ||
| 243 | }); | ||
| 244 | } | ||
| 245 | else { | ||
| 246 | $('#search_results').slideUp(); | ||
| 247 | $('#search_results').empty(); | ||
| 248 | } | ||
| 249 | }, | ||
| 250 | |||
| 251 | show_results : function(results) { | ||
| 252 | $("#search_results").empty(); | ||
| 253 | var found = false; | ||
| 254 | for (result in results) { | ||
| 255 | var link = $(("<a href='#'>"+ results[result].title + "</a>")); | ||
| 256 | $(link).bind("click", move_to_search.link_closure(results[result])); | ||
| 257 | |||
| 258 | |||
| 259 | // Sometimes I don't get jquery; wrap() didn't work *sigh* | ||
| 260 | // Guess I'll need a book someday or another framework | ||
| 261 | var wrapper = $("<div></div>"); | ||
| 262 | $(wrapper).append(link) | ||
| 263 | |||
| 264 | $("#search_results").append(wrapper); | ||
| 265 | found = true; | ||
| 266 | } | ||
| 267 | if (found) | ||
| 268 | $('#search_results').slideDown(); | ||
| 269 | else | ||
| 270 | $('#search_results').slideUp(); | ||
| 271 | |||
| 272 | }, | ||
| 273 | |||
| 274 | link_closure : function(node) { | ||
| 275 | var barf = function(){ | ||
| 276 | $("#move_to_search_term").val(node.title); | ||
| 277 | $("#node_staged_parent_id").val(node.node_id); | ||
| 278 | $('#search_results').slideUp(); | ||
| 279 | $('#search_results').empty(); | ||
| 280 | return false; | ||
| 281 | } | ||
| 282 | |||
| 283 | return barf; | ||
| 284 | } | 206 | } |
| 285 | } | 207 | }; |
| 286 | 208 | ||
| 287 | event_search = { | 209 | event_search = { |
| 288 | initialize_search : function() { | 210 | initialize_search : function() { |
| 289 | $("#event_node_search_term").bind("input", function() { | 211 | initSearchPicker({ |
| 290 | if ($(this).val()) { | 212 | inputSelector: "#event_node_search_term", |
| 291 | $.ajax({ | 213 | resultsSelector: "#event_search_results", |
| 292 | type: "GET", | 214 | onSelect: function(node) { |
| 293 | url: ADMIN_MENU_SEARCH_URL, | 215 | $("#event_node_search_term").val(node.title); |
| 294 | data: "search_term=" + $(this).val(), | 216 | $("#event_node_id").val(node.node_id); |
| 295 | dataType: "json", | ||
| 296 | success : function(results) { | ||
| 297 | event_search.show_results(results); | ||
| 298 | } | ||
| 299 | }); | ||
| 300 | } | ||
| 301 | else { | ||
| 302 | $('#search_results').slideUp(); | ||
| 303 | $('#search_results').empty(); | ||
| 304 | } | ||
| 305 | }); | ||
| 306 | }, | ||
| 307 | 217 | ||
| 308 | show_results : function(results) { | 218 | var title_field = $("#event_title"); |
| 309 | $("#search_results").empty(); | 219 | if (title_field.val() === "") { |
| 310 | var found = false; | 220 | $("#event_title_hint").text("Using \"" + node.title + "\" from the associated node."); |
| 311 | for (result in results) { | 221 | } |
| 312 | var link = $(( | ||
| 313 | "<p><a href='#'>" + results[result].title + | ||
| 314 | "<span class='result_path'>" + results[result].unique_name + "</span>" + | ||
| 315 | "</a></p>")); | ||
| 316 | |||
| 317 | $(link).bind("click", event_search.link_closure(results[result])); | ||
| 318 | |||
| 319 | $("#search_results").append(link); | ||
| 320 | found = true; | ||
| 321 | } | ||
| 322 | if (found) | ||
| 323 | $('#search_results').slideDown(); | ||
| 324 | else | ||
| 325 | $('#search_results').slideUp(); | ||
| 326 | }, | ||
| 327 | |||
| 328 | link_closure : function(node) { | ||
| 329 | var barf = function(){ | ||
| 330 | $("#event_node_search_term").val(node.title); | ||
| 331 | $("#event_node_id").val(node.node_id); | ||
| 332 | $('#search_results').slideUp(); | ||
| 333 | $('#search_results').empty(); | ||
| 334 | |||
| 335 | var title_field = $("#event_title"); | ||
| 336 | if (title_field.val() === "") { | ||
| 337 | $("#event_title_hint").text("Using \"" + node.title + "\" from the associated node."); | ||
| 338 | } | 222 | } |
| 339 | 223 | }); | |
| 340 | return false; | ||
| 341 | } | ||
| 342 | return barf; | ||
| 343 | } | 224 | } |
| 344 | }; | 225 | }; |
diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css index 5c1e489f..da315352 100644 --- a/public/stylesheets/admin.css +++ b/public/stylesheets/admin.css | |||
| @@ -155,7 +155,6 @@ input[type=radio] { | |||
| 155 | padding-right: 5px; | 155 | padding-right: 5px; |
| 156 | padding-top: 1px; | 156 | padding-top: 1px; |
| 157 | padding-bottom: 1px; | 157 | padding-bottom: 1px; |
| 158 | text-transform: lowercase; | ||
| 159 | } | 158 | } |
| 160 | 159 | ||
| 161 | #metadata a:hover { | 160 | #metadata a:hover { |
| @@ -1023,22 +1022,19 @@ div#draft_list table td.actions a { | |||
| 1023 | font-size: 18px; | 1022 | font-size: 18px; |
| 1024 | } | 1023 | } |
| 1025 | 1024 | ||
| 1026 | #menu_search_results p, | 1025 | .search_results p { |
| 1027 | #search_results p { | ||
| 1028 | margin: 0; | 1026 | margin: 0; |
| 1029 | padding: 4px 4px 0 4px; | 1027 | padding: 4px 4px 0 4px; |
| 1030 | border-bottom: 1px solid #e8e8e8; | 1028 | border-bottom: 1px solid #e8e8e8; |
| 1031 | } | 1029 | } |
| 1032 | 1030 | ||
| 1033 | #menu_search_results p a, | 1031 | .search_results p a { |
| 1034 | #search_results p a { | ||
| 1035 | display: block; | 1032 | display: block; |
| 1036 | font-weight: bold; | 1033 | font-weight: bold; |
| 1037 | font-size: 0.95rem; | 1034 | font-size: 0.95rem; |
| 1038 | } | 1035 | } |
| 1039 | 1036 | ||
| 1040 | #menu_search_results p span.result_path, | 1037 | .search_results p span.result_path { |
| 1041 | #search_results p span.result_path { | ||
| 1042 | display: block; | 1038 | display: block; |
| 1043 | margin-top: 2px; | 1039 | margin-top: 2px; |
| 1044 | font-size: 0.75rem; | 1040 | font-size: 0.75rem; |
| @@ -1047,8 +1043,7 @@ div#draft_list table td.actions a { | |||
| 1047 | padding-bottom: 4px; | 1043 | padding-bottom: 4px; |
| 1048 | } | 1044 | } |
| 1049 | 1045 | ||
| 1050 | #menu_search_results p.search_more, | 1046 | .search_results p.search_more { |
| 1051 | #search_results p.search_more { | ||
| 1052 | margin: 0; | 1047 | margin: 0; |
| 1053 | padding: 6px 4px; | 1048 | padding: 6px 4px; |
| 1054 | font-size: 0.8rem; | 1049 | font-size: 0.8rem; |
