Merge pull request #3557 from evazion/fix-autocomplete-consistency

Fix inconsistencies in autocomplete behavior
This commit is contained in:
Albert Yi
2018-02-21 14:51:50 -08:00
committed by GitHub
13 changed files with 97 additions and 164 deletions

View File

@@ -5,10 +5,6 @@
if ($("#c-artists").length) { if ($("#c-artists").length) {
Danbooru.Artist.initialize_check_name(); Danbooru.Artist.initialize_check_name();
Danbooru.Artist.initialize_shortcuts(); Danbooru.Artist.initialize_shortcuts();
if (Danbooru.meta("enable-auto-complete") === "true") {
Danbooru.Artist.initialize_autocomplete();
}
} }
} }
@@ -43,46 +39,8 @@
}); });
} }
}; };
Danbooru.Artist.initialize_autocomplete = function() {
var $fields = $("#search_name,#quick_search_name");
$fields.autocomplete({
minLength: 1,
source: function(req, resp) {
$.ajax({
url: "/artists.json",
data: {
"search[name]": req.term + "*",
"search[is_active]": true,
"search[order]": "post_count",
"limit": 10
},
method: "get",
success: function(data) {
resp($.map(data, function(artist) {
return {
label: artist.name.replace(/_/g, " "),
value: artist.name
};
}));
}
});
}
});
var render_artist = function(list, artist) {
var $link = $("<a/>").addClass("tag-type-1").text(artist.label);
return $("<li/>").data("item.autocomplete", artist).append($link).appendTo(list);
};
$fields.each(function(i, field) {
$(field).data("uiAutocomplete")._renderItem = render_artist;
});
}
})(); })();
$(document).ready(function() { $(document).ready(function() {
Danbooru.Artist.initialize_all(); Danbooru.Artist.initialize_all();
}); });

View File

@@ -11,9 +11,26 @@
Danbooru.Autocomplete.initialize_all = function() { Danbooru.Autocomplete.initialize_all = function() {
if (Danbooru.meta("enable-auto-complete") === "true") { if (Danbooru.meta("enable-auto-complete") === "true") {
$.widget("ui.autocomplete", $.ui.autocomplete, {
options: {
delay: 100,
minLength: 1,
autoFocus: false,
focus: function() { return false; },
},
_create: function() {
this.element.on("keydown.danbooru.autocomplete.tab", null, "tab", Danbooru.Autocomplete.on_tab);
this._super();
},
_renderItem: Danbooru.Autocomplete.render_item,
});
Danbooru.Autocomplete.enable_local_storage = this.test_local_storage(); Danbooru.Autocomplete.enable_local_storage = this.test_local_storage();
this.initialize_tag_autocomplete(); this.initialize_tag_autocomplete();
this.initialize_mention_autocomplete(); this.initialize_mention_autocomplete($(".autocomplete-mentions textarea"));
this.initialize_artist_autocomplete($('[data-autocomplete="artist"]'));
this.initialize_pool_autocomplete($('[data-autocomplete="pool"]'));
this.initialize_wiki_autocomplete($('[data-autocomplete="wiki-page"]'));
this.prune_local_storage(); this.prune_local_storage();
} }
} }
@@ -43,17 +60,8 @@
} }
} }
Danbooru.Autocomplete.initialize_mention_autocomplete = function() { Danbooru.Autocomplete.initialize_mention_autocomplete = function($fields) {
var $fields = $(".autocomplete-mentions textarea");
$fields.on("keydown.danbooru.autocomplete.tab", null, "tab", Danbooru.Autocomplete.on_tab);
$fields.autocomplete({ $fields.autocomplete({
delay: 500,
minLength: 2,
autoFocus: false,
focus: function() {
return false;
},
select: function(event, ui) { select: function(event, ui) {
Danbooru.Autocomplete.insert_completion(this, ui.item.value); Danbooru.Autocomplete.insert_completion(this, ui.item.value);
return false; return false;
@@ -91,13 +99,7 @@
var $fields_multiple = $('[data-autocomplete="tag-query"], [data-autocomplete="tag-edit"]'); var $fields_multiple = $('[data-autocomplete="tag-query"], [data-autocomplete="tag-edit"]');
var $fields_single = $('[data-autocomplete="tag"]'); var $fields_single = $('[data-autocomplete="tag"]');
$fields_multiple.on("keydown.danbooru.autocomplete.tab", null, "tab", Danbooru.Autocomplete.on_tab);
$fields_multiple.autocomplete({ $fields_multiple.autocomplete({
delay: 100,
autoFocus: false,
focus: function() {
return false;
},
select: function(event, ui) { select: function(event, ui) {
// Prevent Danbooru.Upload.initialize_enter_on_tags from running if the // Prevent Danbooru.Upload.initialize_enter_on_tags from running if the
// Enter key is used to select a tag from the autocomplete menu. // Enter key is used to select a tag from the autocomplete menu.
@@ -182,18 +184,74 @@
}); });
$fields_single.autocomplete({ $fields_single.autocomplete({
minLength: 1,
autoFocus: true,
source: function(req, resp) { source: function(req, resp) {
Danbooru.Autocomplete.normal_source(req.term, resp); Danbooru.Autocomplete.normal_source(req.term, resp);
} }
}); });
$.merge($fields_multiple, $fields_single).each(function(i, field) {
$(field).data("uiAutocomplete")._renderItem = Danbooru.Autocomplete.render_item;
});
} }
Danbooru.Autocomplete.initialize_artist_autocomplete = function($fields) {
$fields.autocomplete({
source: function(req, resp) {
$.ajax({
url: "/artists.json",
data: {
"search[name]": req.term + "*",
"search[is_active]": true,
"search[order]": "post_count",
"limit": 10
},
method: "get",
success: function(data) {
resp($.map(data, function(artist) {
return {
type: "tag",
label: artist.name.replace(/_/g, " "),
value: artist.name,
category: <%= Tag.categories.artist %>,
};
}));
}
});
}
});
};
Danbooru.Autocomplete.initialize_pool_autocomplete = function($fields) {
$fields.autocomplete({
source: function(req, resp) {
Danbooru.Autocomplete.pool_source(req.term, resp);
},
});
};
Danbooru.Autocomplete.initialize_wiki_autocomplete = function($fields) {
$fields.autocomplete({
source: function(req, resp) {
$.ajax({
url: "/wiki_pages.json",
data: {
"search[title]": req.term + "*",
"search[hide_deleted]": "Yes",
"search[order]": "post_count",
"limit": 10
},
method: "get",
success: function(data) {
resp($.map(data, function(wiki_page) {
return {
type: "tag",
label: wiki_page.title.replace(/_/g, " "),
value: wiki_page.title,
category: wiki_page.category_name
};
}));
}
});
}
});
};
Danbooru.Autocomplete.normal_source = function(term, resp) { Danbooru.Autocomplete.normal_source = function(term, resp) {
var key = "ac-" + term.replace(/\./g,'\uFFFF'); var key = "ac-" + term.replace(/\./g,'\uFFFF');
if (this.enable_local_storage) { if (this.enable_local_storage) {
@@ -441,7 +499,7 @@
return { return {
type: "pool", type: "pool",
label: pool.name.replace(/_/g, " "), label: pool.name.replace(/_/g, " "),
value: metatag + ":" + pool.name, value: (metatag ? (metatag + ":" + pool.name) : pool.name),
post_count: pool.post_count, post_count: pool.post_count,
category: pool.category category: pool.category
}; };

View File

@@ -4,9 +4,6 @@
Danbooru.Pool.initialize_all = function() { Danbooru.Pool.initialize_all = function() {
if ($("#c-pools").length) { if ($("#c-pools").length) {
this.initialize_shortcuts(); this.initialize_shortcuts();
if (Danbooru.meta("enable-auto-complete") === "true") {
this.initialize_autocomplete_for("#search_name_matches,#quick_search_name_matches");
}
} }
if ($("#c-posts").length && $("#a-show").length) { if ($("#c-posts").length && $("#a-show").length) {
@@ -18,47 +15,9 @@
} }
} }
Danbooru.Pool.initialize_autocomplete_for = function(selector) {
var $fields = $(selector);
$fields.autocomplete({
minLength: 1,
source: function(req, resp) {
$.ajax({
url: "/pools.json",
data: {
"search[name_matches]": req.term,
"limit": 10
},
method: "get",
success: function(data) {
resp($.map(data, function(pool) {
return {
label: pool.name.replace(/_/g, " "),
value: pool.name,
category: pool.category
};
}));
}
});
}
});
var render_pool = function(list, pool) {
var $link = $("<a/>").addClass("pool-category-" + pool.category).text(pool.label);
return $("<li/>").data("item.autocomplete", pool).append($link).appendTo(list);
};
$fields.each(function(i, field) {
$(field).data("uiAutocomplete")._renderItem = render_pool;
});
}
Danbooru.Pool.initialize_add_to_pool_link = function() { Danbooru.Pool.initialize_add_to_pool_link = function() {
$("#add-to-pool-dialog").dialog({autoOpen: false}); $("#add-to-pool-dialog").dialog({autoOpen: false});
this.initialize_autocomplete_for("#add-to-pool-dialog input[type=text]");
$("#pool").click(function(e) { $("#pool").click(function(e) {
e.preventDefault(); e.preventDefault();
$("#add-to-pool-dialog").dialog("open"); $("#add-to-pool-dialog").dialog("open");

View File

@@ -3,52 +3,10 @@
Danbooru.WikiPage.initialize_all = function() { Danbooru.WikiPage.initialize_all = function() {
if ($("#c-wiki-pages,#c-wiki-page-versions").length) { if ($("#c-wiki-pages,#c-wiki-page-versions").length) {
if (Danbooru.meta("enable-auto-complete") === "true") {
this.initialize_autocomplete();
}
this.initialize_shortcuts(); this.initialize_shortcuts();
} }
} }
Danbooru.WikiPage.initialize_autocomplete = function() {
var $fields = $("#search_title,#quick_search_title");
$fields.autocomplete({
minLength: 1,
source: function(req, resp) {
$.ajax({
url: "/wiki_pages.json",
data: {
"search[title]": req.term + "*",
"search[hide_deleted]": "Yes",
"search[order]": "post_count",
"limit": 10
},
method: "get",
success: function(data) {
resp($.map(data, function(wiki_page) {
return {
label: wiki_page.title.replace(/_/g, " "),
value: wiki_page.title,
category: wiki_page.category_name
};
}));
}
});
}
});
var render_wiki_page = function(list, wiki_page) {
var $link = $("<a/>").addClass("tag-type-" + wiki_page.category).text(wiki_page.label);
return $("<li/>").data("item.autocomplete", wiki_page).append($link).appendTo(list);
};
$fields.each(function(i, field) {
$(field).data("uiAutocomplete")._renderItem = render_wiki_page;
});
}
Danbooru.WikiPage.initialize_shortcuts = function() { Danbooru.WikiPage.initialize_shortcuts = function() {
if ($("#a-show").length) { if ($("#a-show").length) {
Danbooru.keydown("e", "edit", function(e) { Danbooru.keydown("e", "edit", function(e) {

View File

@@ -163,14 +163,14 @@ module ApplicationHelper
submit_tag("Preview", "data-input-id" => options[:input_id], "data-preview-id" => options[:preview_id]) submit_tag("Preview", "data-input-id" => options[:input_id], "data-preview-id" => options[:preview_id])
end end
def search_field(method, options = {}) def search_field(method, label: method.titleize, hint: nil, value: nil, **attributes)
name = options[:label] || method.titleize content_tag(:div, class: "input") do
string = '<div class="input"><label for="search_' + method + '">' + name + '</label><input type="text" name="search[' + method + ']" id="search_' + method + '">' label_html = label_tag("search_#{method}", label)
if options[:hint] input_html = text_field_tag(method, value, id: "search_#{method}", name: "search[#{method}]", **attributes)
string += '<p class="hint">' + options[:hint] + '</p>' hint_html = hint.present? ? content_tag(:p, hint, class: "hint") : ""
label_html + input_html + hint_html
end end
string += '</div>'
string.html_safe
end end
def body_attributes(user = CurrentUser.user) def body_attributes(user = CurrentUser.user)

View File

@@ -5,7 +5,7 @@
<div id="search"> <div id="search">
<%= form_tag(artist_versions_path, :method => :get, :class => "simple_form") do %> <%= form_tag(artist_versions_path, :method => :get, :class => "simple_form") do %>
<%= search_field "updater_name", :label => "User" %> <%= search_field "updater_name", :label => "User" %>
<%= search_field "name", :label => "Name" %> <%= search_field "name", :label => "Name", :data => { autocomplete: "artist" } %>
<%= submit_tag "Search" %> <%= submit_tag "Search" %>
<% end %> <% end %>
</div> </div>

View File

@@ -1,3 +1,3 @@
<%= form_tag(artists_path, :method => :get) do %> <%= form_tag(artists_path, :method => :get) do %>
<%= text_field "search", "name", :id => "quick_search_name", :placeholder => "Search artists" %> <%= text_field "search", "name", id: "quick_search_name", placeholder: "Search artists", data: { autocomplete: "artist" } %>
<% end %> <% end %>

View File

@@ -1,5 +1,5 @@
<%= simple_form_for(:search, url: artists_path, method: :get, defaults: { required: false }, html: { class: "inline-form" }) do |f| %> <%= simple_form_for(:search, url: artists_path, method: :get, defaults: { required: false }, html: { class: "inline-form" }) do |f| %>
<%= f.input :name, label: "Name", hint: "Use * for wildcard", input_html: { value: params[:search][:name] } %> <%= f.input :name, label: "Name", hint: "Use * for wildcard", input_html: { value: params[:search][:name], data: { autocomplete: "artist" }} %>
<%= f.input :url_matches, label: "URL", as: "string", input_html: { value: params[:search][:url_matches] } %> <%= f.input :url_matches, label: "URL", as: "string", input_html: { value: params[:search][:url_matches] } %>
<%= f.input :creator_name, label: "Creator", input_html: { value: params[:search][:creator_name] } %> <%= f.input :creator_name, label: "Creator", input_html: { value: params[:search][:creator_name] } %>
<%= f.input :is_active, label: "Active?", collection: [["Yes", true], ["No", false]], include_blank: true, selected: params[:search][:is_active] %> <%= f.input :is_active, label: "Active?", collection: [["Yes", true], ["No", false]], include_blank: true, selected: params[:search][:is_active] %>

View File

@@ -3,7 +3,7 @@
<div class="input"> <div class="input">
<label>Pool Name</label> <label>Pool Name</label>
<span id="pool-name-container"><%= text_field_tag "pool_name", "", :size => 20 %></span> <span id="pool-name-container"><%= text_field_tag "pool_name", "", :size => 20, :data => { autocomplete: "pool" } %></span>
<span id="pool-name-hint" class="hint">Search for a pool containing (<%= link_to "see full list", all_select_pool_element_path, :remote => true %>)</span> <span id="pool-name-hint" class="hint">Search for a pool containing (<%= link_to "see full list", all_select_pool_element_path, :remote => true %>)</span>
</div> </div>

View File

@@ -1,3 +1,3 @@
<%= form_tag(pools_path, :method => :get) do %> <%= form_tag(pools_path, :method => :get) do %>
<%= text_field "search", "name_matches", :id => "quick_search_name_matches", :placeholder => "Search pools" %> <%= text_field "search", "name_matches", id: "quick_search_name_matches", placeholder: "Search pools", data: { autocomplete: "pool" } %>
<% end %> <% end %>

View File

@@ -5,7 +5,7 @@
<th><label for="search_name_matches">Name</label></th> <th><label for="search_name_matches">Name</label></th>
<td> <td>
<div class="input"> <div class="input">
<%= text_field "search", "name_matches", :value => params[:search][:name_matches] %> <%= text_field "search", "name_matches", :value => params[:search][:name_matches], :data => { autocomplete: "pool" } %>
</div> </div>
</td> </td>
</tr> </tr>

View File

@@ -1,3 +1,3 @@
<%= form_tag(wiki_pages_path, :method => :get) do %> <%= form_tag(wiki_pages_path, :method => :get) do %>
<%= text_field "search", "title", :id => "quick_search_title", :placeholder => "Search wiki pages" %> <%= text_field "search", "title", id: "quick_search_title", placeholder: "Search wiki pages", data: { autocomplete: "wiki-page" } %>
<% end %> <% end %>

View File

@@ -1,7 +1,7 @@
<div id="c-wiki-pages"> <div id="c-wiki-pages">
<div id="a-search"> <div id="a-search">
<%= form_tag(wiki_pages_path, :method => :get, :class => "simple_form") do %> <%= form_tag(wiki_pages_path, :method => :get, :class => "simple_form") do %>
<%= search_field "title", :hint => "Use * for wildcard searches" %> <%= search_field "title", :hint => "Use * for wildcard searches", :data => { :autocomplete => "wiki-page" } %>
<%= search_field "creator_name" %> <%= search_field "creator_name" %>
<%= search_field "body_matches", :label => "Body" %> <%= search_field "body_matches", :label => "Body" %>
<%= search_field "other_names_match", :label => "Other names", :hint => "Use * for wildcard searches" %> <%= search_field "other_names_match", :label => "Other names", :hint => "Use * for wildcard searches" %>