Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Option adding (with custom callback) #166

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
29 changes: 28 additions & 1 deletion coffee/chosen.jquery.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class Chosen extends AbstractChosen
@search_choices.find("li.search-choice").remove()
else
this.single_set_selected_text()
if @disable_search or @form_field.options.length <= @disable_search_threshold
if @disable_search or @form_field.options.length <= @disable_search_threshold and not @create_option
@search_field[0].readOnly = true
@container.addClass "chosen-container-single-nosearch"
else
Expand Down Expand Up @@ -355,6 +355,10 @@ class Chosen extends AbstractChosen
if @result_highlight
high = @result_highlight

if high.hasClass "create-option"
this.select_create_option(@search_field.val())
return this.results_hide()

this.result_clear_highlight()

if @is_multiple and @max_selected_options <= this.choices_count()
Expand Down Expand Up @@ -443,16 +447,39 @@ class Chosen extends AbstractChosen

no_results: (terms) ->
no_results_html = this.get_no_results_html(terms)

@search_results.append no_results_html
@form_field_jq.trigger("chosen:no_results", {chosen:this})

show_create_option: (terms) ->
create_option_html = this.get_create_option_html(terms)
@search_results.append create_option_html

create_option_clear: ->
@search_results.find(".create-option").remove()

select_create_option: (terms) ->
if $.isFunction(@create_option)
@create_option.call this, terms
else
this.select_append_option( {value: terms, text: terms} )

select_append_option: ( options ) ->
option = this.get_option_html(options)
@form_field_jq.append option
@form_field_jq.trigger "chosen:updated"
@form_field_jq.trigger "change"
@search_field.trigger "focus"

no_results_clear: ->
@search_results.find(".no-results").remove()

keydown_arrow: ->
if @results_showing and @result_highlight
next_sib = @result_highlight.nextAll("li.active-result").first()
this.result_do_highlight next_sib if next_sib
else if @results_showing and @create_option
this.result_do_highlight(@search_results.find('.create-option'))
else
this.results_show()

Expand Down
32 changes: 30 additions & 2 deletions coffee/chosen.proto.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class @Chosen extends AbstractChosen
@search_choices.select("li.search-choice").invoke("remove")
else
this.single_set_selected_text()
if @disable_search or @form_field.options.length <= @disable_search_threshold
if @disable_search or @form_field.options.length <= @disable_search_threshold and not @create_option
@search_field.readOnly = true
@container.addClassName "chosen-container-single-nosearch"
else
Expand Down Expand Up @@ -347,6 +347,11 @@ class @Chosen extends AbstractChosen
result_select: (evt) ->
if @result_highlight
high = @result_highlight

if high.hasClassName "create-option"
this.select_create_option(@search_field.value)
return this.results_hide()

this.result_clear_highlight()

if @is_multiple and @max_selected_options <= this.choices_count()
Expand Down Expand Up @@ -439,15 +444,38 @@ class @Chosen extends AbstractChosen
@search_results.insert this.get_no_results_html(terms)
@form_field.fire("chosen:no_results", {chosen: this})

show_create_option: (terms) ->
create_option_html = this.get_create_option_html(terms)
@search_results.insert create_option_html
@search_results.down(".create-option").observe "click", (evt) => this.select_create_option(terms)

create_option_clear: ->
co = null
co.remove() while co = @search_results.down(".create-option")

select_create_option: ( terms ) ->
if Object.isFunction( @create_option )
@create_option.call this, terms
else
this.select_append_option( value: terms, text: terms )

select_append_option: (options) ->
@form_field.insert this.get_option_html(options)
Event.fire @form_field, "chosen:updated"
if typeof Event.simulate is 'function'
@form_field.simulate("change")
@search_field.simulate("focus")

no_results_clear: ->
nr = null
nr.remove() while nr = @search_results.down(".no-results")


keydown_arrow: ->
if @results_showing and @result_highlight
next_sib = @result_highlight.next('.active-result')
this.result_do_highlight next_sib if next_sib
else if @results_showing and @create_option
this.result_do_highlight(@search_results.select('.create-option').first())
else
this.results_show()

Expand Down
28 changes: 26 additions & 2 deletions coffee/lib/abstract-chosen.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class AbstractChosen
@max_shown_results = @options.max_shown_results || Number.POSITIVE_INFINITY
@case_sensitive_search = @options.case_sensitive_search || false
@hide_results_on_select = if @options.hide_results_on_select? then @options.hide_results_on_select else true
@create_option = @options.create_option || false
@persistent_create_option = @options.persistent_create_option || false
@skip_no_results = @options.skip_no_results || false

set_default_text: ->
if @form_field.getAttribute("data-placeholder")
Expand All @@ -48,6 +51,7 @@ class AbstractChosen
@default_text = this.escape_html(@default_text)

@results_none_found = @form_field.getAttribute("data-no_results_text") || @options.no_results_text || AbstractChosen.default_no_result_text
@create_option_text = @form_field.getAttribute("data-create_option_text") || @options.create_option_text || AbstractChosen.default_create_option_text

choice_label: (item) ->
if @include_group_label_in_selected and item.group_label?
Expand Down Expand Up @@ -136,6 +140,9 @@ class AbstractChosen

this.outerHTML(group_el)

append_option: (option) ->
this.select_append_option(option)

results_update_field: ->
this.set_default_text()
this.results_reset_cleanup() if not @is_multiple
Expand Down Expand Up @@ -163,10 +170,12 @@ class AbstractChosen
this.no_results_clear()

results = 0
exact_result = false

query = this.get_search_text()
escapedQuery = query.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
regex = this.get_search_regex(escapedQuery)
exactRegex = new RegExp("^#{escapedQuery}$")

for option in @results_data

Expand Down Expand Up @@ -194,6 +203,8 @@ class AbstractChosen

results += 1 if option.search_match and not option.group

exact_result = exact_result || exactRegex.test option.html

if option.search_match
if query.length
startpos = search_match.index
Expand All @@ -211,11 +222,14 @@ class AbstractChosen

if results < 1 and query.length
this.update_results_content ""
this.no_results query
this.no_results query unless @create_option and @skip_no_results
else
this.update_results_content this.results_option_build()
this.winnow_results_set_highlight()

if @create_option and (results < 1 or (!exact_result and @persistent_create_option)) and query.length
this.show_create_option( query )

get_search_regex: (escaped_search_string) ->
regex_string = if @search_contains then escaped_search_string else "(^|\\s|\\b)#{escaped_search_string}[^\\s]*"
regex_string = "^#{regex_string}" unless @enable_split_word_search or @search_contains
Expand Down Expand Up @@ -362,6 +376,16 @@ class AbstractChosen
</li>
"""

get_option_html: ({ value, text }) ->
"""
<option value="#{value}" selected>#{text}</option>
"""

get_create_option_html: (terms) ->
"""
<li class="create-option active-result"><a>#{@create_option_text}</a>: "#{this.escape_html(terms)}"</li>
"""

# class methods and variables ============================================================

@browser_is_supported: ->
Expand All @@ -379,4 +403,4 @@ class AbstractChosen
@default_multiple_text: "Select Some Options"
@default_single_text: "Select an Option"
@default_no_result_text: "No results match"

@default_create_option_text: "Add Option"
Loading