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

Tag like interface (or add new options) #320

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 46 additions & 8 deletions chosen/chosen.jquery.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
break;
case 13:
evt.preventDefault();
if (this.results_showing) {
if (this.results_showing || this.options.allow_option_creation) {
return this.result_select(evt);
}
break;
Expand Down Expand Up @@ -626,7 +626,7 @@
}
};
Chosen.prototype.result_select = function(evt) {
var high, high_id, item, position;
var high, high_id, item, new_option, position;
if (this.result_highlight) {
high = this.result_highlight;
high_id = high.attr("id");
Expand Down Expand Up @@ -656,6 +656,32 @@
this.search_field.val("");
this.form_field_jq.trigger("change");
return this.search_field_scale();
} else if (this.options.allow_option_creation) {
new_option = this.search_field.val();
if (!new_option) {
return;
}
if (this.allow_creation(new_option)) {
$('<option>', {
selected: true,
value: new_option
}).text(new_option).appendTo(this.form_field_jq);
this.results_update_field(evt);
}
this.form_field_jq.trigger("change");
this.search_field.val("");
return this.results_hide();
}
};
Chosen.prototype.allow_creation = function(new_option) {
var matches;
if (this.is_multiple) {
matches = this.search_choices.find("li.search-choice span").filter(function() {
return $(this).text().toLowerCase() === new_option.toLowerCase();
});
return !matches.length;
} else {
return this.selected_item.find('span').text().toLowerCase() !== new_option.toLowerCase();
}
};
Chosen.prototype.result_activate = function(el) {
Expand All @@ -682,13 +708,15 @@
}
};
Chosen.prototype.winnow_results = function() {
var found, option, part, parts, regex, result_id, results, searchText, startTime, startpos, text, zregex, _i, _j, _len, _len2, _ref;
var found, fregex, option, part, parts, regex, result_id, results, searchText, startTime, startpos, text, textToSearch, zregex, _i, _j, _len, _len2, _ref;
startTime = new Date();
this.no_results_clear();
results = 0;
searchText = this.search_field.val() === this.default_text ? "" : $('<div/>').text($.trim(this.search_field.val())).html();
regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
textToSearch = searchText.replace(/[\-\[\]\{\}\(\)\*\+\?\.,\\\^\$\|\#\s]/g, "\\$&");
regex = new RegExp('^' + textToSearch, 'i');
zregex = new RegExp(textToSearch, 'i');
fregex = new RegExp("^" + textToSearch + "$", 'i');
_ref = this.results_data;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
option = _ref[_i];
Expand All @@ -698,7 +726,11 @@
} else if (!(this.is_multiple && option.selected)) {
found = false;
result_id = option.dom_id;
if (regex.test(option.html)) {
if (this.options.allow_option_creation && searchText && fregex.test(option.html)) {
found = true;
results += 1;
this.result_do_highlight($('#' + option.dom_id));
} else if (regex.test(option.html)) {
found = true;
results += 1;
} else if (option.html.indexOf(" ") >= 0 || option.html.indexOf("[") === 0) {
Expand Down Expand Up @@ -738,8 +770,11 @@
}
}
if (results < 1 && searchText.length) {
return this.no_results(searchText);
} else {
this.no_results(searchText);
if (this.options.allow_option_creation && this.is_multiple) {
return this.results_hide();
}
} else if (!this.options.allow_option_creation) {
return this.winnow_results_set_highlight();
}
};
Expand Down Expand Up @@ -767,6 +802,9 @@
};
Chosen.prototype.no_results = function(terms) {
var no_results_html;
if (!this.is_multiple && this.options.allow_option_creation) {
return;
}
no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
no_results_html.find("span").first().html(terms);
return this.search_results.append(no_results_html);
Expand Down
2 changes: 1 addition & 1 deletion chosen/chosen.jquery.min.js

Large diffs are not rendered by default.

60 changes: 51 additions & 9 deletions chosen/chosen.proto.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
break;
case 13:
evt.preventDefault();
if (this.results_showing) {
if (this.results_showing || this.options.allow_option_creation) {
return this.result_select(evt);
}
break;
Expand Down Expand Up @@ -623,7 +623,7 @@
}
};
Chosen.prototype.result_select = function(evt) {
var high, item, position;
var high, item, new_option, position;
if (this.result_highlight) {
high = this.result_highlight;
this.result_clear_highlight();
Expand Down Expand Up @@ -654,6 +654,36 @@
this.form_field.simulate("change");
}
return this.search_field_scale();
} else if (this.options.allow_option_creation) {
new_option = this.search_field.value;
if (!new_option) {
return;
}
if (this.allow_creation(new_option)) {
this.form_field.insert(Element('option', {
selected: true,
value: new_option
}).update(new_option));
this.results_update_field(evt);
}
if (typeof Event.simulate === 'function') {
this.form_field.simulate("change");
}
this.search_field.value = "";
return this.results_hide();
}
};
Chosen.prototype.allow_creation = function(new_option) {
var matches;
if (this.is_multiple) {
matches = this.search_choices.getElementsBySelector("li.search-choice span").select(function(el) {
console.debug(el);
return el.innerHTML.toLowerCase() === new_option.toLowerCase();
});
console.debug(matches);
return !matches.length;
} else {
return this.selected_item.getElementsBySelector('span').innerHTML.toLowerCase() !== new_option.toLowerCase();
}
};
Chosen.prototype.result_activate = function(el) {
Expand Down Expand Up @@ -684,13 +714,15 @@
}
};
Chosen.prototype.winnow_results = function() {
var found, option, part, parts, regex, result_id, results, searchText, startTime, startpos, text, zregex, _i, _j, _len, _len2, _ref;
var found, fregex, option, part, parts, regex, result_id, results, searchText, startTime, startpos, text, textToSearch, zregex, _i, _j, _len, _len2, _ref;
startTime = new Date();
this.no_results_clear();
results = 0;
searchText = this.search_field.value === this.default_text ? "" : this.search_field.value.strip().escapeHTML();
regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
searchText = this.search_field.val() === this.default_text ? "" : $('<div/>').text($.trim(this.search_field.val())).html();
textToSearch = searchText.replace(/[\-\[\]\{\}\(\)\*\+\?\.,\\\^\$\|\#\s]/g, "\\$&");
regex = new RegExp('^' + textToSearch, 'i');
zregex = new RegExp(textToSearch, 'i');
fregex = new RegExp("^" + textToSearch + "$", 'i');
_ref = this.results_data;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
option = _ref[_i];
Expand All @@ -700,7 +732,11 @@
} else if (!(this.is_multiple && option.selected)) {
found = false;
result_id = option.dom_id;
if (regex.test(option.html)) {
if (this.options.allow_option_creation && searchText && fregex.test(option.html)) {
found = true;
results += 1;
this.result_do_highlight($(option.dom_id));
} else if (regex.test(option.html)) {
found = true;
results += 1;
} else if (option.html.indexOf(" ") >= 0 || option.html.indexOf("[") === 0) {
Expand Down Expand Up @@ -740,8 +776,11 @@
}
}
if (results < 1 && searchText.length) {
return this.no_results(searchText);
} else {
this.no_results(searchText);
if (this.options.allow_option_creation && this.is_multiple) {
return this.results_hide();
}
} else if (!this.options.allow_option_creation) {
return this.winnow_results_set_highlight();
}
};
Expand Down Expand Up @@ -771,6 +810,9 @@
}
};
Chosen.prototype.no_results = function(terms) {
if (!this.is_multiple && this.options.allow_option_creation) {
return;
}
return this.search_results.insert(this.no_results_temp.evaluate({
terms: terms
}));
Expand Down
2 changes: 1 addition & 1 deletion chosen/chosen.proto.min.js

Large diffs are not rendered by default.

33 changes: 29 additions & 4 deletions coffee/chosen.jquery.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,23 @@ class Chosen extends AbstractChosen

@form_field_jq.trigger "change"
this.search_field_scale()
else if @options.allow_option_creation
new_option = @search_field.val()
return unless new_option
if @allow_creation(new_option)
$('<option>', {selected: true, value: new_option}).text(new_option).appendTo(@form_field_jq)
@results_update_field(evt)
@form_field_jq.trigger "change"
@search_field.val("")
@results_hide()

allow_creation: (new_option) ->
if @is_multiple
matches = @search_choices.find("li.search-choice span").filter ->
$(this).text().toLowerCase() == new_option.toLowerCase()
!matches.length
else
@selected_item.find('span').text().toLowerCase() != new_option.toLowerCase()

result_activate: (el) ->
el.addClass("active-result")
Expand Down Expand Up @@ -380,8 +397,10 @@ class Chosen extends AbstractChosen
results = 0

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

for option in @results_data
if not option.disabled and not option.empty
Expand All @@ -391,7 +410,11 @@ class Chosen extends AbstractChosen
found = false
result_id = option.dom_id

if regex.test option.html
if @options.allow_option_creation && searchText && fregex.test(option.html)
found = true
results += 1
@result_do_highlight($('#' + option.dom_id))
else if regex.test option.html
found = true
results += 1
else if option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0
Expand Down Expand Up @@ -422,7 +445,8 @@ class Chosen extends AbstractChosen

if results < 1 and searchText.length
this.no_results searchText
else
@results_hide() if @options.allow_option_creation && @is_multiple
else if not @options.allow_option_creation
this.winnow_results_set_highlight()

winnow_results_clear: ->
Expand All @@ -445,6 +469,7 @@ class Chosen extends AbstractChosen
this.result_do_highlight do_high if do_high?

no_results: (terms) ->
return if !@is_multiple && @options.allow_option_creation
no_results_html = $('<li class="no-results">' + @results_none_found + ' "<span></span>"</li>')
no_results_html.find("span").first().html(terms)

Expand Down
37 changes: 32 additions & 5 deletions coffee/chosen.proto.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,25 @@ class Chosen extends AbstractChosen

@form_field.simulate("change") if typeof Event.simulate is 'function'
this.search_field_scale()
else if @options.allow_option_creation
new_option = @search_field.value
return unless new_option
if @allow_creation(new_option)
@form_field.insert(Element('option', {selected: true, value: new_option}).update(new_option))
@results_update_field(evt)
@form_field.simulate("change") if typeof Event.simulate is 'function'
@search_field.value = ""
@results_hide()

allow_creation: (new_option) ->
if @is_multiple
matches = @search_choices.getElementsBySelector("li.search-choice span").select (el) ->
console.debug(el)
el.innerHTML.toLowerCase() == new_option.toLowerCase()
console.debug(matches)
!matches.length
else
@selected_item.getElementsBySelector('span').innerHTML.toLowerCase() != new_option.toLowerCase()

result_activate: (el) ->
el.addClassName("active-result")
Expand Down Expand Up @@ -370,9 +389,11 @@ class Chosen extends AbstractChosen

results = 0

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

for option in @results_data
if not option.disabled and not option.empty
Expand All @@ -382,7 +403,11 @@ class Chosen extends AbstractChosen
found = false
result_id = option.dom_id

if regex.test option.html
if @options.allow_option_creation && searchText && fregex.test(option.html)
found = true
results += 1
@result_do_highlight($(option.dom_id))
else if regex.test option.html
found = true
results += 1
else if option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0
Expand Down Expand Up @@ -413,7 +438,8 @@ class Chosen extends AbstractChosen

if results < 1 and searchText.length
this.no_results(searchText)
else
@results_hide() if @options.allow_option_creation && @is_multiple
else if not @options.allow_option_creation
this.winnow_results_set_highlight()

winnow_results_clear: ->
Expand All @@ -438,6 +464,7 @@ class Chosen extends AbstractChosen
this.result_do_highlight do_high if do_high?

no_results: (terms) ->
return if !@is_multiple && @options.allow_option_creation
@search_results.insert @no_results_temp.evaluate( terms: terms )

no_results_clear: ->
Expand Down
2 changes: 1 addition & 1 deletion coffee/lib/abstract-chosen.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class AbstractChosen
this.results_search()
when 13
evt.preventDefault()
this.result_select(evt) if this.results_showing
this.result_select(evt) if this.results_showing || this.options.allow_option_creation
when 27
this.results_hide() if @results_showing
when 9, 38, 40, 16, 91, 17
Expand Down
Loading