plok 2.0.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/plok/searchable.js +88 -11
- data/app/assets/stylesheets/plok/_autocomplete.scss +23 -35
- data/lib/generators/plok/search/templates/result_object.html.erb +1 -1
- data/lib/plok/version.rb +1 -1
- data/spec/support/fake_ar_model.rb +8 -0
- metadata +5 -10
- data/app/assets/javascripts/jquery-ui.autocomplete.html.js +0 -40
- data/config/plok.yml +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5c12946cd0b1f1f23073f8b34059867e92e2485534c5337ae30695139c4c6bba
|
|
4
|
+
data.tar.gz: ad241a51b95d3a9032ffdf42a596c63155bf4788522726d76890bf9fc7af6e73
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5bc8507b13dbf3bc89e2f431bd1edc811d3a97e868db6b7c76e93f3e223fc8e22f426309e56ee4abf652378518ccbf8487d8efbee3ef33ab17729873adbb5992
|
|
7
|
+
data.tar.gz: 55ebcff954367ce8c14ce285ec8e26f553501a6e77fdf116adf160bc2af31b8c153f622c34bb5d1ba11cdf694474fc4bab504fbd784efe677e6702b0d18db487
|
|
@@ -1,21 +1,98 @@
|
|
|
1
|
+
// Lightweight search autocomplete built on plain jQuery + Bootstrap 5 dropdown
|
|
2
|
+
// markup. Replaces the old jquery-ui.autocomplete widget.
|
|
3
|
+
//
|
|
4
|
+
// It fetches a JSON list of { label: <html>, value: <url> } from the form's
|
|
5
|
+
// action (see Backend::SearchController#query) and renders them as Bootstrap
|
|
6
|
+
// dropdown items. The HTML label embeds a type badge (see the result object
|
|
7
|
+
// partials in app/views/plok/search/result_objects/).
|
|
1
8
|
var search = search || {
|
|
9
|
+
active: -1,
|
|
10
|
+
|
|
2
11
|
init: function() {
|
|
3
|
-
this.target()
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
var $input = this.target();
|
|
13
|
+
if(!$input.length) return;
|
|
14
|
+
|
|
15
|
+
this.$menu = $('<ul class="plok-autocomplete dropdown-menu"></ul>');
|
|
16
|
+
$input
|
|
17
|
+
.attr('autocomplete', 'off')
|
|
18
|
+
.parent().css('position', 'relative').append(this.$menu);
|
|
19
|
+
|
|
20
|
+
$input
|
|
21
|
+
.on('input', this.debounce(this.query.bind(this), 200))
|
|
22
|
+
.on('keydown', this.keydown.bind(this))
|
|
23
|
+
.on('blur', function() { setTimeout(function(){ search.close(); }, 150); });
|
|
24
|
+
|
|
25
|
+
$(document).on('click', function(e) {
|
|
26
|
+
if(!$(e.target).closest('[data-plok-searchable]').length) search.close();
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
query: function() {
|
|
31
|
+
var $input = this.target();
|
|
32
|
+
var term = $input.val();
|
|
33
|
+
if(term.length < 2) return this.close();
|
|
34
|
+
|
|
35
|
+
$.getJSON($input.parents('form').attr('action'), { term: term })
|
|
36
|
+
.done(function(items) { search.render(items); });
|
|
9
37
|
},
|
|
10
38
|
|
|
11
|
-
|
|
39
|
+
render: function(items) {
|
|
40
|
+
this.$menu.empty();
|
|
41
|
+
this.active = -1;
|
|
42
|
+
|
|
43
|
+
if(!items.length) return this.close();
|
|
44
|
+
|
|
45
|
+
items.forEach(function(item) {
|
|
46
|
+
$('<li></li>')
|
|
47
|
+
.append($('<a class="dropdown-item" href="' + item.value + '"></a>').html(item.label))
|
|
48
|
+
.appendTo(search.$menu);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
this.$menu.addClass('show');
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
keydown: function(e) {
|
|
12
55
|
var code = (e.keyCode ? e.keyCode : e.which);
|
|
13
|
-
|
|
56
|
+
var $items = this.$menu.children('li');
|
|
57
|
+
|
|
58
|
+
if(code == 13) { // Enter: follow the active item, never submit the form.
|
|
59
|
+
if(this.active >= 0) {
|
|
60
|
+
window.location = $items.eq(this.active).find('a').attr('href');
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if(!this.$menu.hasClass('show')) return;
|
|
66
|
+
|
|
67
|
+
if(code == 40) { // Down
|
|
68
|
+
this.move(1, $items);
|
|
69
|
+
e.preventDefault();
|
|
70
|
+
} else if(code == 38) { // Up
|
|
71
|
+
this.move(-1, $items);
|
|
72
|
+
e.preventDefault();
|
|
73
|
+
} else if(code == 27) { // Escape
|
|
74
|
+
this.close();
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
move: function(dir, $items) {
|
|
79
|
+
$items.eq(this.active).find('a').removeClass('active');
|
|
80
|
+
this.active = (this.active + dir + $items.length) % $items.length;
|
|
81
|
+
$items.eq(this.active).find('a').addClass('active');
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
close: function() {
|
|
85
|
+
if(this.$menu) this.$menu.removeClass('show').empty();
|
|
86
|
+
this.active = -1;
|
|
14
87
|
},
|
|
15
88
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return
|
|
89
|
+
debounce: function(fn, wait) {
|
|
90
|
+
var timeout;
|
|
91
|
+
return function() {
|
|
92
|
+
var context = this, args = arguments;
|
|
93
|
+
clearTimeout(timeout);
|
|
94
|
+
timeout = setTimeout(function(){ fn.apply(context, args); }, wait);
|
|
95
|
+
};
|
|
19
96
|
},
|
|
20
97
|
|
|
21
98
|
target: function() {
|
|
@@ -1,42 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// Dropdown for the backend search autocomplete (see plok/searchable.js).
|
|
2
|
+
// Built on Bootstrap 5 .dropdown-menu / .dropdown-item markup.
|
|
3
|
+
.plok-autocomplete {
|
|
4
|
+
width: 24rem;
|
|
5
|
+
max-width: 90vw;
|
|
6
|
+
max-height: 70vh;
|
|
7
|
+
overflow-y: auto;
|
|
8
|
+
top: 100%;
|
|
9
|
+
left: 0;
|
|
10
|
+
margin-top: 0.25rem;
|
|
3
11
|
padding: 0;
|
|
4
|
-
z-index: 9999;
|
|
5
|
-
filter: drop-shadow(5px 5px 5px #666);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
// Shows up during autocompletion sometimes.
|
|
9
|
-
.ui-helper-hidden-accessible {
|
|
10
|
-
display: none;
|
|
11
|
-
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
&:last-child {
|
|
20
|
-
border: none;
|
|
21
|
-
margin-bottom: 0;
|
|
22
|
-
padding-bottom: 0;
|
|
23
|
-
}
|
|
13
|
+
.dropdown-item {
|
|
14
|
+
white-space: normal;
|
|
15
|
+
padding: 0.5rem 0.75rem;
|
|
16
|
+
border-bottom: 1px solid var(--bs-border-color);
|
|
17
|
+
cursor: pointer;
|
|
24
18
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
a.ui-menu-item-wrapper {
|
|
31
|
-
border: none;
|
|
32
|
-
|
|
33
|
-
&.ui-state-active {
|
|
34
|
-
background: none;
|
|
35
|
-
color: inherit;
|
|
36
|
-
text-decoration: none;
|
|
19
|
+
&:last-child {
|
|
20
|
+
border-bottom: 0;
|
|
21
|
+
}
|
|
37
22
|
|
|
38
|
-
|
|
39
|
-
|
|
23
|
+
// Keep muted helper text legible when the row is highlighted.
|
|
24
|
+
&.active {
|
|
25
|
+
.text-muted,
|
|
26
|
+
small {
|
|
27
|
+
color: rgba(255, 255, 255, 0.85) !important;
|
|
40
28
|
}
|
|
41
29
|
}
|
|
42
30
|
}
|
data/lib/plok/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: plok
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Davy Hellemans
|
|
8
8
|
- Dave Lens
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: rails
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
16
|
requirements:
|
|
18
|
-
- - "
|
|
17
|
+
- - ">="
|
|
19
18
|
- !ruby/object:Gem::Version
|
|
20
19
|
version: '7.0'
|
|
21
20
|
type: :runtime
|
|
22
21
|
prerelease: false
|
|
23
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
23
|
requirements:
|
|
25
|
-
- - "
|
|
24
|
+
- - ">="
|
|
26
25
|
- !ruby/object:Gem::Version
|
|
27
26
|
version: '7.0'
|
|
28
27
|
- !ruby/object:Gem::Dependency
|
|
@@ -92,7 +91,6 @@ files:
|
|
|
92
91
|
- MIT-LICENSE
|
|
93
92
|
- Rakefile
|
|
94
93
|
- app/assets/config/plok_manifest.js
|
|
95
|
-
- app/assets/javascripts/jquery-ui.autocomplete.html.js
|
|
96
94
|
- app/assets/javascripts/plok/searchable.js
|
|
97
95
|
- app/assets/javascripts/plok/sidebar.js
|
|
98
96
|
- app/assets/stylesheets/plok/_autocomplete.scss
|
|
@@ -107,7 +105,6 @@ files:
|
|
|
107
105
|
- app/models/search_index.rb
|
|
108
106
|
- app/models/search_module.rb
|
|
109
107
|
- config/initializers/module.rb
|
|
110
|
-
- config/plok.yml
|
|
111
108
|
- config/routes.rb
|
|
112
109
|
- db/migrate/20211008130809_create_plok_logs.rb
|
|
113
110
|
- db/migrate/20211015141837_create_plok_queued_tasks.rb
|
|
@@ -154,7 +151,6 @@ licenses:
|
|
|
154
151
|
- MIT
|
|
155
152
|
metadata:
|
|
156
153
|
allowed_push_host: https://rubygems.org
|
|
157
|
-
post_install_message:
|
|
158
154
|
rdoc_options: []
|
|
159
155
|
require_paths:
|
|
160
156
|
- lib
|
|
@@ -169,8 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
169
165
|
- !ruby/object:Gem::Version
|
|
170
166
|
version: '0'
|
|
171
167
|
requirements: []
|
|
172
|
-
rubygems_version:
|
|
173
|
-
signing_key:
|
|
168
|
+
rubygems_version: 4.0.11
|
|
174
169
|
specification_version: 4
|
|
175
170
|
summary: CMS basics
|
|
176
171
|
test_files: []
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* jQuery UI Autocomplete HTML Extension
|
|
3
|
-
*
|
|
4
|
-
* Copyright 2010, Scott González (http://scottgonzalez.com)
|
|
5
|
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
6
|
-
*
|
|
7
|
-
* http://github.com/scottgonzalez/jquery-ui-extensions
|
|
8
|
-
*/
|
|
9
|
-
(function( $ ) {
|
|
10
|
-
|
|
11
|
-
var proto = $.ui.autocomplete.prototype,
|
|
12
|
-
initSource = proto._initSource;
|
|
13
|
-
|
|
14
|
-
function filter( array, term ) {
|
|
15
|
-
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
|
|
16
|
-
return $.grep( array, function(value) {
|
|
17
|
-
return matcher.test( $( "<div>" ).html( value.label || value.value || value ).text() );
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
$.extend( proto, {
|
|
22
|
-
_initSource: function() {
|
|
23
|
-
if ( this.options.html && $.isArray(this.options.source) ) {
|
|
24
|
-
this.source = function( request, response ) {
|
|
25
|
-
response( filter( this.options.source, request.term ) );
|
|
26
|
-
};
|
|
27
|
-
} else {
|
|
28
|
-
initSource.call( this );
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
_renderItem: function( ul, item) {
|
|
33
|
-
return $( "<li></li>" )
|
|
34
|
-
.data( "item.autocomplete", item )
|
|
35
|
-
.append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) )
|
|
36
|
-
.appendTo( ul );
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
})( jQuery );
|