combo_box 0.0.3 → 0.0.4
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.
- data/VERSION +1 -1
- data/lib/assets/javascripts/combo_box.js +46 -16
- data/lib/combo_box/generator.rb +21 -20
- data/lib/combo_box/helpers/form_tag_helper.rb +30 -8
- metadata +11 -11
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
@@ -1,15 +1,31 @@
|
|
1
1
|
/*
|
2
2
|
* jQuery Combo Box
|
3
3
|
*/
|
4
|
+
|
4
5
|
(function ($) {
|
5
|
-
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
$.setComboBox = function (element, selected) {
|
10
|
+
element.prop("valueField").val(selected.id);
|
11
|
+
element.comboBoxCache = selected.label;
|
12
|
+
element.val(element.comboBoxCache);
|
13
|
+
element.attr("size", (element.comboBoxCache.length < 32 ? 32 : element.comboBoxCache.length > element.maxSize ? element.maxSize : element.comboBoxCache.length));
|
14
|
+
element.prop("valueField").trigger("emulated:change");
|
15
|
+
return true;
|
16
|
+
};
|
17
|
+
|
18
|
+
$.getComboBox = function (element) {
|
19
|
+
return {id: element.prop("valueField").val(), label: element.val()};
|
20
|
+
};
|
21
|
+
|
6
22
|
// Initializes combo-box controls
|
7
|
-
$.
|
23
|
+
$.initializeComboBox = function () {
|
8
24
|
var element = $(this);
|
9
|
-
if (
|
25
|
+
if (element.prop("alreadyBound") !== true) {
|
10
26
|
element.comboBoxCache = element.val();
|
11
|
-
element.valueField
|
12
|
-
if ($.isEmptyObject(element.valueField)) {
|
27
|
+
element.prop("valueField", $('#' + element.attr('data-value-container')));
|
28
|
+
if ($.isEmptyObject(element.prop("valueField")[0])) {
|
13
29
|
alert('An input ' + element.id + ' with a "data-combo-box" attribute must contain a "data-value-container" attribute (#' + element.attr('data-value-container') + ')');
|
14
30
|
}
|
15
31
|
element.maxSize = parseInt(element.attr('data-max-size'), 10);
|
@@ -20,22 +36,36 @@
|
|
20
36
|
source: element.attr('data-combo-box'),
|
21
37
|
minLength: 1,
|
22
38
|
select: function (event, ui) {
|
23
|
-
|
24
|
-
element.valueField.value = selected.id;
|
25
|
-
element.comboBoxCache = selected.label;
|
26
|
-
element.attr("size", (element.comboBoxCache.length < 32 ? 32 : element.comboBoxCache.length > element.maxSize ? element.maxSize : element.comboBoxCache.length));
|
27
|
-
$(element.valueField).trigger("emulated:change");
|
28
|
-
return true;
|
39
|
+
return $.setComboBox(element, ui.item);
|
29
40
|
}
|
30
41
|
});
|
31
|
-
|
42
|
+
element.prop("alreadyBound", true);
|
32
43
|
}
|
33
|
-
return
|
44
|
+
return true;
|
34
45
|
};
|
46
|
+
$.initializeComboBoxes = function () {
|
47
|
+
$('input[data-combo-box]').each($.initializeComboBox);
|
48
|
+
}
|
35
49
|
// Bind elements with the method
|
36
50
|
// $('input[data-combo-box]').ready($.initializeComboBoxes);
|
37
|
-
$(document).ready(
|
38
|
-
|
51
|
+
$(document).ready($.initializeComboBoxes);
|
52
|
+
$(document).ajaxComplete($.initializeComboBoxes);
|
53
|
+
|
54
|
+
$("a[data-permute-combo-box]").live("click", function () {
|
55
|
+
var elements = $($(this).attr("data-permute-combo-box"));
|
56
|
+
for (var i = 0; i < elements.length; i += 1) {
|
57
|
+
if ($(elements[i]).attr("data-combo-box") === undefined || $(elements[i]).attr("data-combo-box") === null) {
|
58
|
+
elements[i] = $("input[data-value-container='" + $(elements[i]).attr("id") + "']");
|
59
|
+
}
|
60
|
+
}
|
61
|
+
if (elements.length > 1) {
|
62
|
+
var vt = $.getComboBox($(elements[0]));
|
63
|
+
for (var i = 1; i < elements.length; i += 1) {
|
64
|
+
$.setComboBox($(elements[i-1]), $.getComboBox($(elements[i])));
|
65
|
+
}
|
66
|
+
$.setComboBox($(elements[elements.length - 1]), vt);
|
67
|
+
}
|
68
|
+
return false;
|
39
69
|
});
|
40
|
-
|
70
|
+
|
41
71
|
})(jQuery);
|
data/lib/combo_box/generator.rb
CHANGED
@@ -13,12 +13,12 @@ module ComboBox
|
|
13
13
|
@name = name.to_s
|
14
14
|
@filter = options.delete(:filter) || "%X%"
|
15
15
|
@interpolation_key = options.delete(:interpolation_key) || @name.gsub(/\W/, '_')
|
16
|
-
|
16
|
+
klass = @model
|
17
17
|
@through = (options.delete(:through) || []).collect do |reflection|
|
18
|
-
unless
|
19
|
-
raise Exception.new("Model #{
|
18
|
+
unless klass.reflections[reflection.to_sym]
|
19
|
+
raise Exception.new("Model #{klass.name} has no reflections #{reflection.inspect}")
|
20
20
|
end
|
21
|
-
|
21
|
+
klass = klass.reflections[reflection.to_sym].class_name.constantize
|
22
22
|
reflection.to_sym
|
23
23
|
end
|
24
24
|
@column = foreign_model.columns_hash[@name]
|
@@ -115,26 +115,31 @@ module ComboBox
|
|
115
115
|
|
116
116
|
code = ""
|
117
117
|
code << "search, conditions = params[:term], [#{query.join(' AND ').inspect+parameters}]\n"
|
118
|
-
code << "
|
119
|
-
code << "if
|
120
|
-
code << " conditions
|
121
|
-
code << "
|
122
|
-
code << "
|
123
|
-
code << "
|
118
|
+
code << "if params[:id].to_i > 0\n"
|
119
|
+
code << " conditions[0] << '#{' AND ' if query.size>0}#{@model.table_name}.id = ?'\n"
|
120
|
+
code << " conditions << params[:id].to_i\n"
|
121
|
+
code << "else\n"
|
122
|
+
code << " words = search.to_s.mb_chars.downcase.strip.normalize.split(/[\\s\\,]+/)\n"
|
123
|
+
code << " if words.size > 0\n"
|
124
|
+
code << " conditions[0] << '#{' AND ' if query.size>0}('\n"
|
125
|
+
code << " words.each_index do |index|\n"
|
126
|
+
code << " word = words[index].to_s\n"
|
127
|
+
code << " conditions[0] << ') AND (' if index > 0\n"
|
124
128
|
if ActiveRecord::Base.connection.adapter_name == "MySQL"
|
125
|
-
code << "
|
129
|
+
code << " conditions[0] << "+@columns.collect{|column| "LOWER(CAST(#{column.sql_name} AS CHAR)) LIKE ?"}.join(' OR ').inspect+"\n"
|
126
130
|
else
|
127
|
-
code << "
|
131
|
+
code << " conditions[0] << "+@columns.collect{|column| "LOWER(CAST(#{column.sql_name} AS VARCHAR)) LIKE ?"}.join(' OR ').inspect+"\n"
|
128
132
|
end
|
129
|
-
code << "
|
133
|
+
code << " conditions += ["+@columns.collect{|column| column.filter.inspect.gsub('X', '"+word+"').gsub(/(^\"\"\+|\+\"\"\+|\+\"\")/, '')}.join(", ")+"]\n"
|
134
|
+
code << " end\n"
|
135
|
+
code << " conditions[0] << ')'\n"
|
130
136
|
code << " end\n"
|
131
|
-
code << " conditions[0] << ')'\n"
|
132
137
|
code << "end\n"
|
133
138
|
|
134
139
|
# joins = @options[:joins] ? ", :joins=>"+@options[:joins].inspect : ""
|
135
140
|
# order = ", :order=>"+@columns.collect{|column| "#{column[0]} ASC"}.join(', ').inspect
|
136
141
|
# limit = ", :limit=>"+(@options[:limit]||80).to_s
|
137
|
-
joins = @options[:joins] ? ".joins(#{@options[:joins].inspect}).
|
142
|
+
joins = @options[:joins] ? ".joins(#{@options[:joins].inspect}).includes(#{@options[:joins].inspect})" : ""
|
138
143
|
|
139
144
|
order = @options[:order] ? ".order(#{@options[:order].inspect})" : ".order("+@columns.collect{|c| "#{c.sql_name} ASC"}.join(', ').inspect+")"
|
140
145
|
limit = ".limit(#{@options[:limit]||80})"
|
@@ -179,11 +184,7 @@ module ComboBox
|
|
179
184
|
code << " if #{record}.is_a? #{@model.name}\n"
|
180
185
|
code << " return #{item_label(record)}\n"
|
181
186
|
code << " else\n"
|
182
|
-
|
183
|
-
code << " return '[UnfoundRecord]'\n"
|
184
|
-
else
|
185
|
-
code << " return ''\n"
|
186
|
-
end
|
187
|
+
code << " return ''\n"
|
187
188
|
code << " end\n"
|
188
189
|
code << "end\n"
|
189
190
|
return code
|
@@ -25,15 +25,17 @@ module ComboBox
|
|
25
25
|
action = choices.split(/\#+/)
|
26
26
|
choices = {:action=>action[1], :controller=>action[0]}
|
27
27
|
end
|
28
|
-
choices[:controller] ||= options
|
28
|
+
choices[:controller] ||= options.delete(:controller) || controller.controller_name
|
29
29
|
unless ComboBox::CompiledLabels.methods.include?("item_label_for_#{choices[:action]}_in_#{choices[:controller]}".to_sym)
|
30
|
-
"#{choices[:controller].to_s.classify.pluralize}Controller"
|
30
|
+
needed_controller = "#{choices[:controller].to_s.classify.pluralize}Controller"
|
31
|
+
needed_controller.constantize
|
31
32
|
unless ComboBox::CompiledLabels.methods.include?("item_label_for_#{choices[:action]}_in_#{choices[:controller]}".to_sym)
|
32
|
-
raise Exception.new("It seems there is no search_for declaration corresponding to #{choices[:action]}")
|
33
|
+
raise Exception.new("It seems there is no search_for declaration corresponding to #{choices[:action]} in #{needed_controller}")
|
33
34
|
end
|
34
35
|
end
|
36
|
+
html_options[:id] ||= "#{object_name}_#{method}"
|
35
37
|
html = ""
|
36
|
-
html << tag(:input, :type=>:text, "data-combo-box"=>url_for(choices.merge(:format=>:json)), "data-value-container"=>
|
38
|
+
html << tag(:input, :type=>:text, "data-combo-box"=>url_for(choices.merge(:format=>:json)), "data-value-container"=>html_options[:id], :value=>ComboBox::CompiledLabels.send("item_label_for_#{choices[:action]}_in_#{choices[:controller]}", object.send(method.to_s.gsub(/_id$/,''))), :size=>html_options.delete(:size)||32)
|
37
39
|
html << hidden_field(object_name, method, html_options)
|
38
40
|
return html.html_safe
|
39
41
|
end
|
@@ -52,21 +54,41 @@ module ComboBox
|
|
52
54
|
#
|
53
55
|
# @return [String] HTML code of the tags
|
54
56
|
def combo_box_tag(name, choices = nil, options={}, html_options = {})
|
55
|
-
if choices.nil? or choices == controller_name.to_sym
|
57
|
+
if choices.nil? or (choices == controller_name.to_sym and not options.has_key?(:controller))
|
56
58
|
choices = {:action=>"search_for"}
|
57
59
|
elsif choices.is_a?(Symbol)
|
58
|
-
choices = {:action=>"search_for_#{choices}"}
|
60
|
+
choices = {:action=>"search_for_#{choices}", :controller=>(options.delete(:controller) || controller.controller_name)}
|
61
|
+
if object = options.delete(:value)
|
62
|
+
options[:label] = item_label(object, choices[:action], choices[:controller])
|
63
|
+
html_options[:value] = object.id
|
64
|
+
end
|
59
65
|
elsif choices.is_a?(String)
|
60
66
|
action = choices.split(/\#+/)
|
61
67
|
choices = {:action=>action[1], :controller=>action[0]}
|
62
68
|
end
|
63
|
-
choices[:controller] ||= controller.controller_name
|
69
|
+
choices[:controller] ||= options.delete(:controller) || controller.controller_name
|
70
|
+
html_options[:id] ||= name.to_s.gsub(/\W+/, '_').gsub(/(^_+|_+$)/, '')
|
64
71
|
html = ""
|
65
|
-
html << tag(:input, :type=>:text, "data-combo-box"=>url_for(choices.merge(:format=>:json)), "data-value-container"=>
|
72
|
+
html << tag(:input, :type=>:text, "data-combo-box"=>url_for(choices.merge(:format=>:json)), "data-value-container"=>html_options[:id], :size=>html_options.delete(:size)||32, :value=>options.delete(:label))
|
66
73
|
html << hidden_field_tag(name, html_options.delete(:value), html_options)
|
67
74
|
return html.html_safe
|
68
75
|
end
|
69
76
|
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def item_label(record, item_action, item_controller=nil)
|
81
|
+
item_controller ||= controller.controller_name
|
82
|
+
unless ComboBox::CompiledLabels.methods.include?("item_label_for_#{item_action}_in_#{item_controller}".to_sym)
|
83
|
+
needed_controller = "#{item_controller.to_s.classify.pluralize}Controller"
|
84
|
+
needed_controller.constantize
|
85
|
+
unless ComboBox::CompiledLabels.methods.include?("item_label_for_#{item_action}_in_#{item_controller}".to_sym)
|
86
|
+
raise Exception.new("It seems there is no search_for declaration corresponding to #{item_action} in #{needed_controller}")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
return ComboBox::CompiledLabels.send("item_label_for_#{item_action}_in_#{item_controller}", record)
|
90
|
+
end
|
91
|
+
|
70
92
|
end
|
71
93
|
end
|
72
94
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: combo_box
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-09-
|
12
|
+
date: 2011-09-27 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &25950140 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *25950140
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: jquery-rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &25949660 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *25949660
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jeweler
|
38
|
-
requirement: &
|
38
|
+
requirement: &25949180 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.6.4
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *25949180
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rcov
|
49
|
-
requirement: &
|
49
|
+
requirement: &25948700 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *25948700
|
58
58
|
description: Adds helpers for Rails views and controller in order to manage 'dynamic
|
59
59
|
select'. It uses jQuery UI as support for inobtrusive use in forms. It's not the
|
60
60
|
classic Autocompleter, its use is limited to belongs_to reflections.
|
@@ -93,7 +93,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
93
93
|
version: '0'
|
94
94
|
segments:
|
95
95
|
- 0
|
96
|
-
hash:
|
96
|
+
hash: 3818061861584846825
|
97
97
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
98
|
none: false
|
99
99
|
requirements:
|