chosen-rails 0.9.5

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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chosen-rails.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Tse-Ching Ho
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Chosen for rails asset pipeline
2
+
3
+ [Chosen](https://github.com/harvesthq/chosen) is a library for making long, unwieldy select boxes more user friendly.
4
+
5
+ The `chosen-rails` gem integrates the `Chosen` with the Rails asset pipeline.
6
+
7
+ ## Usage
8
+
9
+ ### Install chosen-rails gem
10
+
11
+ Include `chosen-rails` in Gemefile
12
+
13
+ gem 'chosen-rails'
14
+
15
+ Then run `bundle install`
16
+
17
+ ### Include chosen javascript assets
18
+
19
+ Add to your `app/assets/stylesheets/application.js` if use with jQuery
20
+
21
+ //= require chosen-jquery
22
+
23
+ Or with Prototype
24
+
25
+ //= require chosen-prototype
26
+
27
+ ### Include chosen stylesheet assets
28
+
29
+ Add to your `app/assets/stylesheets/application.css`
30
+
31
+ *= require chosen
32
+
33
+ ## Gem maintainance
34
+
35
+ Maintain `chosen-rails` gem with `Rake` commands.
36
+
37
+ Update origin chosen source files.
38
+
39
+ rake update-chosen
40
+
41
+ Publish gem.
42
+
43
+ rake release
44
+
45
+ ## License
46
+
47
+ use MIT license.
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "thor"
4
+
5
+ class SourceFile < Thor
6
+ include Thor::Actions
7
+
8
+ desc "fetch source files", "fetch source files from GitHub"
9
+ def fetch
10
+ self.destination_root = "vendor/assets"
11
+ remote = "https://github.com/harvesthq/chosen"
12
+ get "#{remote}/raw/master/chosen/chosen-sprite.png", "images/chosen-sprite.png"
13
+ get "#{remote}/raw/master/chosen/chosen.css", "stylesheets/chosen.css"
14
+ get "#{remote}/raw/master/coffee/lib/abstract-chosen.coffee", "javascripts/lib/abstract-chosen.coffee"
15
+ get "#{remote}/raw/master/coffee/lib/select-parser.coffee", "javascripts/lib/select-parser.coffee"
16
+ get "#{remote}/raw/master/coffee/chosen.jquery.coffee", "javascripts/chosen.jquery.coffee"
17
+ get "#{remote}/raw/master/coffee/chosen.proto.coffee", "javascripts/chosen.proto.coffee"
18
+ get "#{remote}/raw/master/VERSION", "VERSION"
19
+ inside destination_root do
20
+ version = File.read("VERSION").sub("\n", "")
21
+ gsub_file "../../lib/chosen-rails/version.rb", /VERSION\s=\s"(\d|\.)+"$/ do |match|
22
+ %Q{VERSION = "#{version}"}
23
+ end
24
+ end
25
+ end
26
+
27
+ desc "convert css to sass file", "convert css to sass file by sass-convert"
28
+ def convert
29
+ self.destination_root = "vendor/assets"
30
+ inside destination_root do
31
+ run("sass-convert -F css -T sass stylesheets/chosen.css stylesheets/chosen.css.sass")
32
+ end
33
+ end
34
+
35
+ desc "clean up useless files", "clean up useless files"
36
+ def cleanup
37
+ self.destination_root = "vendor/assets"
38
+ remove_file "stylesheets/chosen.css"
39
+ remove_file "VERSION"
40
+ end
41
+ end
42
+
43
+ desc "Update Harvest's Chosen Library"
44
+ task "update-chosen" do
45
+ files = SourceFile.new
46
+ files.fetch
47
+ files.convert
48
+ files.cleanup
49
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/chosen-rails/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Tse-Ching Ho"]
6
+ gem.email = ["tsechingho@gmail.com"]
7
+ gem.description = %q{Chosen is a javascript library of select box enhancer for jQuery and Protoype. This gem integrates Chosen with Rails asset pipeline for easy of use.}
8
+ gem.summary = %q{Integrate Chosen javascript library with Rails asset pipeline}
9
+ gem.homepage = "https://github.com/tsechingho/chosen-rails"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "chosen-rails"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Chosen::Rails::VERSION
17
+
18
+ gem.add_dependency "railties", "~> 3.0"
19
+ gem.add_dependency "thor", "~> 0.14"
20
+ gem.add_development_dependency "bundler", "~> 1.0"
21
+ gem.add_development_dependency "rails", "~> 3.0"
22
+ end
@@ -0,0 +1,11 @@
1
+ require "chosen-rails/version"
2
+
3
+ module Chosen
4
+ module Rails
5
+ if ::Rails.version < "3.1"
6
+ require "chosen-rails/railtie"
7
+ else
8
+ require "chosen-rails/engine"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module Chosen
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Chosen
2
+ module Rails
3
+ class Railtie < ::Rails::Railtie
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Chosen
2
+ module Rails
3
+ VERSION = "0.9.5"
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ //= require lib/abstract-chosen
2
+ //= require lib/select-parser
3
+ //= require chosen.jquery
@@ -0,0 +1,3 @@
1
+ //= require lib/abstract-chosen
2
+ //= require lib/select-parser
3
+ //= require chosen.proto
@@ -0,0 +1,550 @@
1
+ ###
2
+ Chosen source: generate output using 'cake build'
3
+ Copyright (c) 2011 by Harvest
4
+ ###
5
+ root = this
6
+ $ = jQuery
7
+
8
+ $.fn.extend({
9
+ chosen: (options) ->
10
+ # Do no harm and return as soon as possible for unsupported browsers, namely IE6 and IE7
11
+ return this if $.browser.msie and ($.browser.version is "6.0" or $.browser.version is "7.0")
12
+ $(this).each((input_field) ->
13
+ new Chosen(this, options) unless ($ this).hasClass "chzn-done"
14
+ )
15
+ })
16
+
17
+ class Chosen extends AbstractChosen
18
+
19
+ setup: ->
20
+ @form_field_jq = $ @form_field
21
+ @is_rtl = @form_field_jq.hasClass "chzn-rtl"
22
+
23
+ finish_setup: ->
24
+ @form_field_jq.addClass "chzn-done"
25
+
26
+ set_up_html: ->
27
+ @container_id = if @form_field.id.length then @form_field.id.replace(/(:|\.)/g, '_') else this.generate_field_id()
28
+ @container_id += "_chzn"
29
+
30
+ @f_width = @form_field_jq.outerWidth()
31
+
32
+ @default_text = if @form_field_jq.data 'placeholder' then @form_field_jq.data 'placeholder' else @default_text_default
33
+
34
+ container_div = ($ "<div />", {
35
+ id: @container_id
36
+ class: "chzn-container#{ if @is_rtl then ' chzn-rtl' else '' }"
37
+ style: 'width: ' + (@f_width) + 'px;' #use parens around @f_width so coffeescript doesn't think + ' px' is a function parameter
38
+ })
39
+
40
+ if @is_multiple
41
+ container_div.html '<ul class="chzn-choices"><li class="search-field"><input type="text" value="' + @default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'
42
+ else
43
+ container_div.html '<a href="javascript:void(0)" class="chzn-single"><span>' + @default_text + '</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'
44
+
45
+ @form_field_jq.hide().after container_div
46
+ @container = ($ '#' + @container_id)
47
+ @container.addClass( "chzn-container-" + (if @is_multiple then "multi" else "single") )
48
+ @dropdown = @container.find('div.chzn-drop').first()
49
+
50
+ dd_top = @container.height()
51
+ dd_width = (@f_width - get_side_border_padding(@dropdown))
52
+
53
+ @dropdown.css({"width": dd_width + "px", "top": dd_top + "px"})
54
+
55
+ @search_field = @container.find('input').first()
56
+ @search_results = @container.find('ul.chzn-results').first()
57
+ this.search_field_scale()
58
+
59
+ @search_no_results = @container.find('li.no-results').first()
60
+
61
+ if @is_multiple
62
+ @search_choices = @container.find('ul.chzn-choices').first()
63
+ @search_container = @container.find('li.search-field').first()
64
+ else
65
+ @search_container = @container.find('div.chzn-search').first()
66
+ @selected_item = @container.find('.chzn-single').first()
67
+ sf_width = dd_width - get_side_border_padding(@search_container) - get_side_border_padding(@search_field)
68
+ @search_field.css( {"width" : sf_width + "px"} )
69
+
70
+ this.results_build()
71
+ this.set_tab_index()
72
+ @form_field_jq.trigger("liszt:ready", {chosen: this})
73
+
74
+ register_observers: ->
75
+ @container.mousedown (evt) => this.container_mousedown(evt)
76
+ @container.mouseup (evt) => this.container_mouseup(evt)
77
+ @container.mouseenter (evt) => this.mouse_enter(evt)
78
+ @container.mouseleave (evt) => this.mouse_leave(evt)
79
+
80
+ @search_results.mouseup (evt) => this.search_results_mouseup(evt)
81
+ @search_results.mouseover (evt) => this.search_results_mouseover(evt)
82
+ @search_results.mouseout (evt) => this.search_results_mouseout(evt)
83
+
84
+ @form_field_jq.bind "liszt:updated", (evt) => this.results_update_field(evt)
85
+
86
+ @search_field.blur (evt) => this.input_blur(evt)
87
+ @search_field.keyup (evt) => this.keyup_checker(evt)
88
+ @search_field.keydown (evt) => this.keydown_checker(evt)
89
+
90
+ if @is_multiple
91
+ @search_choices.click (evt) => this.choices_click(evt)
92
+ @search_field.focus (evt) => this.input_focus(evt)
93
+
94
+ search_field_disabled: ->
95
+ @is_disabled = @form_field_jq[0].disabled
96
+ if(@is_disabled)
97
+ @container.addClass 'chzn-disabled'
98
+ @search_field[0].disabled = true
99
+ @selected_item.unbind "focus", @activate_action if !@is_multiple
100
+ this.close_field()
101
+ else
102
+ @container.removeClass 'chzn-disabled'
103
+ @search_field[0].disabled = false
104
+ @selected_item.bind "focus", @activate_action if !@is_multiple
105
+
106
+ container_mousedown: (evt) ->
107
+ if !@is_disabled
108
+ target_closelink = if evt? then ($ evt.target).hasClass "search-choice-close" else false
109
+ if evt and evt.type is "mousedown"
110
+ evt.stopPropagation()
111
+ if not @pending_destroy_click and not target_closelink
112
+ if not @active_field
113
+ @search_field.val "" if @is_multiple
114
+ $(document).click @click_test_action
115
+ this.results_show()
116
+ else if not @is_multiple and evt and (($(evt.target)[0] == @selected_item[0]) || $(evt.target).parents("a.chzn-single").length)
117
+ evt.preventDefault()
118
+ this.results_toggle()
119
+
120
+ this.activate_field()
121
+ else
122
+ @pending_destroy_click = false
123
+
124
+ container_mouseup: (evt) ->
125
+ this.results_reset(evt) if evt.target.nodeName is "ABBR"
126
+
127
+ blur_test: (evt) ->
128
+ this.close_field() if not @active_field and @container.hasClass "chzn-container-active"
129
+
130
+ close_field: ->
131
+ $(document).unbind "click", @click_test_action
132
+
133
+ if not @is_multiple
134
+ @selected_item.attr "tabindex", @search_field.attr("tabindex")
135
+ @search_field.attr "tabindex", -1
136
+
137
+ @active_field = false
138
+ this.results_hide()
139
+
140
+ @container.removeClass "chzn-container-active"
141
+ this.winnow_results_clear()
142
+ this.clear_backstroke()
143
+
144
+ this.show_search_field_default()
145
+ this.search_field_scale()
146
+
147
+ activate_field: ->
148
+ if not @is_multiple and not @active_field
149
+ @search_field.attr "tabindex", (@selected_item.attr "tabindex")
150
+ @selected_item.attr "tabindex", -1
151
+
152
+ @container.addClass "chzn-container-active"
153
+ @active_field = true
154
+
155
+ @search_field.val(@search_field.val())
156
+ @search_field.focus()
157
+
158
+
159
+ test_active_click: (evt) ->
160
+ if $(evt.target).parents('#' + @container_id).length
161
+ @active_field = true
162
+ else
163
+ this.close_field()
164
+
165
+ results_build: ->
166
+ @parsing = true
167
+ @results_data = root.SelectParser.select_to_array @form_field
168
+
169
+ if @is_multiple and @choices > 0
170
+ @search_choices.find("li.search-choice").remove()
171
+ @choices = 0
172
+ else if not @is_multiple
173
+ @selected_item.find("span").text @default_text
174
+ if @form_field.options.length <= @disable_search_threshold
175
+ @container.addClass "chzn-container-single-nosearch"
176
+ else
177
+ @container.removeClass "chzn-container-single-nosearch"
178
+
179
+ content = ''
180
+ for data in @results_data
181
+ if data.group
182
+ content += this.result_add_group data
183
+ else if !data.empty
184
+ content += this.result_add_option data
185
+ if data.selected and @is_multiple
186
+ this.choice_build data
187
+ else if data.selected and not @is_multiple
188
+ @selected_item.find("span").text data.text
189
+ this.single_deselect_control_build() if @allow_single_deselect
190
+
191
+ this.search_field_disabled()
192
+ this.show_search_field_default()
193
+ this.search_field_scale()
194
+
195
+ @search_results.html content
196
+ @parsing = false
197
+
198
+
199
+ result_add_group: (group) ->
200
+ if not group.disabled
201
+ group.dom_id = @container_id + "_g_" + group.array_index
202
+ '<li id="' + group.dom_id + '" class="group-result">' + $("<div />").text(group.label).html() + '</li>'
203
+ else
204
+ ""
205
+
206
+ result_do_highlight: (el) ->
207
+ if el.length
208
+ this.result_clear_highlight()
209
+
210
+ @result_highlight = el
211
+ @result_highlight.addClass "highlighted"
212
+
213
+ maxHeight = parseInt @search_results.css("maxHeight"), 10
214
+ visible_top = @search_results.scrollTop()
215
+ visible_bottom = maxHeight + visible_top
216
+
217
+ high_top = @result_highlight.position().top + @search_results.scrollTop()
218
+ high_bottom = high_top + @result_highlight.outerHeight()
219
+
220
+ if high_bottom >= visible_bottom
221
+ @search_results.scrollTop if (high_bottom - maxHeight) > 0 then (high_bottom - maxHeight) else 0
222
+ else if high_top < visible_top
223
+ @search_results.scrollTop high_top
224
+
225
+ result_clear_highlight: ->
226
+ @result_highlight.removeClass "highlighted" if @result_highlight
227
+ @result_highlight = null
228
+
229
+ results_show: ->
230
+ if not @is_multiple
231
+ @selected_item.addClass "chzn-single-with-drop"
232
+ if @result_single_selected
233
+ this.result_do_highlight( @result_single_selected )
234
+
235
+ dd_top = if @is_multiple then @container.height() else (@container.height() - 1)
236
+ @dropdown.css {"top": dd_top + "px", "left":0}
237
+ @results_showing = true
238
+
239
+ @search_field.focus()
240
+ @search_field.val @search_field.val()
241
+
242
+ this.winnow_results()
243
+
244
+ results_hide: ->
245
+ @selected_item.removeClass "chzn-single-with-drop" unless @is_multiple
246
+ this.result_clear_highlight()
247
+ @dropdown.css {"left":"-9000px"}
248
+ @results_showing = false
249
+
250
+
251
+ set_tab_index: (el) ->
252
+ if @form_field_jq.attr "tabindex"
253
+ ti = @form_field_jq.attr "tabindex"
254
+ @form_field_jq.attr "tabindex", -1
255
+
256
+ if @is_multiple
257
+ @search_field.attr "tabindex", ti
258
+ else
259
+ @selected_item.attr "tabindex", ti
260
+ @search_field.attr "tabindex", -1
261
+
262
+ show_search_field_default: ->
263
+ if @is_multiple and @choices < 1 and not @active_field
264
+ @search_field.val(@default_text)
265
+ @search_field.addClass "default"
266
+ else
267
+ @search_field.val("")
268
+ @search_field.removeClass "default"
269
+
270
+ search_results_mouseup: (evt) ->
271
+ target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first()
272
+ if target.length
273
+ @result_highlight = target
274
+ this.result_select(evt)
275
+
276
+ search_results_mouseover: (evt) ->
277
+ target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first()
278
+ this.result_do_highlight( target ) if target
279
+
280
+ search_results_mouseout: (evt) ->
281
+ this.result_clear_highlight() if $(evt.target).hasClass "active-result" or $(evt.target).parents('.active-result').first()
282
+
283
+
284
+ choices_click: (evt) ->
285
+ evt.preventDefault()
286
+ if( @active_field and not($(evt.target).hasClass "search-choice" or $(evt.target).parents('.search-choice').first) and not @results_showing )
287
+ this.results_show()
288
+
289
+ choice_build: (item) ->
290
+ choice_id = @container_id + "_c_" + item.array_index
291
+ @choices += 1
292
+ @search_container.before '<li class="search-choice" id="' + choice_id + '"><span>' + item.html + '</span><a href="javascript:void(0)" class="search-choice-close" rel="' + item.array_index + '"></a></li>'
293
+ link = $('#' + choice_id).find("a").first()
294
+ link.click (evt) => this.choice_destroy_link_click(evt)
295
+
296
+ choice_destroy_link_click: (evt) ->
297
+ evt.preventDefault()
298
+ if not @is_disabled
299
+ @pending_destroy_click = true
300
+ this.choice_destroy $(evt.target)
301
+ else
302
+ evt.stopPropagation
303
+
304
+ choice_destroy: (link) ->
305
+ @choices -= 1
306
+ this.show_search_field_default()
307
+
308
+ this.results_hide() if @is_multiple and @choices > 0 and @search_field.val().length < 1
309
+
310
+ this.result_deselect (link.attr "rel")
311
+ link.parents('li').first().remove()
312
+
313
+ results_reset: (evt) ->
314
+ @form_field.options[0].selected = true
315
+ @selected_item.find("span").text @default_text
316
+ this.show_search_field_default()
317
+ $(evt.target).remove();
318
+ @form_field_jq.trigger "change"
319
+ this.results_hide() if @active_field
320
+
321
+ result_select: (evt) ->
322
+ if @result_highlight
323
+ high = @result_highlight
324
+ high_id = high.attr "id"
325
+
326
+ this.result_clear_highlight()
327
+
328
+ if @is_multiple
329
+ this.result_deactivate high
330
+ else
331
+ @search_results.find(".result-selected").removeClass "result-selected"
332
+ @result_single_selected = high
333
+
334
+ high.addClass "result-selected"
335
+
336
+ position = high_id.substr(high_id.lastIndexOf("_") + 1 )
337
+ item = @results_data[position]
338
+ item.selected = true
339
+
340
+ @form_field.options[item.options_index].selected = true
341
+
342
+ if @is_multiple
343
+ this.choice_build item
344
+ else
345
+ @selected_item.find("span").first().text item.text
346
+ this.single_deselect_control_build() if @allow_single_deselect
347
+
348
+ this.results_hide() unless evt.metaKey and @is_multiple
349
+
350
+ @search_field.val ""
351
+
352
+ @form_field_jq.trigger "change"
353
+ this.search_field_scale()
354
+
355
+ result_activate: (el) ->
356
+ el.addClass("active-result")
357
+
358
+ result_deactivate: (el) ->
359
+ el.removeClass("active-result")
360
+
361
+ result_deselect: (pos) ->
362
+ result_data = @results_data[pos]
363
+ result_data.selected = false
364
+
365
+ @form_field.options[result_data.options_index].selected = false
366
+ result = $("#" + @container_id + "_o_" + pos)
367
+ result.removeClass("result-selected").addClass("active-result").show()
368
+
369
+ this.result_clear_highlight()
370
+ this.winnow_results()
371
+
372
+ @form_field_jq.trigger "change"
373
+ this.search_field_scale()
374
+
375
+ single_deselect_control_build: ->
376
+ @selected_item.find("span").first().after "<abbr class=\"search-choice-close\"></abbr>" if @allow_single_deselect and @selected_item.find("abbr").length < 1
377
+
378
+ winnow_results: ->
379
+ this.no_results_clear()
380
+
381
+ results = 0
382
+
383
+ searchText = if @search_field.val() is @default_text then "" else $('<div/>').text($.trim(@search_field.val())).html()
384
+ regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
385
+ zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
386
+
387
+ for option in @results_data
388
+ if not option.disabled and not option.empty
389
+ if option.group
390
+ $('#' + option.dom_id).css('display', 'none')
391
+ else if not (@is_multiple and option.selected)
392
+ found = false
393
+ result_id = option.dom_id
394
+ result = $("#" + result_id)
395
+
396
+ if regex.test option.html
397
+ found = true
398
+ results += 1
399
+ else if option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0
400
+ #TODO: replace this substitution of /\[\]/ with a list of characters to skip.
401
+ parts = option.html.replace(/\[|\]/g, "").split(" ")
402
+ if parts.length
403
+ for part in parts
404
+ if regex.test part
405
+ found = true
406
+ results += 1
407
+
408
+ if found
409
+ if searchText.length
410
+ startpos = option.html.search zregex
411
+ text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length)
412
+ text = text.substr(0, startpos) + '<em>' + text.substr(startpos)
413
+ else
414
+ text = option.html
415
+
416
+ result.html(text)
417
+ this.result_activate result
418
+
419
+ $("#" + @results_data[option.group_array_index].dom_id).css('display', 'list-item') if option.group_array_index?
420
+ else
421
+ this.result_clear_highlight() if @result_highlight and result_id is @result_highlight.attr 'id'
422
+ this.result_deactivate result
423
+
424
+ if results < 1 and searchText.length
425
+ this.no_results searchText
426
+ else
427
+ this.winnow_results_set_highlight()
428
+
429
+ winnow_results_clear: ->
430
+ @search_field.val ""
431
+ lis = @search_results.find("li")
432
+
433
+ for li in lis
434
+ li = $(li)
435
+ if li.hasClass "group-result"
436
+ li.css('display', 'auto')
437
+ else if not @is_multiple or not li.hasClass "result-selected"
438
+ this.result_activate li
439
+
440
+ winnow_results_set_highlight: ->
441
+ if not @result_highlight
442
+
443
+ selected_results = if not @is_multiple then @search_results.find(".result-selected.active-result") else []
444
+ do_high = if selected_results.length then selected_results.first() else @search_results.find(".active-result").first()
445
+
446
+ this.result_do_highlight do_high if do_high?
447
+
448
+ no_results: (terms) ->
449
+ no_results_html = $('<li class="no-results">' + @results_none_found + ' "<span></span>"</li>')
450
+ no_results_html.find("span").first().html(terms)
451
+
452
+ @search_results.append no_results_html
453
+
454
+ no_results_clear: ->
455
+ @search_results.find(".no-results").remove()
456
+
457
+ keydown_arrow: ->
458
+ if not @result_highlight
459
+ first_active = @search_results.find("li.active-result").first()
460
+ this.result_do_highlight $(first_active) if first_active
461
+ else if @results_showing
462
+ next_sib = @result_highlight.nextAll("li.active-result").first()
463
+ this.result_do_highlight next_sib if next_sib
464
+ this.results_show() if not @results_showing
465
+
466
+ keyup_arrow: ->
467
+ if not @results_showing and not @is_multiple
468
+ this.results_show()
469
+ else if @result_highlight
470
+ prev_sibs = @result_highlight.prevAll("li.active-result")
471
+
472
+ if prev_sibs.length
473
+ this.result_do_highlight prev_sibs.first()
474
+ else
475
+ this.results_hide() if @choices > 0
476
+ this.result_clear_highlight()
477
+
478
+ keydown_backstroke: ->
479
+ if @pending_backstroke
480
+ this.choice_destroy @pending_backstroke.find("a").first()
481
+ this.clear_backstroke()
482
+ else
483
+ @pending_backstroke = @search_container.siblings("li.search-choice").last()
484
+ @pending_backstroke.addClass "search-choice-focus"
485
+
486
+ clear_backstroke: ->
487
+ @pending_backstroke.removeClass "search-choice-focus" if @pending_backstroke
488
+ @pending_backstroke = null
489
+
490
+ keydown_checker: (evt) ->
491
+ stroke = evt.which ? evt.keyCode
492
+ this.search_field_scale()
493
+
494
+ this.clear_backstroke() if stroke != 8 and this.pending_backstroke
495
+
496
+ switch stroke
497
+ when 8
498
+ @backstroke_length = this.search_field.val().length
499
+ break
500
+ when 9
501
+ this.result_select(evt) if this.results_showing and not @is_multiple
502
+ @mouse_on_container = false
503
+ break
504
+ when 13
505
+ evt.preventDefault()
506
+ break
507
+ when 38
508
+ evt.preventDefault()
509
+ this.keyup_arrow()
510
+ break
511
+ when 40
512
+ this.keydown_arrow()
513
+ break
514
+
515
+ search_field_scale: ->
516
+ if @is_multiple
517
+ h = 0
518
+ w = 0
519
+
520
+ style_block = "position:absolute; left: -1000px; top: -1000px; display:none;"
521
+ styles = ['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing']
522
+
523
+ for style in styles
524
+ style_block += style + ":" + @search_field.css(style) + ";"
525
+
526
+ div = $('<div />', { 'style' : style_block })
527
+ div.text @search_field.val()
528
+ $('body').append div
529
+
530
+ w = div.width() + 25
531
+ div.remove()
532
+
533
+ if( w > @f_width-10 )
534
+ w = @f_width - 10
535
+
536
+ @search_field.css({'width': w + 'px'})
537
+
538
+ dd_top = @container.height()
539
+ @dropdown.css({"top": dd_top + "px"})
540
+
541
+ generate_random_id: ->
542
+ string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char()
543
+ while $("#" + string).length > 0
544
+ string += this.generate_random_char()
545
+ string
546
+
547
+ get_side_border_padding = (elmt) ->
548
+ side_border_padding = elmt.outerWidth() - elmt.width()
549
+
550
+ root.get_side_border_padding = get_side_border_padding