recordselect_vho 3.0.3 → 3.0.204

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.
@@ -24,6 +24,10 @@ module RecordSelect
24
24
  # define any association includes you want for the finder search.
25
25
  def record_select_includes; end
26
26
 
27
+ def record_select_like_operator
28
+ @like_operator ||= ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" ? "ILIKE" : "LIKE"
29
+ end
30
+
27
31
  # generate conditions from params[:search]
28
32
  # override this if you want to customize the search routine
29
33
  def record_select_conditions_from_search
@@ -37,11 +41,11 @@ module RecordSelect
37
41
  tokens << params[:search].strip
38
42
  end
39
43
 
40
- where_clauses = record_select_config.search_on.collect { |sql| "#{sql} LIKE ?" }
44
+ where_clauses = record_select_config.search_on.collect { |sql| "#{sql} #{record_select_like_operator} ?" }
41
45
  phrase = "(#{where_clauses.join(' OR ')})"
42
46
 
43
47
  sql = ([phrase] * tokens.length).join(' AND ')
44
- tokens = tokens.collect{ |value| [search_pattern.sub('?', value.downcase)] * record_select_config.search_on.length }.flatten
48
+ tokens = tokens.collect{ |value| [search_pattern.sub('?', value)] * record_select_config.search_on.length }.flatten
45
49
 
46
50
  conditions = [sql, *tokens]
47
51
  end
@@ -94,13 +94,16 @@ module RecordSelectHelper
94
94
 
95
95
  controller = assert_controller_responds(options[:controller])
96
96
 
97
+ # js identifier so we can talk to it.
98
+ widget = "rs_%s" % name.gsub(/[\[\]]/, '_').chomp('_')
99
+
97
100
  current = current.inject([]) { |memo, record| memo.push({:id => record.id, :label => label_for_field(record, controller)}) }
98
101
 
99
102
  url = url_for({:action => :browse, :controller => options[:controller], :escape => false}.merge(options[:params]))
100
103
 
101
104
  html = text_field_tag("#{name}[]", nil, :autocomplete => 'off', :id => options[:id], :class => options[:class], :onfocus => "this.focused=true", :onblur => "this.focused=false")
102
105
  html << content_tag('ul', '', :class => 'record-select-list');
103
- html << javascript_tag("new RecordSelect.Multiple(#{options[:id].to_json}, #{url.to_json}, {current: #{current.to_json}});")
106
+ html << javascript_tag("#{widget} = new RecordSelect.Multiple(#{options[:id].to_json}, #{url.to_json}, {current: #{current.to_json}});")
104
107
 
105
108
  return html
106
109
  end
@@ -2,7 +2,7 @@ module RecordSelect
2
2
  module Version
3
3
  MAJOR = 3
4
4
  MINOR = 0
5
- PATCH = 3
5
+ PATCH = 204
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  end
metadata CHANGED
@@ -1,28 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: recordselect_vho
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1
5
- prerelease: false
4
+ hash: 415
5
+ prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 3
10
- version: 3.0.3
9
+ - 204
10
+ version: 3.0.204
11
11
  platform: ruby
12
12
  authors:
13
+ - Sergio Cambra
13
14
  - Volker Hochstein
14
15
  - Lance Ivy
15
16
  autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2011-02-03 00:00:00 +01:00
20
- default_executable:
20
+ date: 2013-01-26 00:00:00 Z
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
- prerelease: false
24
- name: shoulda
25
- version_requirements: &id001 !ruby/object:Gem::Requirement
23
+ requirement: &id001 !ruby/object:Gem::Requirement
26
24
  none: false
27
25
  requirements:
28
26
  - - ">="
@@ -31,12 +29,12 @@ dependencies:
31
29
  segments:
32
30
  - 0
33
31
  version: "0"
34
- requirement: *id001
35
32
  type: :development
36
- - !ruby/object:Gem::Dependency
33
+ name: shoulda
34
+ version_requirements: *id001
37
35
  prerelease: false
38
- name: bundler
39
- version_requirements: &id002 !ruby/object:Gem::Requirement
36
+ - !ruby/object:Gem::Dependency
37
+ requirement: &id002 !ruby/object:Gem::Requirement
40
38
  none: false
41
39
  requirements:
42
40
  - - ~>
@@ -47,28 +45,12 @@ dependencies:
47
45
  - 0
48
46
  - 0
49
47
  version: 1.0.0
50
- requirement: *id002
51
48
  type: :development
52
- - !ruby/object:Gem::Dependency
49
+ name: bundler
50
+ version_requirements: *id002
53
51
  prerelease: false
54
- name: jeweler
55
- version_requirements: &id003 !ruby/object:Gem::Requirement
56
- none: false
57
- requirements:
58
- - - ~>
59
- - !ruby/object:Gem::Version
60
- hash: 7
61
- segments:
62
- - 1
63
- - 5
64
- - 2
65
- version: 1.5.2
66
- requirement: *id003
67
- type: :development
68
52
  - !ruby/object:Gem::Dependency
69
- prerelease: false
70
- name: rcov
71
- version_requirements: &id004 !ruby/object:Gem::Requirement
53
+ requirement: &id003 !ruby/object:Gem::Requirement
72
54
  none: false
73
55
  requirements:
74
56
  - - ">="
@@ -77,24 +59,26 @@ dependencies:
77
59
  segments:
78
60
  - 0
79
61
  version: "0"
80
- requirement: *id004
81
62
  type: :development
82
- - !ruby/object:Gem::Dependency
63
+ name: rcov
64
+ version_requirements: *id003
83
65
  prerelease: false
84
- name: rails
85
- version_requirements: &id005 !ruby/object:Gem::Requirement
66
+ - !ruby/object:Gem::Dependency
67
+ requirement: &id004 !ruby/object:Gem::Requirement
86
68
  none: false
87
69
  requirements:
88
- - - ~>
70
+ - - ">="
89
71
  - !ruby/object:Gem::Version
90
- hash: 7
72
+ hash: 3
91
73
  segments:
92
74
  - 3
75
+ - 1
93
76
  - 0
94
- - 0
95
- version: 3.0.0
96
- requirement: *id005
77
+ version: 3.1.0
97
78
  type: :runtime
79
+ name: rails
80
+ version_requirements: *id004
81
+ prerelease: false
98
82
  description: RecordSelect is a Rails widget to help you pick one record out of many. I designed it as a more usable and performant alternative to generating a massive dropdown list
99
83
  email: activescaffold@googlegroups.com
100
84
  executables: []
@@ -104,41 +88,27 @@ extensions: []
104
88
  extra_rdoc_files:
105
89
  - README
106
90
  files:
107
- - .document
108
- - CHANGELOG
109
- - Gemfile
110
- - MIT-LICENSE
111
- - README
112
- - Rakefile
113
- - app/views/record_select/_browse.html.erb
114
91
  - app/views/record_select/_list.html.erb
115
- - app/views/record_select/_search.html.erb
116
92
  - app/views/record_select/browse.js.rjs
117
- - assets/images/cross.gif
118
- - assets/images/next.gif
119
- - assets/images/previous.gif
120
- - assets/javascripts/jquery/record_select.js
121
- - assets/javascripts/prototype/record_select.js
122
- - assets/stylesheets/record_select.css
123
- - init.rb
124
- - install.rb
125
- - lib/record_select.rb
126
- - lib/record_select/actions.rb
127
- - lib/record_select/conditions.rb
128
- - lib/record_select/config.rb
129
- - lib/record_select/extensions/active_record.rb
93
+ - app/views/record_select/_search.html.erb
94
+ - app/views/record_select/_browse.html.erb
95
+ - lib/recordselect_vho.rb
96
+ - lib/recordselect.rb
97
+ - lib/record_select/version.rb
98
+ - lib/record_select/helpers/record_select_helper.rb
130
99
  - lib/record_select/extensions/localization.rb
131
100
  - lib/record_select/extensions/routing_mapper.rb
101
+ - lib/record_select/extensions/active_record.rb
102
+ - lib/record_select/config.rb
103
+ - lib/record_select/actions.rb
104
+ - lib/record_select/conditions.rb
132
105
  - lib/record_select/form_builder.rb
133
- - lib/record_select/helpers/record_select_helper.rb
134
- - lib/record_select/version.rb
135
106
  - lib/record_select_assets.rb
136
- - lib/recordselect.rb
137
- - lib/recordselect_vho.rb
138
- - recordselect_vho.gemspec
107
+ - lib/record_select.rb
108
+ - MIT-LICENSE
109
+ - CHANGELOG
110
+ - README
139
111
  - test/recordselect_test.rb
140
- - uninstall.rb
141
- has_rdoc: true
142
112
  homepage: http://github.com/vhochstein/recordselect
143
113
  licenses:
144
114
  - MIT
@@ -168,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
138
  requirements: []
169
139
 
170
140
  rubyforge_project:
171
- rubygems_version: 1.3.7
141
+ rubygems_version: 1.8.17
172
142
  signing_key:
173
143
  specification_version: 3
174
144
  summary: RecordSelect widget as a replacement for massive drop down lists
data/.document DELETED
@@ -1,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- MIT-LICENSE
data/Gemfile DELETED
@@ -1,13 +0,0 @@
1
- source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
-
6
- # Add dependencies to develop your gem here.
7
- # Include everything needed to run rake, tests, features, etc.
8
- group :development do
9
- gem "shoulda", ">= 0"
10
- gem "bundler", "~> 1.0.0"
11
- gem "jeweler", "~> 1.5.2"
12
- gem "rcov", ">= 0"
13
- end
data/Rakefile DELETED
@@ -1,50 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- require './lib/record_select/version.rb'
14
- Jeweler::Tasks.new do |gem|
15
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
16
- gem.name = "recordselect_vho"
17
- gem.version = RecordSelect::Version::STRING
18
- gem.homepage = "http://github.com/vhochstein/recordselect"
19
- gem.license = "MIT"
20
- gem.summary = %Q{RecordSelect widget as a replacement for massive drop down lists}
21
- gem.description = %Q{RecordSelect is a Rails widget to help you pick one record out of many. I designed it as a more usable and performant alternative to generating a massive dropdown list}
22
- gem.email = "activescaffold@googlegroups.com"
23
- gem.authors = ["Volker Hochstein", "Lance Ivy"]
24
- gem.add_runtime_dependency 'rails', '~> 3.0.0'
25
- # Include your dependencies below. Runtime dependencies are required when using your gem,
26
- # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
27
- # gem.add_runtime_dependency 'jabber4r', '> 0.1'
28
- # gem.add_development_dependency 'rspec', '> 1.2.3'
29
- end
30
- Jeweler::RubygemsDotOrgTasks.new
31
-
32
- require 'rake/testtask'
33
- Rake::TestTask.new(:test) do |test|
34
- test.libs << 'lib' << 'test'
35
- test.pattern = 'test/**/test_*.rb'
36
- test.verbose = true
37
- end
38
-
39
- require 'rake/rdoctask'
40
- desc 'Generate documentation for the recordselect plugin.'
41
- Rake::RDocTask.new(:rdoc) do |rdoc|
42
- rdoc.rdoc_dir = 'rdoc'
43
- rdoc.title = "Recordselect #{RecordSelect::Version::STRING}"
44
- rdoc.options << '--line-numbers' << '--inline-source'
45
- rdoc.rdoc_files.include('README')
46
- rdoc.rdoc_files.include('lib/**/*.rb')
47
- rdoc.rdoc_files.include('assets/**/*.js')
48
- end
49
-
50
- task :default => :test
Binary file
Binary file
Binary file
@@ -1,499 +0,0 @@
1
- if (typeof(Class) === 'undefined') {
2
- /* Simple Inheritance
3
- http://ejohn.org/blog/simple-javascript-inheritance/
4
- */
5
- (function(){
6
- var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
7
-
8
- // The base Class implementation (does nothing)
9
- this.Class = function(){};
10
-
11
- // Create a new Class that inherits from this class
12
- Class.extend = function(prop) {
13
- var _super = this.prototype;
14
-
15
- // Instantiate a base class (but only create the instance,
16
- // don't run the init constructor)
17
- initializing = true;
18
- var prototype = new this();
19
- initializing = false;
20
-
21
- // Copy the properties over onto the new prototype
22
- for (var name in prop) {
23
- // Check if we're overwriting an existing function
24
- prototype[name] = typeof prop[name] == "function" &&
25
- typeof _super[name] == "function" && fnTest.test(prop[name]) ?
26
- (function(name, fn){
27
- return function() {
28
- var tmp = this._super;
29
-
30
- // Add a new ._super() method that is the same method
31
- // but on the super-class
32
- this._super = _super[name];
33
-
34
- // The method only need to be bound temporarily, so we
35
- // remove it when we're done executing
36
- var ret = fn.apply(this, arguments);
37
- this._super = tmp;
38
-
39
- return ret;
40
- };
41
- })(name, prop[name]) :
42
- prop[name];
43
- }
44
-
45
- // The dummy class constructor
46
- function Class() {
47
- // All construction is actually done in the init method
48
- if ( !initializing && this.init )
49
- this.init.apply(this, arguments);
50
- }
51
-
52
- // Populate our constructed prototype object
53
- Class.prototype = prototype;
54
-
55
- // Enforce the constructor to be what we expect
56
- Class.constructor = Class;
57
-
58
- // And make this class extendable
59
- Class.extend = arguments.callee;
60
-
61
- return Class;
62
- };
63
- })();
64
- };
65
-
66
- /*
67
- jQuery delayed observer
68
- (c) 2007 - Maxime Haineault (max@centdessin.com)
69
-
70
- Special thanks to Stephen Goguen & Tane Piper.
71
-
72
- Slight modifications by Elliot Winkler
73
- */
74
-
75
- if (typeof(jQuery.fn.delayedObserver) === 'undefined') {
76
- (function() {
77
- var delayedObserverStack = [];
78
- var observed;
79
-
80
- function delayedObserverCallback(stackPos) {
81
- observed = delayedObserverStack[stackPos];
82
- if (observed.timer) return;
83
-
84
- observed.timer = setTimeout(function(){
85
- observed.timer = null;
86
- observed.callback(observed.obj.val(), observed.obj);
87
- }, observed.delay * 1000);
88
-
89
- observed.oldVal = observed.obj.val();
90
- }
91
-
92
- // going by
93
- // <http://www.cambiaresearch.com/c4/702b8cd1-e5b0-42e6-83ac-25f0306e3e25/Javascript-Char-Codes-Key-Codes.aspx>
94
- // I think these codes only work when using keyup or keydown
95
- function isNonPrintableKey(event) {
96
- var code = event.keyCode;
97
- return (
98
- event.metaKey ||
99
- (code >= 9 || code <= 16) || (code >= 27 && code <= 40) || (code >= 91 && code <= 93) || (code >= 112 && code <= 145)
100
- );
101
- }
102
-
103
- jQuery.fn.extend({
104
- delayedObserver:function(delay, callback){
105
- $this = $(this);
106
-
107
- delayedObserverStack.push({
108
- obj: $this, timer: null, delay: delay,
109
- oldVal: $this.val(), callback: callback
110
- });
111
-
112
- stackPos = delayedObserverStack.length-1;
113
-
114
- $this.keyup(function(event) {
115
- if (isNonPrintableKey(event)) return;
116
- observed = delayedObserverStack[stackPos];
117
- if (observed.obj.val() == observed.obj.oldVal) return;
118
- else delayedObserverCallback(stackPos);
119
- });
120
- }
121
- });
122
- })();
123
- };
124
-
125
- $(document).ready(function() {
126
- RecordSelect.document_loaded = true;
127
- $('div.record-select * li.record a').live('ajax:before', function(event) {
128
- var link = $(this);
129
- if (link) {
130
- if (RecordSelect.notify(link) == false) {
131
- return false;
132
- } else {
133
- link.toggleClass("selected");
134
- }
135
- }
136
- return true;
137
- });
138
- });
139
-
140
- /**
141
- Form.Element.AfterActivity = function(element, callback, delay) {
142
- element = $(element);
143
- if (!delay) delay = 0.25;
144
- new Form.Element.Observer(element, delay, function(element, value) {
145
- // TODO: display loading indicator
146
- if (element.activity_timer) clearTimeout(element.activity_timer);
147
- element.activity_timer = setTimeout(function() {
148
- callback(element.value);
149
- }, delay * 1000 + 50);
150
- });
151
- }
152
- */
153
-
154
- var RecordSelect = new Object();
155
- RecordSelect.document_loaded = false;
156
-
157
- RecordSelect.notify = function(item) {
158
- var e = item.closest('.record-select-handler');
159
- var onselect = e.get(0).onselect || e.attr('onselect');
160
- if (typeof onselect != 'function') onselect = eval(onselect);
161
- if (onselect)
162
- {
163
- try {
164
- // .unescapeHTML() not implemented so far
165
- var label = $.trim(item.find('label').first().html());
166
- if (label.length == 0) {
167
- label = item.html();
168
- }
169
- onselect(item.parent().attr('id').substr(2), label, e);
170
- } catch(e) {
171
- alert(e);
172
- }
173
- return false;
174
- }
175
- else return true;
176
- }
177
-
178
- RecordSelect.render_page = function(record_select_id, page) {
179
- $('#' + record_select_id + ' ol').first().replaceWith(page);
180
- };
181
-
182
- RecordSelect.Abstract = Class.extend({
183
- /**
184
- * obj - the id or element that will anchor the recordselect to the page
185
- * url - the url to run the recordselect
186
- * options - ??? (check concrete classes)
187
- */
188
- init: function(obj, url, options) {
189
- if (typeof(obj) == 'string') obj = '#' + obj;
190
- this.obj = $(obj);
191
- this.url = url;
192
- this.options = options;
193
- this.container;
194
-
195
- if (RecordSelect.document_loaded) {
196
- this.onload();
197
- } else {
198
- var _this = this; $(document).ready(function() { _this.onload(); })
199
- }
200
- },
201
-
202
- /**
203
- * Finish the setup - IE doesn't like doing certain things before the page loads
204
- * --override--
205
- */
206
- onload: function() {},
207
-
208
- /**
209
- * the onselect event handler - when someone clicks on a record
210
- * --override--
211
- */
212
- onselect: function(id, value) {
213
- alert(id + ': ' + value);
214
- },
215
-
216
- /**
217
- * opens the recordselect
218
- */
219
- open: function() {
220
- if (this.is_open()) return;
221
- var _this = this;
222
- $.ajax({
223
- url: this.url,
224
- //type: "POST",
225
- //data: options['params'],
226
- //dataType: options.ajax_data_type,
227
- success: function(data){
228
- _this.container.html(data);
229
- _this.show();
230
- $(document.body).mousedown(jQuery.proxy(_this, "onbodyclick"));
231
- }
232
- });
233
- },
234
-
235
- /**
236
- * positions and reveals the recordselect
237
- */
238
- show: function() {
239
- var offset = this.obj.offset();
240
- this.container.css('left', offset.left)
241
- .css('top', (this.obj.height() + offset.top));
242
-
243
- if (this._use_iframe_mask()) {
244
- this.container.after('<iframe src="javascript:false;" class="record-select-mask" />');
245
- var mask = this.container.next('iframe');
246
- mask.css('left', this.container.css('left'))
247
- .css('top', this.container.css('top'));
248
- }
249
-
250
- this.container.show();
251
-
252
- if (this._use_iframe_mask()) {
253
- var dimensions = this.container.children().first();
254
- mask.css('width', dimensions.css('width'))
255
- .css('height', dimensions.css('height'));
256
- }
257
- },
258
-
259
- /**
260
- * closes the recordselect by emptying the container
261
- */
262
- close: function() {
263
- if (this._use_iframe_mask()) {
264
- this.container.next('iframe').remove();
265
- }
266
-
267
- this.container.hide();
268
- // hopefully by using remove() instead of innerHTML we won't leak memory
269
- this.container.children().remove();
270
- },
271
-
272
- /**
273
- * returns true/false for whether the recordselect is open
274
- */
275
- is_open: function() {
276
- return (!($.trim(this.container.html()).length == 0))
277
- },
278
-
279
- /**
280
- * when the user clicks outside the dropdown
281
- */
282
- onbodyclick: function(event) {
283
- if (!this.is_open()) return;
284
- if (this.container.has($(event.target)).length > 0) {
285
- return;
286
- } else {
287
- this.close();
288
- }
289
- },
290
-
291
- /**
292
- * creates and initializes (and returns) the recordselect container
293
- */
294
- create_container: function() {
295
- var e = $("<div />", {'class': "record-select-container record-select-handler"});
296
- e.css('display', 'none')
297
- $(document.body).append(e);
298
- e.get(0).onselect = $.proxy(this, "onselect")
299
- return e;
300
- },
301
-
302
- onkeyup: function(event) {
303
- if (!this.is_open()) return;
304
- this.container.find('.text-input').val(this.obj.val()).trigger(event);
305
- },
306
-
307
- /**
308
- * all the behavior to respond to a text field as a search box
309
- */
310
- _respond_to_text_field: function(text_field) {
311
- // attach the events to start this party
312
- text_field.focus($.proxy(this, 'open'));
313
-
314
- // the autosearch event - needs to happen slightly late (keyup is later than keypress)
315
- text_field.keyup($.proxy(this, 'onkeyup'));
316
-
317
- // keyboard navigation, if available
318
- if (this.onkeypress) {
319
- text_field.keypress($.proxy(this, "onkeypress"));
320
- }
321
- },
322
-
323
- _use_iframe_mask: function() {
324
- return this.container.insertAdjacentHTML ? true : false;
325
- }
326
- });
327
-
328
-
329
-
330
- /**
331
- * Adds keyboard navigation to RecordSelect objects
332
- */
333
- $.extend(RecordSelect.Abstract.prototype, {
334
- current: null,
335
-
336
- /**
337
- * keyboard navigation - where to intercept the keys is up to the concrete class
338
- */
339
- onkeypress: function(ev) {
340
- var elem;
341
- switch (ev.keyCode) {
342
- case 38: //Event.KEY_UP
343
- if (this.current && this.current.closest('.record-select')) elem = this.current.prev();
344
- if (!elem) elem = this.container.find('ol li.record').last();
345
- this.highlight(elem);
346
- break;
347
- case 40: //Event.KEY_DOWN
348
- if (this.current && this.current.closest('.record-select')) elem = this.current.next();
349
- if (!elem) elem = this.container.find('ol li.record').first();
350
- this.highlight(elem);
351
- break;
352
- case 13: // Event.KEY_RETURN
353
- if (this.current) this.current.find('a').click();
354
- break;
355
- case 39: // Event.KEY_RIGHT
356
- elem = this.container.find('li.pagination.next');
357
- if (elem) elem.find('a').click();
358
- break;
359
- case 37: // Event.KEY_LEFT
360
- elem = this.container.find('li.pagination.previous');
361
- if (elem) elem.find('a').click();
362
- break;
363
- case 27: // Event.KEY_ESC
364
- this.close();
365
- break;
366
- default:
367
- return true;
368
- }
369
- ev.preventDefault(); // so "enter" doesn't submit the form, among other things(?)
370
- },
371
-
372
- /**
373
- * moves the highlight to a new object
374
- */
375
- highlight: function(obj) {
376
- if (this.current) this.current.removeClass('current');
377
- this.current = $(obj);
378
- obj.addClass('current');
379
- }
380
- });
381
-
382
- /**
383
- * Used by link_to_record_select
384
- * The options hash should contain a onselect: key, with a javascript function as value
385
- */
386
- RecordSelect.Dialog = RecordSelect.Abstract.extend({
387
- onload: function() {
388
- this.container = this.create_container();
389
- this.obj.click($.proxy(this, "toggle"));
390
- if (this.onkeypress) this.obj.keypress($.proxy(this, 'onkeypress'));
391
- },
392
-
393
- onselect: function(id, value) {
394
- if (this.options.onselect(id, value) != false) this.close();
395
- },
396
-
397
- toggle: function() {
398
- if (this.is_open()) this.close();
399
- else this.open();
400
- }
401
- });
402
-
403
- /**
404
- * Used by record_select_field helper
405
- * The options hash may contain id: and label: keys, designating the current value
406
- * The options hash may also include an onchange: key, where the value is a javascript function (or eval-able string) for an callback routine.
407
- */
408
- RecordSelect.Single = RecordSelect.Abstract.extend({
409
- onload: function() {
410
- // initialize the container
411
- this.container = this.create_container();
412
- this.container.addClass('record-select-autocomplete');
413
-
414
- // create the hidden input
415
- this.obj.after('<input type="hidden" name="" value="" />');
416
- this.hidden_input = this.obj.next();
417
-
418
- // transfer the input name from the text input to the hidden input
419
- this.hidden_input.attr('name', this.obj.attr('name'));
420
- this.obj.attr('name', '');
421
-
422
- // initialize the values
423
- this.set(this.options.id, this.options.label);
424
-
425
- this._respond_to_text_field(this.obj);
426
- if (this.obj.focused) this.open(); // if it was focused before we could attach observers
427
- },
428
-
429
- close: function() {
430
- // if they close the dialog with the text field empty, then delete the id value
431
- if (this.obj.val() == '') this.set('', '');
432
-
433
- RecordSelect.Abstract.prototype.close.call(this);
434
- },
435
-
436
- onselect: function(id, value) {
437
- if (this.options.onchange) this.options.onchange(id, value);
438
- this.set(id, value);
439
- this.close();
440
- },
441
-
442
- /**
443
- * sets the id/label
444
- */
445
- set: function(id, label) {
446
- // unescaped html missing for label
447
- this.obj.val(label);
448
- this.hidden_input.val(id);
449
- }
450
- });
451
-
452
- /**
453
- * Used by record_multi_select_field helper.
454
- * Options:
455
- * list - the id (or object) of the <ul> to contain the <li>s of selected entries
456
- * current - an array of id:/label: keys designating the currently selected entries
457
- */
458
- RecordSelect.Multiple = RecordSelect.Abstract.extend({
459
- onload: function() {
460
- // initialize the container
461
- this.container = this.create_container();
462
- this.container.addClass('record-select-autocomplete');
463
-
464
- // decide where the <li> entries should be placed
465
- if (this.options.list) this.list_container = $(this.options.list);
466
- else this.list_container = this.obj.next('ul');
467
-
468
- // take the input name from the text input, and store it for this.add()
469
- this.input_name = this.obj.attr('name');
470
- this.obj.attr('name', '');
471
-
472
- // initialize the list
473
- for(var i = 0, length = this.options.current.length; i < length; i++) {
474
- this.add(this.options.current[i].id, this.options.current[i].label);
475
- }
476
-
477
- this._respond_to_text_field(this.obj);
478
- if (this.obj.focused) this.open(); // if it was focused before we could attach observers
479
- },
480
-
481
- onselect: function(id, value) {
482
- this.add(id, value);
483
- },
484
-
485
- /**
486
- * Adds a record to the selected list
487
- */
488
- add: function(id, label) {
489
- // return silently if this value has already been selected
490
- if (this.list_container.has('input[value=' + id + ']').length > 0) return;
491
-
492
- var entry = '<li>'
493
- + '<a href="#" onclick="$(this).parent().remove(); return false;" class="remove">remove</a>'
494
- + '<input type="hidden" name="' + this.input_name + '" value="' + id + '" />'
495
- + '<label>' + label + '</label>'
496
- + '</li>';
497
- this.list_container.prepend(entry)
498
- }
499
- });