[inventory] search autocomplete in dropdown
parent
e6d8238d57
commit
f89af8e2cc
|
@ -4,6 +4,8 @@ Style/Documentation:
|
|||
Enabled: false
|
||||
Metrics/MethodLength:
|
||||
Enabled: false
|
||||
Metrics/ClassLength:
|
||||
Enabled: false
|
||||
Metrics/AbcSize:
|
||||
Enabled: false
|
||||
|
||||
|
|
10
Gemfile
10
Gemfile
|
@ -3,13 +3,14 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
|||
|
||||
ruby '2.6.3'
|
||||
|
||||
gem 'rails', '~> 6.0.1'
|
||||
gem 'jbuilder', '~> 2.7'
|
||||
gem 'pg', '~> 1.1' # dnf install libpq-devel
|
||||
gem 'puma', '~> 4.1'
|
||||
gem 'rails', '~> 6.0.1'
|
||||
gem 'rails-jquery-autocomplete'
|
||||
gem 'sass-rails', '>= 6'
|
||||
gem 'webpacker', '~> 4.0'
|
||||
gem 'turbolinks', '~> 5'
|
||||
gem 'jbuilder', '~> 2.7'
|
||||
gem 'webpacker', '~> 4.0'
|
||||
# Use Redis adapter to run Action Cable in production
|
||||
# gem 'redis', '~> 4.0'
|
||||
# Use Active Model has_secure_password
|
||||
|
@ -19,9 +20,8 @@ gem 'jbuilder', '~> 2.7'
|
|||
# gem 'image_processing', '~> 1.2'
|
||||
|
||||
gem 'bootsnap', '>= 1.4.2', require: false
|
||||
|
||||
gem 'foundation-rails', '~> 6.5'
|
||||
gem 'autoprefixer-rails'
|
||||
gem 'foundation-rails', '~> 6.5'
|
||||
|
||||
group :development, :test do
|
||||
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||
|
|
|
@ -158,6 +158,8 @@ GEM
|
|||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.3.0)
|
||||
loofah (~> 2.3)
|
||||
rails-jquery-autocomplete (1.0.5)
|
||||
rails (>= 3.2)
|
||||
railties (6.0.1)
|
||||
actionpack (= 6.0.1)
|
||||
activesupport (= 6.0.1)
|
||||
|
@ -268,6 +270,7 @@ DEPENDENCIES
|
|||
puma (~> 4.1)
|
||||
rails (~> 6.0.1)
|
||||
rails-controller-testing
|
||||
rails-jquery-autocomplete
|
||||
rspec-rails (= 4.0.0.beta3)
|
||||
sass-rails (>= 6)
|
||||
selenium-webdriver
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
class InventoryObjectsController < ApplicationController
|
||||
autocomplete :inventory_object, :name
|
||||
|
||||
def index
|
||||
@objects = InventoryObject.all
|
||||
@search_object = InventoryObject.new
|
||||
end
|
||||
|
||||
def show
|
||||
|
|
|
@ -11,3 +11,5 @@ $(document).on('turbolinks:load', function() {
|
|||
});
|
||||
|
||||
import "aug-attr-spliced";
|
||||
|
||||
require("jquery-ui/ui/widgets/autocomplete")();
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Unobtrusive autocomplete
|
||||
*
|
||||
* To use it, you just have to include the HTML attribute autocomplete
|
||||
* with the autocomplete URL as the value
|
||||
*
|
||||
* Example:
|
||||
* <input type="text" data-autocomplete="/url/to/autocomplete">
|
||||
*
|
||||
* Optionally, you can use a jQuery selector to specify a field that can
|
||||
* be updated with the element id whenever you find a matching value
|
||||
*
|
||||
* Example:
|
||||
* <input type="text" data-autocomplete="/url/to/autocomplete" data-id-element="#id_field">
|
||||
*/
|
||||
|
||||
(function(jQuery)
|
||||
{
|
||||
var self = null;
|
||||
jQuery.fn.railsAutocomplete = function(selector) {
|
||||
var handler = function() {
|
||||
if (!this.railsAutoCompleter) {
|
||||
this.railsAutoCompleter = new jQuery.railsAutocomplete(this);
|
||||
}
|
||||
};
|
||||
if (jQuery.fn.on !== undefined) {
|
||||
if (!selector) {
|
||||
return;
|
||||
}
|
||||
return jQuery(document).on('focus',selector,handler);
|
||||
}
|
||||
else {
|
||||
return this.live('focus',handler);
|
||||
}
|
||||
};
|
||||
|
||||
jQuery.railsAutocomplete = function (e) {
|
||||
var _e = e;
|
||||
this.init(_e);
|
||||
};
|
||||
jQuery.railsAutocomplete.options = {
|
||||
showNoMatches: true,
|
||||
noMatchesLabel: 'no existing match'
|
||||
}
|
||||
|
||||
jQuery.railsAutocomplete.fn = jQuery.railsAutocomplete.prototype = {
|
||||
railsAutocomplete: '0.0.1'
|
||||
};
|
||||
|
||||
jQuery.railsAutocomplete.fn.extend = jQuery.railsAutocomplete.extend = jQuery.extend;
|
||||
jQuery.railsAutocomplete.fn.extend({
|
||||
init: function(e) {
|
||||
e.delimiter = jQuery(e).attr('data-delimiter') || null;
|
||||
e.min_length = jQuery(e).attr('data-min-length') || jQuery(e).attr('min-length') || 2;
|
||||
e.append_to = jQuery(e).attr('data-append-to') || null;
|
||||
e.autoFocus = jQuery(e).attr('data-auto-focus') || false;
|
||||
function split( val ) {
|
||||
return val.split( e.delimiter );
|
||||
}
|
||||
function extractLast( term ) {
|
||||
return split( term ).pop().replace(/^\s+/,"");
|
||||
}
|
||||
|
||||
jQuery(e).autocomplete({
|
||||
appendTo: e.append_to,
|
||||
autoFocus: e.autoFocus,
|
||||
delay: jQuery(e).attr('delay') || 0,
|
||||
source: function( request, response ) {
|
||||
var firedFrom = this.element[0];
|
||||
var params = {term: extractLast( request.term )};
|
||||
if (jQuery(e).attr('data-autocomplete-fields')) {
|
||||
jQuery.each(jQuery.parseJSON(jQuery(e).attr('data-autocomplete-fields')), function(field, selector) {
|
||||
params[field] = jQuery(selector).val();
|
||||
});
|
||||
}
|
||||
jQuery.getJSON( jQuery(e).attr('data-autocomplete'), params, function() {
|
||||
var options = {};
|
||||
jQuery.extend(options, jQuery.railsAutocomplete.options);
|
||||
jQuery.each(options, function(key, value) {
|
||||
if(options.hasOwnProperty(key)) {
|
||||
var attrVal = jQuery(e).attr('data-' + key);
|
||||
options[key] = attrVal ? attrVal : value;
|
||||
}
|
||||
});
|
||||
if(arguments[0].length == 0 && jQuery.inArray(options.showNoMatches, [true, 'true']) >= 0) {
|
||||
arguments[0] = [];
|
||||
arguments[0][0] = { id: "", label: options.noMatchesLabel };
|
||||
}
|
||||
jQuery(arguments[0]).each(function(i, el) {
|
||||
var obj = {};
|
||||
obj[el.id] = el;
|
||||
jQuery(e).data(obj);
|
||||
});
|
||||
response.apply(null, arguments);
|
||||
jQuery(firedFrom).trigger('railsAutocomplete.source', arguments);
|
||||
});
|
||||
},
|
||||
change: function( event, ui ) {
|
||||
if(!jQuery(this).is('[data-id-element]') ||
|
||||
jQuery(jQuery(this).attr('data-id-element')).val() === "") {
|
||||
return;
|
||||
}
|
||||
jQuery(jQuery(this).attr('data-id-element')).val(ui.item ? ui.item.id : "").trigger('change');
|
||||
|
||||
if (jQuery(this).attr('data-update-elements')) {
|
||||
var update_elements = jQuery.parseJSON(jQuery(this).attr("data-update-elements"));
|
||||
var data = ui.item ? jQuery(this).data(ui.item.id.toString()) : {};
|
||||
if(update_elements && jQuery(update_elements['id']).val() === "") {
|
||||
return;
|
||||
}
|
||||
for (var key in update_elements) {
|
||||
var element = jQuery(update_elements[key]);
|
||||
if (element.is(':checkbox')) {
|
||||
if (data[key] != null) {
|
||||
element.prop('checked', data[key]);
|
||||
}
|
||||
} else {
|
||||
element.val(ui.item ? data[key] : "").trigger('change');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
search: function() {
|
||||
// custom minLength
|
||||
var term = extractLast( this.value );
|
||||
if ( term.length < e.min_length ) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
focus: function() {
|
||||
// prevent value inserted on focus
|
||||
return false;
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
// first ensure value is a string
|
||||
ui.item.value = ui.item.value.toString();
|
||||
if(ui.item.value.toLowerCase().indexOf('no match') != -1 || ui.item.value.toLowerCase().indexOf('too many results') != -1){
|
||||
jQuery(this).trigger('railsAutocomplete.noMatch', ui);
|
||||
return false;
|
||||
}
|
||||
var terms = split( this.value );
|
||||
// remove the current input
|
||||
terms.pop();
|
||||
// add the selected item
|
||||
terms.push( ui.item.value );
|
||||
// add placeholder to get the comma-and-space at the end
|
||||
if (e.delimiter != null) {
|
||||
terms.push( "" );
|
||||
this.value = terms.join( e.delimiter );
|
||||
} else {
|
||||
this.value = terms.join("");
|
||||
if (jQuery(this).attr('data-id-element')) {
|
||||
jQuery(jQuery(this).attr('data-id-element')).val(ui.item.id).trigger('change');
|
||||
}
|
||||
if (jQuery(this).attr('data-update-elements')) {
|
||||
var data = ui.item;
|
||||
var new_record = ui.item.value.indexOf('Create New') != -1 ? true : false;
|
||||
var update_elements = jQuery.parseJSON(jQuery(this).attr("data-update-elements"));
|
||||
for (var key in update_elements) {
|
||||
if(jQuery(update_elements[key]).attr("type") === "checkbox"){
|
||||
if(data[key] === true || data[key] === 1) {
|
||||
jQuery(update_elements[key]).attr("checked","checked");
|
||||
}
|
||||
else {
|
||||
jQuery(update_elements[key]).removeAttr("checked");
|
||||
}
|
||||
}
|
||||
else{
|
||||
if((new_record && data[key] && data[key].indexOf('Create New') == -1) || !new_record){
|
||||
jQuery(update_elements[key]).val(data[key]).trigger('change');
|
||||
}else{
|
||||
jQuery(update_elements[key]).val('').trigger('change');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var remember_string = this.value;
|
||||
jQuery(this).bind('keyup.clearId', function(){
|
||||
if(jQuery.trim(jQuery(this).val()) != jQuery.trim(remember_string)){
|
||||
jQuery(jQuery(this).attr('data-id-element')).val("").trigger('change');
|
||||
jQuery(this).unbind('keyup.clearId');
|
||||
}
|
||||
});
|
||||
jQuery(e).trigger('railsAutocomplete.select', ui);
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
jQuery(e).trigger('railsAutocomplete.init');
|
||||
}
|
||||
});
|
||||
|
||||
jQuery(document).ready(function(){
|
||||
jQuery('input[data-autocomplete]').railsAutocomplete('input[data-autocomplete]');
|
||||
});
|
||||
})(jQuery);
|
|
@ -9,14 +9,17 @@
|
|||
</div>
|
||||
|
||||
<div class="small-12 medium-auto cell">
|
||||
<form class="grid-x grid-padding-x">
|
||||
<div class="shrink cell">
|
||||
<button class="button secondary">Search</button>
|
||||
<%= form_for @search_object, {url: inventory_search_path} do |f| %>
|
||||
<div class="grid-x grid-padding-x">
|
||||
<div class="shrink cell">
|
||||
<%= f.submit "Search", class: "button secondary" %>
|
||||
</div>
|
||||
<div class="auto cell">
|
||||
<%= f.autocomplete_field :name,
|
||||
autocomplete_name_inventory_objects_path %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="auto cell">
|
||||
<input type="text" id="searchterm"/>
|
||||
</div>
|
||||
</form>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -8,44 +8,45 @@
|
|||
|
||||
<%= stylesheet_link_tag "application" %>
|
||||
<%= javascript_pack_tag "application" %>
|
||||
<%= javascript_pack_tag "autocomplete-rails" %>
|
||||
<%= csrf_meta_tags %>
|
||||
</head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="title-bar aug"
|
||||
data-responsive-toggle="applications-menu"
|
||||
data-hide-for="medium">
|
||||
<button class="menu-icon" type="button"
|
||||
data-toggle="applications-menu">
|
||||
</button>
|
||||
<div class="title-bar-title">Arcology</div>
|
||||
</div>
|
||||
<body>
|
||||
<div class="title-bar aug"
|
||||
data-responsive-toggle="applications-menu"
|
||||
data-hide-for="medium">
|
||||
<button class="menu-icon" type="button"
|
||||
data-toggle="applications-menu">
|
||||
</button>
|
||||
<div class="title-bar-title">Arcology</div>
|
||||
</div>
|
||||
|
||||
<div class="top-bar aug" id="applications-menu">
|
||||
<div class="top-bar-left">
|
||||
<ul class="menu">
|
||||
<li class="hide-for-small-only menu-text">Arcology</li>
|
||||
<li><%= link_to "Metadata", metadata_path %></li>
|
||||
<li><%= link_to "Inventory", inventory_objects_path %></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-bar aug" id="applications-menu">
|
||||
<div class="top-bar-left">
|
||||
<ul class="menu">
|
||||
<li class="hide-for-small-only menu-text">Arcology</li>
|
||||
<li><%= link_to "Metadata", metadata_path %></li>
|
||||
<li><%= link_to "Inventory", inventory_objects_path %></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if flash.notice %>
|
||||
<div class="callout warning">
|
||||
<%= flash.notice %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if flash.notice %>
|
||||
<div class="callout warning">
|
||||
<%= flash.notice %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if flash.alert %>
|
||||
<div class="callout alert">
|
||||
<%= flash.alert %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if flash.alert %>
|
||||
<div class="callout alert">
|
||||
<%= flash.alert %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="grid-container">
|
||||
<%= yield %>
|
||||
</div>
|
||||
<div class="grid-container">
|
||||
<%= yield %>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
Rails.application.routes.draw do
|
||||
resources :metadata
|
||||
|
||||
resources :inventory_objects, path: 'inventory' do
|
||||
get 'child', action: 'new'
|
||||
|
||||
get :autocomplete_name, on: :collection
|
||||
end
|
||||
resources :file_data
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"augmented-ui": "^1.1.0",
|
||||
"foundation-sites": "^6.5.3",
|
||||
"jquery": "^3.4.1",
|
||||
"jquery-ui": "^1.12.1",
|
||||
"turbolinks": "^5.2.0"
|
||||
},
|
||||
"version": "0.1.0",
|
||||
|
|
|
@ -3807,6 +3807,11 @@ jest-worker@^24.9.0:
|
|||
merge-stream "^2.0.0"
|
||||
supports-color "^6.1.0"
|
||||
|
||||
jquery-ui@^1.12.1:
|
||||
version "1.12.1"
|
||||
resolved "https://registry.yarnpkg.com/jquery-ui/-/jquery-ui-1.12.1.tgz#bcb4045c8dd0539c134bc1488cdd3e768a7a9e51"
|
||||
integrity sha1-vLQEXI3QU5wTS8FIjN0+dop6nlE=
|
||||
|
||||
jquery@^3.4.1:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2"
|
||||
|
|
Loading…
Reference in New Issue