diff --git a/lib/chosen-rails/version.rb b/lib/chosen-rails/version.rb
index 99fc6ee..6cc0cce 100644
--- a/lib/chosen-rails/version.rb
+++ b/lib/chosen-rails/version.rb
@@ -1,6 +1,6 @@
module Chosen
module Rails
VERSION = '0.9.14'
- CHOSEN_VERSION = '0.9.14'
+ CHOSEN_VERSION = '0.9.15'
end
end
diff --git a/vendor/assets/javascripts/chosen.jquery.coffee b/vendor/assets/javascripts/chosen.jquery.coffee
index 0df0f2d..2b6f869 100644
--- a/vendor/assets/javascripts/chosen.jquery.coffee
+++ b/vendor/assets/javascripts/chosen.jquery.coffee
@@ -164,11 +164,12 @@ class Chosen extends AbstractChosen
results_build: ->
@parsing = true
+ @selected_option_count = null
+
@results_data = root.SelectParser.select_to_array @form_field
- if @is_multiple and @choices > 0
+ if @is_multiple and this.choices_count() > 0
@search_choices.find("li.search-choice").remove()
- @choices = 0
else if not @is_multiple
@selected_item.addClass("chzn-default").find("span").text(@default_text)
if @disable_search or @form_field.options.length <= @disable_search_threshold
@@ -229,7 +230,7 @@ class Chosen extends AbstractChosen
results_show: ->
if @result_single_selected?
this.result_do_highlight @result_single_selected
- else if @is_multiple and @max_selected_options <= @choices
+ else if @is_multiple and @max_selected_options <= this.choices_count()
@form_field_jq.trigger("liszt:maxselected", {chosen: this})
return false
@@ -261,13 +262,13 @@ class Chosen extends AbstractChosen
set_label_behavior: ->
@form_field_label = @form_field_jq.parents("label") # first check for a parent label
if not @form_field_label.length and @form_field.id.length
- @form_field_label = $("label[for=#{@form_field.id}]") #next check for a for=#{id}
+ @form_field_label = $("label[for='#{@form_field.id}']") #next check for a for=#{id}
if @form_field_label.length > 0
@form_field_label.click (evt) => if @is_multiple then this.container_mousedown(evt) else this.activate_field()
show_search_field_default: ->
- if @is_multiple and @choices < 1 and not @active_field
+ if @is_multiple and this.choices_count() < 1 and not @active_field
@search_field.val(@default_text)
@search_field.addClass "default"
else
@@ -289,18 +290,16 @@ class Chosen extends AbstractChosen
this.result_clear_highlight() if $(evt.target).hasClass "active-result" or $(evt.target).parents('.active-result').first()
choice_build: (item) ->
- if @is_multiple and @max_selected_options <= @choices
- @form_field_jq.trigger("liszt:maxselected", {chosen: this})
- return false # fire event
- choice_id = @container_id + "_c_" + item.array_index
- @choices += 1
+ choice = $('
', { class: "search-choice" }).html("#{item.html}")
+
if item.disabled
- html = '' + item.html + ''
+ choice.addClass 'search-choice-disabled'
else
- html = '' + item.html + ''
- @search_container.before html
- link = $('#' + choice_id).find("a").first()
- link.click (evt) => this.choice_destroy_link_click(evt)
+ close_link = $('', { href: '#', class: 'search-choice-close', rel: item.array_index })
+ close_link.click (evt) => this.choice_destroy_link_click(evt)
+ choice.append close_link
+
+ @search_container.before choice
choice_destroy_link_click: (evt) ->
evt.preventDefault()
@@ -309,10 +308,9 @@ class Chosen extends AbstractChosen
choice_destroy: (link) ->
if this.result_deselect (link.attr "rel")
- @choices -= 1
this.show_search_field_default()
- this.results_hide() if @is_multiple and @choices > 0 and @search_field.val().length < 1
+ this.results_hide() if @is_multiple and this.choices_count() > 0 and @search_field.val().length < 1
link.parents('li').first().remove()
@@ -320,6 +318,7 @@ class Chosen extends AbstractChosen
results_reset: ->
@form_field.options[0].selected = true
+ @selected_option_count = null
@selected_item.find("span").text @default_text
@selected_item.addClass("chzn-default") if not @is_multiple
this.show_search_field_default()
@@ -338,6 +337,10 @@ class Chosen extends AbstractChosen
this.result_clear_highlight()
+ if @is_multiple and @max_selected_options <= this.choices_count()
+ @form_field_jq.trigger("liszt:maxselected", {chosen: this})
+ return false
+
if @is_multiple
this.result_deactivate high
else
@@ -352,6 +355,7 @@ class Chosen extends AbstractChosen
item.selected = true
@form_field.options[item.options_index].selected = true
+ @selected_option_count = null
if @is_multiple
this.choice_build item
@@ -380,6 +384,8 @@ class Chosen extends AbstractChosen
result_data.selected = false
@form_field.options[result_data.options_index].selected = false
+ @selected_option_count = null
+
result = $("#" + @container_id + "_o_" + pos)
result.removeClass("result-selected").addClass("active-result").show()
@@ -494,7 +500,7 @@ class Chosen extends AbstractChosen
if prev_sibs.length
this.result_do_highlight prev_sibs.first()
else
- this.results_hide() if @choices > 0
+ this.results_hide() if this.choices_count() > 0
this.result_clear_highlight()
keydown_backstroke: ->
diff --git a/vendor/assets/javascripts/chosen.proto.coffee b/vendor/assets/javascripts/chosen.proto.coffee
index fa6d3f1..f5ef77e 100644
--- a/vendor/assets/javascripts/chosen.proto.coffee
+++ b/vendor/assets/javascripts/chosen.proto.coffee
@@ -19,8 +19,6 @@ class Chosen extends AbstractChosen
# HTML Templates
@single_temp = new Template('#{default}
')
@multi_temp = new Template('')
- @choice_temp = new Template('#{choice}')
- @choice_noclose_temp = new Template('#{choice}')
@no_results_temp = new Template('' + @results_none_found + ' "#{terms}"')
set_up_html: ->
@@ -154,11 +152,12 @@ class Chosen extends AbstractChosen
results_build: ->
@parsing = true
+ @selected_option_count = null
+
@results_data = root.SelectParser.select_to_array @form_field
- if @is_multiple and @choices > 0
+ if @is_multiple and this.choices_count() > 0
@search_choices.select("li.search-choice").invoke("remove")
- @choices = 0
else if not @is_multiple
@selected_item.addClassName("chzn-default").down("span").update(@default_text)
if @disable_search or @form_field.options.length <= @disable_search_threshold
@@ -203,7 +202,7 @@ class Chosen extends AbstractChosen
visible_top = @search_results.scrollTop
visible_bottom = maxHeight + visible_top
- high_top = @result_highlight.positionedOffset().top
+ high_top = @result_highlight.positionedOffset().top + @search_results.scrollTop
high_bottom = high_top + @result_highlight.getHeight()
if high_bottom >= visible_bottom
@@ -218,7 +217,7 @@ class Chosen extends AbstractChosen
results_show: ->
if @result_single_selected?
this.result_do_highlight @result_single_selected
- else if @is_multiple and @max_selected_options <= @choices
+ else if @is_multiple and @max_selected_options <= this.choices_count()
@form_field.fire("liszt:maxselected", {chosen: this})
return false
@@ -250,13 +249,13 @@ class Chosen extends AbstractChosen
set_label_behavior: ->
@form_field_label = @form_field.up("label") # first check for a parent label
if not @form_field_label?
- @form_field_label = $$("label[for=#{@form_field.id}]").first() #next check for a for=#{id}
+ @form_field_label = $$("label[for='#{@form_field.id}']").first() #next check for a for=#{id}
if @form_field_label?
@form_field_label.observe "click", (evt) => if @is_multiple then this.container_mousedown(evt) else this.activate_field()
show_search_field_default: ->
- if @is_multiple and @choices < 1 and not @active_field
+ if @is_multiple and this.choices_count() < 1 and not @active_field
@search_field.value = @default_text
@search_field.addClassName "default"
else
@@ -278,19 +277,16 @@ class Chosen extends AbstractChosen
this.result_clear_highlight() if evt.target.hasClassName('active-result') or evt.target.up('.active-result')
choice_build: (item) ->
- if @is_multiple and @max_selected_options <= @choices
- @form_field.fire("liszt:maxselected", {chosen: this})
- return false
- choice_id = @container_id + "_c_" + item.array_index
- @choices += 1
- @search_container.insert
- before: (if item.disabled then @choice_noclose_temp else @choice_temp).evaluate
- id: choice_id
- choice: item.html
- position: item.array_index
- if not item.disabled
- link = $(choice_id).down('a')
- link.observe "click", (evt) => this.choice_destroy_link_click(evt)
+ choice = new Element('li', { class: "search-choice" }).update("#{item.html}")
+
+ if item.disabled
+ choice.addClassName 'search-choice-disabled'
+ else
+ close_link = new Element('a', { href: '#', class: 'search-choice-close', rel: item.array_index })
+ close_link.observe "click", (evt) => this.choice_destroy_link_click(evt)
+ choice.insert close_link
+
+ @search_container.insert { before: choice }
choice_destroy_link_click: (evt) ->
evt.preventDefault()
@@ -299,10 +295,9 @@ class Chosen extends AbstractChosen
choice_destroy: (link) ->
if this.result_deselect link.readAttribute("rel")
- @choices -= 1
this.show_search_field_default()
- this.results_hide() if @is_multiple and @choices > 0 and @search_field.value.length < 1
+ this.results_hide() if @is_multiple and this.choices_count() > 0 and @search_field.value.length < 1
link.up('li').remove()
@@ -310,6 +305,7 @@ class Chosen extends AbstractChosen
results_reset: ->
@form_field.options[0].selected = true
+ @selected_option_count = null
@selected_item.down("span").update(@default_text)
@selected_item.addClassName("chzn-default") if not @is_multiple
this.show_search_field_default()
@@ -327,6 +323,10 @@ class Chosen extends AbstractChosen
high = @result_highlight
this.result_clear_highlight()
+ if @is_multiple and @max_selected_options <= this.choices_count()
+ @form_field.fire("liszt:maxselected", {chosen: this})
+ return false
+
if @is_multiple
this.result_deactivate high
else
@@ -341,6 +341,7 @@ class Chosen extends AbstractChosen
item.selected = true
@form_field.options[item.options_index].selected = true
+ @selected_option_count = null
if @is_multiple
this.choice_build item
@@ -370,6 +371,8 @@ class Chosen extends AbstractChosen
result_data.selected = false
@form_field.options[result_data.options_index].selected = false
+ @selected_option_count = null
+
result = $(@container_id + "_o_" + pos)
result.removeClassName("result-selected").addClassName("active-result").show()
@@ -488,7 +491,7 @@ class Chosen extends AbstractChosen
if prevs.length
this.result_do_highlight prevs.first()
else
- this.results_hide() if @choices > 0
+ this.results_hide() if this.choices_count() > 0
this.result_clear_highlight()
keydown_backstroke: ->
diff --git a/vendor/assets/javascripts/lib/abstract-chosen.coffee b/vendor/assets/javascripts/lib/abstract-chosen.coffee
index d83d2c8..ca653d0 100644
--- a/vendor/assets/javascripts/lib/abstract-chosen.coffee
+++ b/vendor/assets/javascripts/lib/abstract-chosen.coffee
@@ -32,7 +32,6 @@ class AbstractChosen
@disable_search = @options.disable_search || false
@enable_split_word_search = if @options.enable_split_word_search? then @options.enable_split_word_search else true
@search_contains = @options.search_contains || false
- @choices = 0
@single_backstroke_delete = @options.single_backstroke_delete || false
@max_selected_options = @options.max_selected_options || Infinity
@inherit_select_classes = @options.inherit_select_classes || false
@@ -95,6 +94,15 @@ class AbstractChosen
else
this.results_show()
+ choices_count: ->
+ return @selected_option_count if @selected_option_count?
+
+ @selected_option_count = 0
+ for option in @form_field.options
+ @selected_option_count += 1 if option.selected
+
+ return @selected_option_count
+
choices_click: (evt) ->
evt.preventDefault()
this.results_show() unless @results_showing
@@ -105,7 +113,7 @@ class AbstractChosen
switch stroke
when 8
- if @is_multiple and @backstroke_length < 1 and @choices > 0
+ if @is_multiple and @backstroke_length < 1 and this.choices_count() > 0
this.keydown_backstroke()
else if not @pending_backstroke
this.result_clear_highlight()
@@ -131,16 +139,7 @@ class AbstractChosen
newchar = chars.substring rand, rand+1
container_width: ->
- return @options.width if @options.width?
-
- width = if window.getComputedStyle?
- parseFloat window.getComputedStyle(@form_field).getPropertyValue('width')
- else if jQuery? and @form_field_jq?
- @form_field_jq.outerWidth()
- else
- @form_field.getWidth()
-
- width + "px"
+ return if @options.width? then @options.width else "#{@form_field.offsetWidth}px"
# class methods and variables ============================================================