assoc_whisperer 1.0.4 → 1.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 +5 -13
- data/app/assets/javascripts/assoc_whisp.js +248 -0
- data/app/helpers/action_view/helpers/assoc_whisperer_helper.rb +2 -1
- data/app/helpers/action_view/helpers/tags/assoc_whisperer_field.rb +2 -2
- data/lib/assoc_whisperer/version.rb +1 -1
- metadata +11 -11
- data/app/assets/javascripts/assoc_whisp.coffee +0 -179
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MjlhMDE5NmE1YzlhM2QzYzA2NjA5NjczYTY2OWQyOWJiNjYwMTk0Mg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 560ba60c23716d32676b7fad089a78bb3564acce
|
4
|
+
data.tar.gz: 56bf2e3a493c9e96bca65ea408dc5f515d97a590
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NmE1ZWViZTBjNGExMDYxMjgyNzU2ZmMyNWE4ZmU0MTZlNWJjNTQwYWMxNDUz
|
11
|
-
NGYyMGRlZWRmZmJlOTk0NDhhNzVlMDJlMDFlNWM1MGNlM2ZhNGY=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
OWVlMGQ0MGU0MjQ2M2M3YmNhZjVlYjVlOWYwZWVmZmQzMjk2MjRiYzQyYzI1
|
14
|
-
YzZiMjBkZDYyZjQ3YTdhNTY5NmY4YzJkNWJmODA5YzQ3NmZjODA0OTIzMTFk
|
15
|
-
NGI1YWYxMWRlY2E4NWI1Y2UyNmMzYmIwMDgyMDU3YmFiOTE3NzQ=
|
6
|
+
metadata.gz: e79e15a365f8db2031de3ed1d3daf7b8a68477be0e5daa039739be214b16172e8a90f0de9356255ff5dc9b416ab5f09d7a8b7f85a7968da911d93756da46c2a5
|
7
|
+
data.tar.gz: 8a89817479453e08c83062b5506199fbaf160317fcab33f22b0d1cf68e319a3191ce7c6369e46d24e4f2d69f4e0713588bc07b23e05f4854b059b15dbb6eeefe
|
@@ -0,0 +1,248 @@
|
|
1
|
+
/**
|
2
|
+
* Created by doooby on 30.9.14.
|
3
|
+
*/
|
4
|
+
|
5
|
+
document.AssocWhisperer = (function () {
|
6
|
+
var proto, klass, all_array = [];
|
7
|
+
|
8
|
+
$(document).ready(function(){
|
9
|
+
var w;
|
10
|
+
$('.assoc_whisperer').each(function (i, el) {
|
11
|
+
w = createWhisperer(el);
|
12
|
+
all_array.push(w);
|
13
|
+
});
|
14
|
+
});
|
15
|
+
|
16
|
+
// This is where Whisperer Object is created - with all hidden inner methods.
|
17
|
+
function createWhisperer(dom_node) {
|
18
|
+
var el, w, _nodes, _timer;
|
19
|
+
|
20
|
+
el = $(dom_node);
|
21
|
+
_nodes = {
|
22
|
+
base: el,
|
23
|
+
text_field: el.children('.text_field'),
|
24
|
+
value_field: el.children('.value_field'),
|
25
|
+
list: null
|
26
|
+
};
|
27
|
+
|
28
|
+
w = Object.create(proto, {
|
29
|
+
nodes: {value: _nodes},
|
30
|
+
action: {value: el.attr('data-action')},
|
31
|
+
url: {value: el.attr('data-url')},
|
32
|
+
focused: {value: false, writable: true},
|
33
|
+
filled: {value: _nodes['value_field'].val()!=='', writable: true},
|
34
|
+
client_side: {value: el.attr('data-client-side')==='true'},
|
35
|
+
full_data: {value: null, writable: true}
|
36
|
+
});
|
37
|
+
|
38
|
+
_nodes.text_field.on('keyup', function(e){
|
39
|
+
var input_text;
|
40
|
+
if (e.keyCode===27) { // escape key
|
41
|
+
w.removeList();
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
// if (e.keyCode!==37 && e.keyCode!==39) {} // left & right
|
45
|
+
|
46
|
+
if (_timer) clearTimeout(_timer);
|
47
|
+
if (w.filled) {
|
48
|
+
w.filled = false;
|
49
|
+
_nodes['value_field'].val('');
|
50
|
+
_nodes['text_field'].addClass('unfilled');
|
51
|
+
}
|
52
|
+
|
53
|
+
input_text = _nodes['text_field'].val();
|
54
|
+
if (input_text==='') {
|
55
|
+
w.removeList();
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
if (_nodes['list']) {
|
59
|
+
_nodes['list'].addClass('invalid');
|
60
|
+
}
|
61
|
+
_timer = setTimeout(function () {
|
62
|
+
if (w.client_side) {
|
63
|
+
if (!w.full_data) querry.call(w, null, function (html_text) {
|
64
|
+
w.full_data = $(html_text);
|
65
|
+
digest(input_text);
|
66
|
+
});
|
67
|
+
else digest(input_text);
|
68
|
+
}
|
69
|
+
else querry.call(w, input_text, function (html_text) {
|
70
|
+
showList($(html_text));
|
71
|
+
});
|
72
|
+
}, 700);
|
73
|
+
}
|
74
|
+
});
|
75
|
+
_nodes.text_field.on('click', function(){ _nodes['text_field'].select(); });
|
76
|
+
_nodes.text_field.focus(function(){ w.focused = true; });
|
77
|
+
_nodes.text_field.blur(function(){ onBlur(); });
|
78
|
+
el.children('.dropdown_button').on('click', function(){
|
79
|
+
if (_timer) clearTimeout(_timer);
|
80
|
+
if (w.client_side) {
|
81
|
+
function f () {
|
82
|
+
var input_text;
|
83
|
+
if (w.filled) showList(w.full_data);
|
84
|
+
else {
|
85
|
+
input_text = _nodes['text_field'].val();
|
86
|
+
digest(input_text==='' ? null : input_text);
|
87
|
+
}
|
88
|
+
_nodes['list'].focus();
|
89
|
+
}
|
90
|
+
if (!w.full_data) querry.call(w, null, function (html_text) {
|
91
|
+
w.full_data = $(html_text);
|
92
|
+
f();
|
93
|
+
});
|
94
|
+
else f();
|
95
|
+
}
|
96
|
+
else {
|
97
|
+
if (w.filled) querry.call(w, null, function (html_text) {
|
98
|
+
showList($(html_text));
|
99
|
+
});
|
100
|
+
else querry.call(w, _nodes['text_field'].val(), function (html_text) {
|
101
|
+
showList($(html_text));
|
102
|
+
});
|
103
|
+
_nodes['list'].focus();
|
104
|
+
}
|
105
|
+
});
|
106
|
+
|
107
|
+
// For local full_data finds matching rows and shows them.
|
108
|
+
function digest(input_text) {
|
109
|
+
var narrowed_list = w.full_data;
|
110
|
+
if (input_text && input_text!=='') {
|
111
|
+
input_text = input_text.toLowerCase();
|
112
|
+
narrowed_list = $(narrowed_list[0].cloneNode());
|
113
|
+
w.full_data.children().each(function () {
|
114
|
+
if (this.innerText.toLowerCase().indexOf(input_text)!==-1)
|
115
|
+
narrowed_list.append($(this).clone());
|
116
|
+
});
|
117
|
+
}
|
118
|
+
showList(narrowed_list);
|
119
|
+
}
|
120
|
+
|
121
|
+
// Attaches a List sent by html string within Whisperer's tag. Positions it underneath the text field.
|
122
|
+
function showList (list) {
|
123
|
+
var base_dom;
|
124
|
+
w.removeList();
|
125
|
+
|
126
|
+
_nodes['list'] = list;
|
127
|
+
|
128
|
+
base_dom = _nodes['base'];
|
129
|
+
list.css('min-width', base_dom.width());
|
130
|
+
list.css('left', base_dom.offset().left);
|
131
|
+
list.css('top', base_dom.position().top + base_dom.outerHeight());
|
132
|
+
list.focus(function(){ w.focused = true; });
|
133
|
+
list.blur(function(){ onBlur(); });
|
134
|
+
base_dom.append(list);
|
135
|
+
|
136
|
+
list.find('div').on('click', function(el){ w.select($(el.currentTarget)); });
|
137
|
+
}
|
138
|
+
|
139
|
+
// Hides the List if either of the controls were unfocused.
|
140
|
+
function onBlur () {
|
141
|
+
w.focused = false;
|
142
|
+
setTimeout(function(){ if (!w.focused) w.removeList(); }, 100);
|
143
|
+
}
|
144
|
+
|
145
|
+
return w;
|
146
|
+
}
|
147
|
+
|
148
|
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
149
|
+
// Whisperer prototype //
|
150
|
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
151
|
+
|
152
|
+
proto = Object.create(Object);
|
153
|
+
|
154
|
+
// Removes the List should there be any.
|
155
|
+
Object.defineProperty(proto, 'removeList', {
|
156
|
+
value: function () {
|
157
|
+
if (this.nodes['list']) {
|
158
|
+
this.nodes['list'].detach();
|
159
|
+
this.nodes['list'] = null
|
160
|
+
}
|
161
|
+
}
|
162
|
+
});
|
163
|
+
|
164
|
+
// Select given row (must be jQuery object) and hides the List.
|
165
|
+
Object.defineProperty(proto, 'select', {
|
166
|
+
value: function (row) {
|
167
|
+
var text;
|
168
|
+
if (row.length!==1) return;
|
169
|
+
text = row.text();
|
170
|
+
this.nodes['text_field'].val(text);
|
171
|
+
this.nodes['text_field'].removeClass('unfilled');
|
172
|
+
this.nodes['value_field'].val(row.attr('data-value'));
|
173
|
+
this.filled = true;
|
174
|
+
this.removeList();
|
175
|
+
}
|
176
|
+
});
|
177
|
+
|
178
|
+
// Actual ajax request for given input
|
179
|
+
function querry (input, on_success) {
|
180
|
+
var w = this;
|
181
|
+
klass.querrying = true;
|
182
|
+
$.ajax(w.url, {
|
183
|
+
type: 'GET',
|
184
|
+
dataType: 'html',
|
185
|
+
data: {data_action: w.action, input: (input||'')},
|
186
|
+
error: function () { w.removeList(); },
|
187
|
+
success: on_success,
|
188
|
+
complete: function () { klass.querrying = false; }
|
189
|
+
}
|
190
|
+
);
|
191
|
+
}
|
192
|
+
|
193
|
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
194
|
+
// public interface //
|
195
|
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
196
|
+
|
197
|
+
|
198
|
+
klass = Object.create(Object, {querrying: {value: false, writable: true}});
|
199
|
+
|
200
|
+
// Return a Whisperer instance by its data-action attribute.
|
201
|
+
function findWhisperer(action) {
|
202
|
+
var i, w;
|
203
|
+
for (i = 0; i < all_array.length; i += 1) {
|
204
|
+
w = all_array[i];
|
205
|
+
if (w.action===action) return w;
|
206
|
+
}
|
207
|
+
return null;
|
208
|
+
}
|
209
|
+
|
210
|
+
// Sets a value to Whisperer
|
211
|
+
Object.defineProperty(klass, 'setValueFor', {
|
212
|
+
value: function (value, whisp_action) {
|
213
|
+
findWhisperer(whisp_action).nodes['value_field'].val(value);
|
214
|
+
}
|
215
|
+
});
|
216
|
+
|
217
|
+
// Querries for selected text and seletcs the option if found
|
218
|
+
Object.defineProperty(klass, 'selectTextFor', {
|
219
|
+
value: function (text, whisp_action) {
|
220
|
+
var w;
|
221
|
+
w = findWhisperer(whisp_action);
|
222
|
+
querry.call(w, text, function (html_text) {
|
223
|
+
w.select($(html_text).find('div:contains("'+text+'")'));
|
224
|
+
});
|
225
|
+
}
|
226
|
+
});
|
227
|
+
|
228
|
+
// Querries and seletcs the option by value if found
|
229
|
+
// Selects the first option if the given value is '#1'.
|
230
|
+
Object.defineProperty(klass, 'selectValueFor', {
|
231
|
+
value: function (value, whisp_action) {
|
232
|
+
var w;
|
233
|
+
w = findWhisperer(whisp_action);
|
234
|
+
querry.call(w, null, function (html_text) {
|
235
|
+
switch (value) {
|
236
|
+
case '#1':
|
237
|
+
w.select($(html_text).find('div:first'));
|
238
|
+
break;
|
239
|
+
default:
|
240
|
+
w.select($(html_text).find('div[data-value="'+value+'"]'));
|
241
|
+
break;
|
242
|
+
}
|
243
|
+
});
|
244
|
+
}
|
245
|
+
});
|
246
|
+
|
247
|
+
return Object.freeze(klass);
|
248
|
+
})();
|
@@ -52,7 +52,8 @@ module ActionView
|
|
52
52
|
content << %Q( type="text" value="#{options[:text]}">)
|
53
53
|
content << %Q(<span class="dropdown_button">\u25BE</span>)
|
54
54
|
content_tag :span, content.html_safe, 'data-url' => (options[:url]||AssocWhisperer.def_url),
|
55
|
-
'data-action' => data_action, '
|
55
|
+
'data-action' => data_action, 'data-client-side' => (options[:client_side] && 'true'),
|
56
|
+
'class' => 'assoc_whisperer'
|
56
57
|
end
|
57
58
|
|
58
59
|
private
|
@@ -17,8 +17,8 @@ module ActionView
|
|
17
17
|
content << %Q( id="#{text_tag_id}" name="#{text_tag_name}" size="#{@options[:size]||12}")
|
18
18
|
content << %Q( type="text" value="#{text_tag_value}">)
|
19
19
|
content << %Q(<span class="dropdown_button">\u25BE</span>)
|
20
|
-
content_tag :span, content.html_safe, 'data-url' => @options[:url],
|
21
|
-
'data-
|
20
|
+
content_tag :span, content.html_safe, 'data-url' => @options[:url], 'data-action' => @action,
|
21
|
+
'data-client-side' => (@options[:client_side] && 'true'), 'class' => 'assoc_whisperer'
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: assoc_whisperer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ondřej Želazko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
description: You can associate two models together, while user inputs e.g. name and
|
@@ -46,12 +46,12 @@ executables: []
|
|
46
46
|
extensions: []
|
47
47
|
extra_rdoc_files: []
|
48
48
|
files:
|
49
|
-
- .gitignore
|
49
|
+
- ".gitignore"
|
50
50
|
- Gemfile
|
51
51
|
- LICENSE.txt
|
52
52
|
- README.md
|
53
53
|
- Rakefile
|
54
|
-
- app/assets/javascripts/assoc_whisp.
|
54
|
+
- app/assets/javascripts/assoc_whisp.js
|
55
55
|
- app/assets/stylesheets/assoc_whisp_example.css
|
56
56
|
- app/helpers/action_view/helpers/assoc_whisperer_helper.rb
|
57
57
|
- app/helpers/action_view/helpers/tags/assoc_whisperer_field.rb
|
@@ -70,17 +70,17 @@ require_paths:
|
|
70
70
|
- lib
|
71
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
|
-
- -
|
78
|
+
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
82
|
rubyforge_project:
|
83
|
-
rubygems_version: 2.
|
83
|
+
rubygems_version: 2.2.2
|
84
84
|
signing_key:
|
85
85
|
specification_version: 4
|
86
86
|
summary: Rails tag assoc_whisperer for forms
|
@@ -1,179 +0,0 @@
|
|
1
|
-
document.AssocWhispering = {
|
2
|
-
# Stores all instantiated Whisperer objects.
|
3
|
-
all: []
|
4
|
-
# Any active Whisperer#getList method holds this variable in true state.
|
5
|
-
working: false
|
6
|
-
# Return a Whisperer instance by its data-action attribute.
|
7
|
-
find: (action) ->
|
8
|
-
for w in document.AssocWhispering.all
|
9
|
-
return w if w._action==action
|
10
|
-
return null
|
11
|
-
# Makes a whisperer (found by its data-action) to select the given text, if present.
|
12
|
-
selectTextFor: (text, whisp_action) ->
|
13
|
-
w = document.AssocWhispering.find(whisp_action)
|
14
|
-
w._last_input = '§'
|
15
|
-
w.getList('', false, ->
|
16
|
-
w.selectText(text)
|
17
|
-
)
|
18
|
-
# Makes a whisperer (found by its data-action) to select the given value, if present.
|
19
|
-
# Selects the first value if the given value is '#1'.
|
20
|
-
selectValueFor: (value, whisp_action) ->
|
21
|
-
w = document.AssocWhispering.find(whisp_action)
|
22
|
-
w._last_input = '§'
|
23
|
-
w.getList('', false, ->
|
24
|
-
switch value
|
25
|
-
when '#1' then w.select(w._list_tag.find('div:first'))
|
26
|
-
else w.selectValue(value)
|
27
|
-
)
|
28
|
-
}
|
29
|
-
|
30
|
-
$(document).ready ->
|
31
|
-
# attach all whisperers to after document id loaded
|
32
|
-
$('.assoc_whisperer').each (i, el) ->
|
33
|
-
w = new Whisperer(el)
|
34
|
-
document.AssocWhispering.all.push(w)
|
35
|
-
|
36
|
-
# This is the class that is instantiated and hold behind a tag with 'assoc_whisperer' css class.
|
37
|
-
# It holds an action and url that is supposed to call when user changes the input text field.
|
38
|
-
# Request is sent 700ms after last input key hit.
|
39
|
-
# On success response attaches the list and shows it.
|
40
|
-
# One can click on the drop down button to have the list generated for empty input (ie. '' string).
|
41
|
-
class Whisperer
|
42
|
-
_tag: null
|
43
|
-
_text_field: null
|
44
|
-
_value_field: null
|
45
|
-
_list_tag: null
|
46
|
-
_action: null
|
47
|
-
_url: null
|
48
|
-
|
49
|
-
_timeout: null
|
50
|
-
_last_input: '§'
|
51
|
-
_is_filled: false
|
52
|
-
_focus: null
|
53
|
-
|
54
|
-
# Constructor takes the element tag, that it shoud hang to (and which holds all the settings).
|
55
|
-
constructor: (element) ->
|
56
|
-
@_tag = $(element)
|
57
|
-
@_action = @_tag.attr('data-action')
|
58
|
-
@_url = @_tag.attr('data-url')
|
59
|
-
@_text_field = @_tag.children('.text_field')
|
60
|
-
@_value_field = @_tag.children('.value_field')
|
61
|
-
|
62
|
-
@_text_field.keyup @text_field_keyup
|
63
|
-
@_text_field.click => @_text_field.select()
|
64
|
-
@_text_field.focus => @_focus = 'text_field'
|
65
|
-
@_text_field.blur @controls_blur
|
66
|
-
@_tag.children('.dropdown_button').click @dropdown_button_click
|
67
|
-
|
68
|
-
@_is_filled = @_value_field.val()!=''
|
69
|
-
|
70
|
-
########################## E V E N T S ##############################################
|
71
|
-
|
72
|
-
# Catchs ever key pressed to send a request only after the last one (applying 700ms timeout).
|
73
|
-
text_field_keyup: (e) =>
|
74
|
-
if e.keyCode==40 #down
|
75
|
-
return
|
76
|
-
else if e.keyCode==27 #escape
|
77
|
-
@removeList()
|
78
|
-
return
|
79
|
-
input = @_text_field.val()
|
80
|
-
clearTimeout(@_timeout) if @_timeout
|
81
|
-
@setUnfilled() if input!=@_last_input && @_is_filled
|
82
|
-
if input==''
|
83
|
-
@_last_input = input
|
84
|
-
@removeList()
|
85
|
-
else
|
86
|
-
fnc = => @getList(input)
|
87
|
-
@_timeout = setTimeout(fnc, 700)
|
88
|
-
|
89
|
-
# A 'button' to show the whole menu list (like entering an empty input).
|
90
|
-
dropdown_button_click: =>
|
91
|
-
hold_last = @_last_input
|
92
|
-
@_last_input = '§'
|
93
|
-
if @_is_filled
|
94
|
-
@getList('', true)
|
95
|
-
@_last_input = hold_last
|
96
|
-
else
|
97
|
-
@getList(@_text_field.val(), true)
|
98
|
-
|
99
|
-
# Called by both text_field and list, to ensure that if focused anything else, the list hides itself.
|
100
|
-
controls_blur: =>
|
101
|
-
@_focus = null
|
102
|
-
setTimeout( =>
|
103
|
-
@removeList() unless @_focus
|
104
|
-
,100)
|
105
|
-
|
106
|
-
########################## L I S T ################################################
|
107
|
-
|
108
|
-
# An Ajax request sent to a server for given url with given action and input as params.
|
109
|
-
# Fires only if input changed. Before the request it visualy deactivates the list, hides it on error.
|
110
|
-
# If success, attaches the list and fires onShow callback, if defined.
|
111
|
-
getList: (input, focus=false, onShown=null) =>
|
112
|
-
return if input==@_last_input
|
113
|
-
@_last_input = input
|
114
|
-
@deactivateList()
|
115
|
-
document.AssocWhispering.working = true;
|
116
|
-
$.ajax(@_tag.attr('data-url'),
|
117
|
-
type: 'GET'
|
118
|
-
dataType: 'html'
|
119
|
-
data: {data_action: @_tag.attr('data-action'), input: input}
|
120
|
-
error: @removeList
|
121
|
-
success: (data) =>
|
122
|
-
@showList(data)
|
123
|
-
@_list_tag.focus() if focus
|
124
|
-
onShown() if onShown
|
125
|
-
document.AssocWhispering.working = false;
|
126
|
-
)
|
127
|
-
|
128
|
-
# Attaches a list to html document, within the Whisperer's tag and sets its position to be under the input text field.
|
129
|
-
showList: (data) =>
|
130
|
-
@removeList()
|
131
|
-
@_list_tag = $(data)
|
132
|
-
@_list_tag.css('min-width', @_tag.width())
|
133
|
-
@_list_tag.css('left', @_tag.offset().left)
|
134
|
-
@_list_tag.css('top', @_tag.position().top + @_tag.outerHeight())
|
135
|
-
|
136
|
-
@_tag.append(@_list_tag)
|
137
|
-
@_list_tag.focus => @_focus = 'list'
|
138
|
-
@_list_tag.blur @controls_blur
|
139
|
-
|
140
|
-
rows = @_list_tag.find('div')
|
141
|
-
rows.click (el) => @select($(el.currentTarget))
|
142
|
-
|
143
|
-
# Adds a class 'inactive' to list to make it visualy distinguishable.
|
144
|
-
deactivateList: =>
|
145
|
-
return unless @_list_tag
|
146
|
-
@_list_tag.addClass('inactive')
|
147
|
-
|
148
|
-
# Detaches list from html, ie. hides it.
|
149
|
-
removeList: =>
|
150
|
-
return unless @_list_tag
|
151
|
-
@_list_tag.detach()
|
152
|
-
@_list_tag = null
|
153
|
-
|
154
|
-
########################## S E L E C T I O N ############################################
|
155
|
-
|
156
|
-
# Selects given row and sets its value to the hidden value field and removes the list.
|
157
|
-
select: (row) =>
|
158
|
-
return unless row.length==1
|
159
|
-
text = row.text()
|
160
|
-
@_text_field.val(text)
|
161
|
-
@_value_field.val(row.attr('data-value'))
|
162
|
-
@_last_input = text
|
163
|
-
@_is_filled = true
|
164
|
-
@_text_field.removeClass('unfilled')
|
165
|
-
@removeList()
|
166
|
-
|
167
|
-
# Selects row by given value.
|
168
|
-
selectValue: (value) =>
|
169
|
-
@select(@_list_tag.find('div[data-value='+value+']'))
|
170
|
-
|
171
|
-
# Selects row by given text label.
|
172
|
-
selectText: (text) =>
|
173
|
-
@select(@_list_tag.find('div:contains("'+text+'")'))
|
174
|
-
|
175
|
-
# Sets Whisperer to 'unfilled' state - no value has been selected (applies css class 'unfilled').
|
176
|
-
setUnfilled: =>
|
177
|
-
@_is_filled = false
|
178
|
-
@_value_field.val('')
|
179
|
-
@_text_field.addClass('unfilled')
|