Skip to content

Commit

Permalink
Merge pull request #1339 from harvesthq/the-need-for-speed
Browse files Browse the repository at this point in the history
Speed Chosen up significantly.
  • Loading branch information
pfiller committed Jul 10, 2013
2 parents bf86615 + d741861 commit 992cf28
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 170 deletions.
101 changes: 19 additions & 82 deletions coffee/chosen.jquery.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -166,31 +166,20 @@ class Chosen extends AbstractChosen
if @is_multiple
@search_choices.find("li.search-choice").remove()
else if not @is_multiple
@selected_item.addClass("chzn-default").find("span").text(@default_text)
this.single_set_selected_text()
if @disable_search or @form_field.options.length <= @disable_search_threshold
@search_field[0].readOnly = true
@container.addClass "chzn-container-single-nosearch"
else
@search_field[0].readOnly = false
@container.removeClass "chzn-container-single-nosearch"

content = ''
for data in @results_data
if data.group
content += this.result_add_group data
else if !data.empty
content += this.result_add_option data
if data.selected and @is_multiple
this.choice_build data
else if data.selected and not @is_multiple
@selected_item.removeClass("chzn-default").find("span").text data.text
this.single_deselect_control_build() if @allow_single_deselect
this.update_results_content this.results_option_build({first:true})

this.search_field_disabled()
this.show_search_field_default()
this.search_field_scale()

@search_results.html content
@parsing = false

result_add_group: (group) ->
Expand Down Expand Up @@ -235,6 +224,9 @@ class Chosen extends AbstractChosen

this.winnow_results()

update_results_content: (content) ->
@search_results.html content

results_hide: ->
if @results_showing
this.result_clear_highlight()
Expand Down Expand Up @@ -311,8 +303,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.single_set_selected_text()
this.show_search_field_default()
this.results_reset_cleanup()
@form_field_jq.trigger "change"
Expand All @@ -338,7 +329,6 @@ class Chosen extends AbstractChosen
else
@search_results.find(".result-selected").removeClass "result-selected"
@result_single_selected = high
@selected_item.removeClass("chzn-default")

high.addClass "result-selected"

Expand All @@ -352,8 +342,7 @@ class Chosen extends AbstractChosen
if @is_multiple
this.choice_build item
else
@selected_item.find("span").first().text item.text
this.single_deselect_control_build() if @allow_single_deselect
this.single_set_selected_text(item.text)

this.results_hide() unless (evt.metaKey or evt.ctrlKey) and @is_multiple

Expand All @@ -363,16 +352,14 @@ class Chosen extends AbstractChosen
@current_selectedIndex = @form_field.selectedIndex
this.search_field_scale()

result_activate: (el, option) ->
if option.disabled
el.addClass("disabled-result")
else if @is_multiple and option.selected
el.addClass("result-selected")
single_set_selected_text: (text=@default_text) ->
if text is @default_text
@selected_item.addClass("chzn-default")
else
el.addClass("active-result")
this.single_deselect_control_build()
@selected_item.removeClass("chzn-default")

result_deactivate: (el) ->
el.removeClass("active-result result-selected disabled-result")
@selected_item.find("span").text(text)

result_deselect: (pos) ->
result_data = @results_data[pos]
Expand All @@ -387,7 +374,7 @@ class Chosen extends AbstractChosen
result.removeClass("result-selected").addClass("active-result").show()

this.result_clear_highlight()
this.winnow_results()
this.winnow_results() if @results_showing

@form_field_jq.trigger "change", {deselected: @form_field.options[result_data.options_index].value}
this.search_field_scale()
Expand All @@ -401,65 +388,15 @@ class Chosen extends AbstractChosen
@selected_item.find("span").first().after "<abbr class=\"search-choice-close\"></abbr>" unless @selected_item.find("abbr").length
@selected_item.addClass("chzn-single-with-deselect")

winnow_results: ->
this.no_results_clear()

results = 0

searchText = if @search_field.val() is @default_text then "" else $('<div/>').text($.trim(@search_field.val())).html()
regexAnchor = if @search_contains then "" else "^"
regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')

for option in @results_data
if not option.empty
if option.group
$('#' + option.dom_id).css('display', 'none')
else
found = false
result_id = option.dom_id
result = $("#" + result_id)

if regex.test option.html
found = true
results += 1
else if @enable_split_word_search and (option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0)
#TODO: replace this substitution of /\[\]/ with a list of characters to skip.
parts = option.html.replace(/\[|\]/g, "").split(" ")
if parts.length
for part in parts
if regex.test part
found = true
results += 1

if found
if searchText.length
startpos = option.html.search zregex
text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length)
text = text.substr(0, startpos) + '<em>' + text.substr(startpos)
else
text = option.html

result.html(text)
this.result_activate result, option

$("#" + @results_data[option.group_array_index].dom_id).css('display', 'list-item') if option.group_array_index?
else
this.result_clear_highlight() if @result_highlight and result_id is @result_highlight.attr 'id'
this.result_deactivate result

if results < 1 and searchText.length
this.no_results searchText
else
this.winnow_results_set_highlight()
get_search_text: ->
if @search_field.val() is @default_text then "" else $('<div/>').text($.trim(@search_field.val())).html()

winnow_results_set_highlight: ->
if not @result_highlight

selected_results = if not @is_multiple then @search_results.find(".result-selected.active-result") else []
do_high = if selected_results.length then selected_results.first() else @search_results.find(".active-result").first()
selected_results = if not @is_multiple then @search_results.find(".result-selected.active-result") else []
do_high = if selected_results.length then selected_results.first() else @search_results.find(".active-result").first()

this.result_do_highlight do_high if do_high?
this.result_do_highlight do_high if do_high?

no_results: (terms) ->
no_results_html = $('<li class="no-results">' + @results_none_found + ' "<span></span>"</li>')
Expand Down
108 changes: 21 additions & 87 deletions coffee/chosen.proto.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -154,31 +154,20 @@ class Chosen extends AbstractChosen
if @is_multiple
@search_choices.select("li.search-choice").invoke("remove")
else if not @is_multiple
@selected_item.addClassName("chzn-default").down("span").update(@default_text)
this.single_set_selected_text()
if @disable_search or @form_field.options.length <= @disable_search_threshold
@search_field.readOnly = true
@container.addClassName "chzn-container-single-nosearch"
else
@search_field.readOnly = false
@container.removeClassName "chzn-container-single-nosearch"

content = ''
for data in @results_data
if data.group
content += this.result_add_group data
else if !data.empty
content += this.result_add_option data
if data.selected and @is_multiple
this.choice_build data
else if data.selected and not @is_multiple
@selected_item.removeClassName("chzn-default").down("span").update( data.html )
this.single_deselect_control_build() if @allow_single_deselect
this.update_results_content this.results_option_build({first:true})

this.search_field_disabled()
this.show_search_field_default()
this.search_field_scale()

@search_results.update content
@parsing = false

result_add_group: (group) ->
Expand Down Expand Up @@ -222,6 +211,9 @@ class Chosen extends AbstractChosen

this.winnow_results()

update_results_content: (content) ->
@search_results.update content

results_hide: ->
if @results_showing
this.result_clear_highlight()
Expand Down Expand Up @@ -298,8 +290,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.single_set_selected_text()
this.show_search_field_default()
this.results_reset_cleanup()
@form_field.simulate("change") if typeof Event.simulate is 'function'
Expand All @@ -323,7 +314,6 @@ class Chosen extends AbstractChosen
high.removeClassName("active-result")
else
@search_results.descendants(".result-selected").invoke "removeClassName", "result-selected"
@selected_item.removeClassName("chzn-default")
@result_single_selected = high

high.addClassName("result-selected")
Expand All @@ -338,8 +328,7 @@ class Chosen extends AbstractChosen
if @is_multiple
this.choice_build item
else
@selected_item.down("span").update(item.html)
this.single_deselect_control_build() if @allow_single_deselect
this.single_set_selected_text(item.text)

this.results_hide() unless (evt.metaKey or evt.ctrlKey) and @is_multiple

Expand All @@ -350,18 +339,14 @@ class Chosen extends AbstractChosen

this.search_field_scale()

result_activate: (el, option) ->
if option.disabled
el.addClassName("disabled-result")
else if @is_multiple and option.selected
el.addClassName("result-selected")
single_set_selected_text: (text=@default_text) ->
if text is @default_text
@selected_item.addClassName("chzn-default")
else
el.addClassName("active-result")
this.single_deselect_control_build()
@selected_item.removeClassName("chzn-default")

result_deactivate: (el) ->
el.removeClassName("active-result")
el.removeClassName("result-selected")
el.removeClassName("disabled-result")
@selected_item.down("span").update(text)

result_deselect: (pos) ->
result_data = @results_data[pos]
Expand All @@ -376,7 +361,7 @@ class Chosen extends AbstractChosen
result.removeClassName("result-selected").addClassName("active-result").show()

this.result_clear_highlight()
this.winnow_results()
this.winnow_results() if @results_showing

@form_field.simulate("change") if typeof Event.simulate is 'function'
this.search_field_scale()
Expand All @@ -389,68 +374,17 @@ class Chosen extends AbstractChosen
@selected_item.down("span").insert { after: "<abbr class=\"search-choice-close\"></abbr>" } unless @selected_item.down("abbr")
@selected_item.addClassName("chzn-single-with-deselect")

winnow_results: ->
this.no_results_clear()

results = 0

searchText = if @search_field.value is @default_text then "" else @search_field.value.strip().escapeHTML()
regexAnchor = if @search_contains then "" else "^"
regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')

for option in @results_data
if not option.empty
if option.group
$(option.dom_id).hide()
else
found = false
result_id = option.dom_id

if regex.test option.html
found = true
results += 1
else if @enable_split_word_search and (option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0)
#TODO: replace this substitution of /\[\]/ with a list of characters to skip.
parts = option.html.replace(/\[|\]/g, "").split(" ")
if parts.length
for part in parts
if regex.test part
found = true
results += 1

if found
if searchText.length
startpos = option.html.search zregex
text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length)
text = text.substr(0, startpos) + '<em>' + text.substr(startpos)
else
text = option.html

$(result_id).update text if $(result_id).innerHTML != text

this.result_activate $(result_id), option

$(@results_data[option.group_array_index].dom_id).setStyle({display: 'list-item'}) if option.group_array_index?
else
this.result_clear_highlight() if $(result_id) is @result_highlight
this.result_deactivate $(result_id)

if results < 1 and searchText.length
this.no_results(searchText)
else
this.winnow_results_set_highlight()
get_search_text: ->
if @search_field.value is @default_text then "" else @search_field.value.strip().escapeHTML()

winnow_results_set_highlight: ->
if not @result_highlight

if not @is_multiple
do_high = @search_results.down(".result-selected.active-result")
if not @is_multiple
do_high = @search_results.down(".result-selected.active-result")

if not do_high?
do_high = @search_results.down(".active-result")
if not do_high?
do_high = @search_results.down(".active-result")

this.result_do_highlight do_high if do_high?
this.result_do_highlight do_high if do_high?

no_results: (terms) ->
@search_results.insert @no_results_temp.evaluate( terms: terms )
Expand Down
Loading

0 comments on commit 992cf28

Please sign in to comment.