activeadmin_addons 0.11.0 → 0.12.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/activeadmin_addons/all.js.coffee +1 -0
- data/app/assets/javascripts/activeadmin_addons/selected-list.js +110 -0
- data/app/assets/stylesheets/activeadmin_addons/all.scss +1 -0
- data/app/assets/stylesheets/selected-list.scss +31 -0
- data/app/inputs/ajax_filter_input.rb +7 -1
- data/app/inputs/selected_list_input.rb +94 -0
- data/app/inputs/tags_input.rb +2 -2
- data/lib/activeadmin_addons/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7b657178df2d8d9aa225ff46d4cd07e178a82e1
|
4
|
+
data.tar.gz: c439b4bb6dc8835f8264d80f9bad2e9786860551
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3f1a38e47deaac87e470163dc80056f89cb1b446cc5c834f94883d541ce3d757041ed2dea7bbdf619f8ff5eb7005bbc3fc0f3e36c781d49eea612ec87fa89a2
|
7
|
+
data.tar.gz: 355f3a995e4771798d5ac0667037b45e356cab4541a98545587f7e33013f4b3886e137d147f586699ac9a8d8b2a444d9e85176457a2f2b32e2f646d9aff26310
|
@@ -0,0 +1,110 @@
|
|
1
|
+
//= require select2
|
2
|
+
//= require_self
|
3
|
+
|
4
|
+
$(function() {
|
5
|
+
setupSelectedList(document);
|
6
|
+
|
7
|
+
$(document).on('has_many_add:after', function(event, container){
|
8
|
+
setupSelectedList(container);
|
9
|
+
});
|
10
|
+
|
11
|
+
function setupSelectedList(container) {
|
12
|
+
$('.selected-list-container').click(function(event) {
|
13
|
+
var item = $(event.target);
|
14
|
+
if (item.hasClass('selected-item')) {
|
15
|
+
item.remove();
|
16
|
+
}
|
17
|
+
});
|
18
|
+
|
19
|
+
$('.selected-list', container).each(function(i, el) {
|
20
|
+
var url = $(el).data('url'),
|
21
|
+
fields = $(el).data('fields'),
|
22
|
+
displayName = $(el).data('display_name'),
|
23
|
+
width = $(el).data('width') || '100%',
|
24
|
+
method = $(el).data('method'),
|
25
|
+
model = $(el).data('model'),
|
26
|
+
prefix = model + '_' + method,
|
27
|
+
responseRoot = $(el).data('response_root'),
|
28
|
+
minimumInputLength = $(el).data('minimum_input_length'),
|
29
|
+
order = $(el).data('order') || (fields[0] + '_desc');
|
30
|
+
|
31
|
+
|
32
|
+
var selectOptions = {
|
33
|
+
width: width,
|
34
|
+
minimumInputLength: minimumInputLength,
|
35
|
+
allowClear: true,
|
36
|
+
multiple: true,
|
37
|
+
createSearchChoice: function() { return null; },
|
38
|
+
ajax: {
|
39
|
+
url: url,
|
40
|
+
dataType: 'json',
|
41
|
+
delay: 250,
|
42
|
+
cache: true,
|
43
|
+
data: function(term) {
|
44
|
+
var textQuery = { m: 'or' };
|
45
|
+
fields.forEach(function(field) {
|
46
|
+
textQuery[field + '_contains'] = term;
|
47
|
+
});
|
48
|
+
|
49
|
+
var query = {
|
50
|
+
order: order,
|
51
|
+
q: {
|
52
|
+
groupings: [textQuery],
|
53
|
+
combinator: 'and'
|
54
|
+
}
|
55
|
+
};
|
56
|
+
|
57
|
+
return query;
|
58
|
+
},
|
59
|
+
results: function(data, page) {
|
60
|
+
if(data.constructor == Object) {
|
61
|
+
data = data[responseRoot];
|
62
|
+
}
|
63
|
+
|
64
|
+
return {
|
65
|
+
results: jQuery.map(data, function(resource) {
|
66
|
+
return {
|
67
|
+
id: resource.id,
|
68
|
+
text: resource[displayName].toString()
|
69
|
+
};
|
70
|
+
})
|
71
|
+
};
|
72
|
+
},
|
73
|
+
},
|
74
|
+
};
|
75
|
+
|
76
|
+
function onItemSelected(event) {
|
77
|
+
var selectedItemsContainer = $("[id='" + prefix + "_selected_values']"),
|
78
|
+
itemName = model + '[' + method + '][]',
|
79
|
+
itemId = prefix + '_' + event.val;
|
80
|
+
|
81
|
+
if ($("#" + itemId).length > 0) {
|
82
|
+
return;
|
83
|
+
}
|
84
|
+
|
85
|
+
var item = $('<div>' + event.object.text + '</div>').attr({
|
86
|
+
class: 'selected-item',
|
87
|
+
id: itemId,
|
88
|
+
});
|
89
|
+
|
90
|
+
var hidden_input = $('<input>').attr({
|
91
|
+
name: itemName,
|
92
|
+
type: 'hidden',
|
93
|
+
value: event.val
|
94
|
+
});
|
95
|
+
|
96
|
+
item.appendTo(selectedItemsContainer);
|
97
|
+
hidden_input.appendTo(item);
|
98
|
+
}
|
99
|
+
|
100
|
+
function onSelectClosed() {
|
101
|
+
$(el).select2('val', '');
|
102
|
+
}
|
103
|
+
|
104
|
+
$(el).on('select2-selecting', onItemSelected);
|
105
|
+
$(el).on('select2-close', onSelectClosed);
|
106
|
+
|
107
|
+
$(el).select2(selectOptions);
|
108
|
+
});
|
109
|
+
}
|
110
|
+
});
|
@@ -0,0 +1,31 @@
|
|
1
|
+
$selected-list-btn-color: #AAA;
|
2
|
+
$selected-list-btn-hover-color: #333;
|
3
|
+
|
4
|
+
.selected-list-label {
|
5
|
+
display: inline-block;
|
6
|
+
}
|
7
|
+
|
8
|
+
.selected-list-container {
|
9
|
+
display: inline-block;
|
10
|
+
width: 80%;
|
11
|
+
|
12
|
+
.selected-item {
|
13
|
+
height: 25px;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
.selected-item {
|
18
|
+
display: table;
|
19
|
+
cursor: pointer;
|
20
|
+
|
21
|
+
&::before {
|
22
|
+
color: $selected-list-btn-color;
|
23
|
+
content: '\2716\00a0\00a0';
|
24
|
+
}
|
25
|
+
|
26
|
+
&:hover {
|
27
|
+
&::before {
|
28
|
+
color: $selected-list-btn-hover-color;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
@@ -31,7 +31,13 @@ class AjaxFilterInput < Formtastic::Inputs::StringInput
|
|
31
31
|
|
32
32
|
# rubocop:disable Style/RescueModifier
|
33
33
|
def get_selected_value(display_name)
|
34
|
-
|
34
|
+
association_name = method.to_s.chomp("_id")
|
35
|
+
association = @object.klass.reflect_on_association(association_name)
|
36
|
+
if association.options && association.options.keys.include?(:class_name)
|
37
|
+
filter_class = association.options[:class_name].constantize rescue @object.klass
|
38
|
+
else
|
39
|
+
filter_class = association_name.classify.constantize rescue @object.klass
|
40
|
+
end
|
35
41
|
selected_value = @object.conditions.find { |c| c.attributes.map(&:name).include?(method.to_s) }.values.first.value rescue nil
|
36
42
|
filter_class.find(selected_value).send(display_name) if !!selected_value
|
37
43
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
class SelectedListInput < Formtastic::Inputs::StringInput
|
2
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
3
|
+
def input_html_options
|
4
|
+
opts = {}
|
5
|
+
opts[:class] = ["selected-list"].concat([@options[:class]] || []).join(' ')
|
6
|
+
opts["data-model"] = model_name
|
7
|
+
opts["data-method"] = method
|
8
|
+
opts["data-url"] = @options[:url] || build_url
|
9
|
+
opts["data-response_root"] = @options[:response_root] || opts["data-url"].split('/').last
|
10
|
+
opts["data-fields"] = (@options[:fields] || ["name"]).to_json
|
11
|
+
opts["data-display_name"] = @options[:display_name] || "name"
|
12
|
+
opts["data-minimum_input_length"] = @options[:minimum_input_length] || 1
|
13
|
+
opts["data-width"] = @options[:width] if @options[:width]
|
14
|
+
opts["data-order"] = @options[:order_by] if @options[:order_by]
|
15
|
+
super.merge(opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_html
|
19
|
+
input_wrapping do
|
20
|
+
[
|
21
|
+
builder.label(translated_attribute(method), class: "selected-list-label"),
|
22
|
+
render_control_wrapper
|
23
|
+
].flatten.join("\n").html_safe
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def render_control_wrapper
|
28
|
+
template.content_tag(:div, class: "selected-list-container") do
|
29
|
+
template.content_tag(label_html)
|
30
|
+
template.concat(render_items_list)
|
31
|
+
template.concat(builder.text_field(virtual_attr, input_html_options))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_items_list
|
36
|
+
prefix = "#{model_name}_#{method}"
|
37
|
+
attr_name = "#{model_name}[#{method}][]"
|
38
|
+
template.content_tag(:div, id: "#{prefix}_selected_values", class: "selected-values") do
|
39
|
+
template.concat(
|
40
|
+
builder.hidden_field(method, id: "#{prefix}_empty", name: attr_name, value: nil)
|
41
|
+
)
|
42
|
+
@object.send(method).each do |item_id|
|
43
|
+
template.concat(render_item_label(prefix, attr_name, item_id))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def render_item_label(prefix, attr_name, item_id)
|
49
|
+
attr_id = "#{prefix}_#{item_id}"
|
50
|
+
div_config = { id: attr_id, class: "selected-item" }
|
51
|
+
template.content_tag(:div, div_config) do
|
52
|
+
template.concat(item_label(item_id))
|
53
|
+
template.concat(builder.hidden_field(nil, id: nil, name: attr_name, value: item_id))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def item_label(item_id)
|
58
|
+
selected_items.find { |item| item.id == item_id }.send(@options[:display_name] || "name")
|
59
|
+
end
|
60
|
+
|
61
|
+
def selected_items
|
62
|
+
@selected_items ||= @object.send(relation_name)
|
63
|
+
end
|
64
|
+
|
65
|
+
def translated_attribute(attribute)
|
66
|
+
@object.class.human_attribute_name(attribute)
|
67
|
+
end
|
68
|
+
|
69
|
+
def model_name
|
70
|
+
@object.class.to_s.underscore.tr('/', '_')
|
71
|
+
end
|
72
|
+
|
73
|
+
def virtual_attr
|
74
|
+
attr_name = "#{method}_str".to_sym
|
75
|
+
@object.singleton_class.send(:attr_accessor, attr_name) unless @object.respond_to?(attr_name)
|
76
|
+
attr_name
|
77
|
+
end
|
78
|
+
|
79
|
+
def build_url
|
80
|
+
url = ["/"]
|
81
|
+
|
82
|
+
if ActiveAdmin.application.default_namespace.present?
|
83
|
+
url << "#{ActiveAdmin.application.default_namespace}/"
|
84
|
+
end
|
85
|
+
|
86
|
+
url << relation_name
|
87
|
+
|
88
|
+
url.join("")
|
89
|
+
end
|
90
|
+
|
91
|
+
def relation_name
|
92
|
+
method.to_s.chomp("_ids").tableize
|
93
|
+
end
|
94
|
+
end
|
data/app/inputs/tags_input.rb
CHANGED
@@ -30,7 +30,7 @@ class TagsInput < Formtastic::Inputs::StringInput
|
|
30
30
|
input_wrapping do
|
31
31
|
[
|
32
32
|
label_html,
|
33
|
-
|
33
|
+
render_selected_hidden_items,
|
34
34
|
builder.text_field(virtual_input_name, relation_tag_options)
|
35
35
|
].flatten.join("\n").html_safe
|
36
36
|
end
|
@@ -68,7 +68,7 @@ class TagsInput < Formtastic::Inputs::StringInput
|
|
68
68
|
attr_name.to_sym
|
69
69
|
end
|
70
70
|
|
71
|
-
def
|
71
|
+
def render_selected_hidden_items
|
72
72
|
prefix = "#{model_name}_#{method}"
|
73
73
|
attr_name = "#{model_name}[#{method}][]"
|
74
74
|
template.content_tag(:div, id: "#{prefix}_selected_values") do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeadmin_addons
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Platanus
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-
|
14
|
+
date: 2017-05-28 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: railties
|
@@ -373,15 +373,18 @@ files:
|
|
373
373
|
- app/assets/javascripts/activeadmin_addons/config.js
|
374
374
|
- app/assets/javascripts/activeadmin_addons/date-time-picker.js
|
375
375
|
- app/assets/javascripts/activeadmin_addons/select2.js
|
376
|
+
- app/assets/javascripts/activeadmin_addons/selected-list.js
|
376
377
|
- app/assets/javascripts/palette-color-picker.js
|
377
378
|
- app/assets/stylesheets/activeadmin_addons/all.scss
|
378
379
|
- app/assets/stylesheets/palette-color-picker.scss
|
380
|
+
- app/assets/stylesheets/selected-list.scss
|
379
381
|
- app/inputs/ajax_filter_input.rb
|
380
382
|
- app/inputs/color_picker_input.rb
|
381
383
|
- app/inputs/date_time_picker_input.rb
|
382
384
|
- app/inputs/nested_select_input.rb
|
383
385
|
- app/inputs/range_select_input.rb
|
384
386
|
- app/inputs/search_select_input.rb
|
387
|
+
- app/inputs/selected_list_input.rb
|
385
388
|
- app/inputs/tags_input.rb
|
386
389
|
- lib/activeadmin_addons.rb
|
387
390
|
- lib/activeadmin_addons/active_admin_config.rb
|
@@ -420,7 +423,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
420
423
|
version: '0'
|
421
424
|
requirements: []
|
422
425
|
rubyforge_project:
|
423
|
-
rubygems_version: 2.
|
426
|
+
rubygems_version: 2.6.12
|
424
427
|
signing_key:
|
425
428
|
specification_version: 4
|
426
429
|
summary: Set of addons to help with the activeadmin ui
|