Merge master into abstract-chosen

This commit is contained in:
Matthew Beale 2011-09-30 17:39:03 -04:00
commit 47b7b4d6bc
14 changed files with 473 additions and 184 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
.DS_Store .DS_Store
node_modules

View file

@ -1 +1 @@
0.9.1 0.9.5

Binary file not shown.

Before

Width:  |  Height:  |  Size: 742 B

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -57,6 +57,19 @@
-ms-text-overflow: ellipsis; -ms-text-overflow: ellipsis;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.chzn-container-single .chzn-single abbr {
display: block;
position: absolute;
right: 26px;
top: 8px;
width: 12px;
height: 13px;
font-size: 1px;
background: url(chosen-sprite.png) right top no-repeat;
}
.chzn-container-single .chzn-single abbr:hover {
background-position: right -11px;
}
.chzn-container-single .chzn-single div { .chzn-container-single .chzn-single div {
-webkit-border-radius: 0 4px 4px 0; -webkit-border-radius: 0 4px 4px 0;
-moz-border-radius : 0 4px 4px 0; -moz-border-radius : 0 4px 4px 0;
@ -88,18 +101,19 @@
} }
.chzn-container-single .chzn-search { .chzn-container-single .chzn-search {
padding: 3px 4px; padding: 3px 4px;
position: relative;
margin: 0; margin: 0;
white-space: nowrap; white-space: nowrap;
} }
.chzn-container-single .chzn-search input { .chzn-container-single .chzn-search input {
background: #fff url('chosen-sprite.png') no-repeat 100% -20px; background: #fff url('chosen-sprite.png') no-repeat 100% -22px;
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); background: url('chosen-sprite.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); background: url('chosen-sprite.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); background: url('chosen-sprite.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); background: url('chosen-sprite.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); background: url('chosen-sprite.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); background: url('chosen-sprite.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); background: url('chosen-sprite.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%,#eeeeee 99%);
margin: 1px 0; margin: 1px 0;
padding: 4px 20px 4px 5px; padding: 4px 20px 4px 5px;
outline: 0; outline: 0;
@ -117,6 +131,11 @@
} }
/* @end */ /* @end */
.chzn-container-single-nosearch .chzn-search input {
position: absolute;
left: -9000px;
}
/* @group Multi Chosen */ /* @group Multi Chosen */
.chzn-container-multi .chzn-choices { .chzn-container-multi .chzn-choices {
background-color: #fff; background-color: #fff;
@ -191,18 +210,18 @@
.chzn-container-multi .chzn-choices .search-choice .search-choice-close { .chzn-container-multi .chzn-choices .search-choice .search-choice-close {
display: block; display: block;
position: absolute; position: absolute;
right: 5px; right: 3px;
top: 6px; top: 4px;
width: 8px; width: 12px;
height: 9px; height: 13px;
font-size: 1px; font-size: 1px;
background: url(chosen-sprite.png) right top no-repeat; background: url(chosen-sprite.png) right top no-repeat;
} }
.chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover { .chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover {
background-position: right -9px; background-position: right -11px;
} }
.chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close { .chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close {
background-position: right -9px; background-position: right -11px;
} }
/* @end */ /* @end */
@ -220,6 +239,7 @@
padding: 0; padding: 0;
} }
.chzn-container .chzn-results li { .chzn-container .chzn-results li {
display: none;
line-height: 80%; line-height: 80%;
padding: 7px 7px 8px; padding: 7px 7px 8px;
margin: 0; margin: 0;
@ -227,6 +247,7 @@
} }
.chzn-container .chzn-results .active-result { .chzn-container .chzn-results .active-result {
cursor: pointer; cursor: pointer;
display: list-item;
} }
.chzn-container .chzn-results .highlighted { .chzn-container .chzn-results .highlighted {
background: #3875d7; background: #3875d7;
@ -241,6 +262,7 @@
} }
.chzn-container .chzn-results .no-results { .chzn-container .chzn-results .no-results {
background: #f4f4f4; background: #f4f4f4;
display: list-item;
} }
.chzn-container .chzn-results .group-result { .chzn-container .chzn-results .group-result {
cursor: default; cursor: default;
@ -303,6 +325,18 @@
} }
/* @end */ /* @end */
/* @group Disabled Support */
.chzn-disabled {
cursor: default;
opacity:0.5 !important;
}
.chzn-disabled .chzn-single {
cursor: default;
}
.chzn-disabled .chzn-choices .search-choice .search-choice-close {
cursor: default;
}
/* @group Right to Left */ /* @group Right to Left */
.chzn-rtl { direction:rtl;text-align: right; } .chzn-rtl { direction:rtl;text-align: right; }
.chzn-rtl .chzn-single { padding-left: 0; padding-right: 8px; } .chzn-rtl .chzn-single { padding-left: 0; padding-right: 8px; }
@ -321,14 +355,14 @@
.chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 20px; } .chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 20px; }
.chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; } .chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; }
.chzn-rtl .chzn-search input { .chzn-rtl .chzn-search input {
background: url('chosen-sprite.png') no-repeat -38px -20px, #ffffff; background: url('chosen-sprite.png') no-repeat -38px -22px, #ffffff;
background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); background: url('chosen-sprite.png') no-repeat -38px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); background: url('chosen-sprite.png') no-repeat -38px -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
background: url('chosen-sprite.png') no-repeat -38px -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); background: url('chosen-sprite.png') no-repeat -38px -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
background: url('chosen-sprite.png') no-repeat -38px -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); background: url('chosen-sprite.png') no-repeat -38px -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); background: url('chosen-sprite.png') no-repeat -38px -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); background: url('chosen-sprite.png') no-repeat -38px -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
background: url('chosen-sprite.png') no-repeat -38px -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); background: url('chosen-sprite.png') no-repeat -38px -22px, linear-gradient(top, #ffffff 85%,#eeeeee 99%);
padding: 4px 5px 4px 20px; padding: 4px 5px 4px 20px;
} }
/* @end */ /* @end */

View file

@ -1,7 +1,7 @@
// Chosen, a Select Box Enhancer for jQuery and Protoype // Chosen, a Select Box Enhancer for jQuery and Protoype
// by Patrick Filler for Harvest, http://getharvest.com // by Patrick Filler for Harvest, http://getharvest.com
// //
// Version 0.9.1 // Version 0.9.5
// Full source at https://github.com/harvesthq/chosen // Full source at https://github.com/harvesthq/chosen
// Copyright (c) 2011 Harvest http://getharvest.com // Copyright (c) 2011 Harvest http://getharvest.com
@ -53,7 +53,9 @@
html: option.innerHTML, html: option.innerHTML,
selected: option.selected, selected: option.selected,
disabled: group_disabled === true ? group_disabled : option.disabled, disabled: group_disabled === true ? group_disabled : option.disabled,
group_array_index: group_position group_array_index: group_position,
classes: option.className,
style: option.style.cssText
}); });
} else { } else {
this.parsed.push({ this.parsed.push({
@ -83,13 +85,15 @@
/* /*
Chosen source: generate output using 'cake build' Chosen source: generate output using 'cake build'
Copyright (c) 2011 by Harvest Copyright (c) 2011 by Harvest
*/ var AbstractChosen, root; */
var AbstractChosen, root;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
root = this; root = this;
AbstractChosen = (function() { AbstractChosen = (function() {
function AbstractChosen(elmn) { function AbstractChosen(form_field, options) {
this.form_field = form_field;
this.options = options != null ? options : {};
this.set_default_values(); this.set_default_values();
this.form_field = elmn;
this.is_multiple = this.form_field.multiple; this.is_multiple = this.form_field.multiple;
this.default_text_default = this.is_multiple ? "Select Some Options" : "Select an Option"; this.default_text_default = this.is_multiple ? "Select Some Options" : "Select an Option";
this.setup(); this.setup();
@ -101,12 +105,18 @@
this.click_test_action = __bind(function(evt) { this.click_test_action = __bind(function(evt) {
return this.test_active_click(evt); return this.test_active_click(evt);
}, this); }, this);
this.activate_action = __bind(function(evt) {
return this.activate_field(evt);
}, this);
this.active_field = false; this.active_field = false;
this.mouse_on_container = false; this.mouse_on_container = false;
this.results_showing = false; this.results_showing = false;
this.result_highlighted = null; this.result_highlighted = null;
this.result_single_selected = null; this.result_single_selected = null;
return this.choices = 0; this.allow_single_deselect = (this.options.allow_single_deselect != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
this.disable_search_threshold = this.options.disable_search_threshold || 0;
this.choices = 0;
return this.results_none_found = this.options.no_results_text || "No results match";
}; };
AbstractChosen.prototype.mouse_enter = function() { AbstractChosen.prototype.mouse_enter = function() {
return this.mouse_on_container = true; return this.mouse_on_container = true;
@ -130,7 +140,7 @@
} }
}; };
AbstractChosen.prototype.result_add_option = function(option) { AbstractChosen.prototype.result_add_option = function(option) {
var classes; var classes, style;
if (!option.disabled) { if (!option.disabled) {
option.dom_id = this.container_id + "_o_" + option.array_index; option.dom_id = this.container_id + "_o_" + option.array_index;
classes = option.selected && this.is_multiple ? [] : ["active-result"]; classes = option.selected && this.is_multiple ? [] : ["active-result"];
@ -140,7 +150,11 @@
if (option.group_array_index != null) { if (option.group_array_index != null) {
classes.push("group-option"); classes.push("group-option");
} }
return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.html + '</li>'; if (option.classes !== "") {
classes.push(option.classes);
}
style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : "";
return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '"' + style + '>' + option.html + '</li>';
} else { } else {
return ""; return "";
} }
@ -219,7 +233,8 @@
/* /*
Chosen source: generate output using 'cake build' Chosen source: generate output using 'cake build'
Copyright (c) 2011 by Harvest Copyright (c) 2011 by Harvest
*/ var $, Chosen, get_side_border_padding, root; */
var $, Chosen, get_side_border_padding, root;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; } function ctor() { this.constructor = child; }
@ -231,13 +246,13 @@
root = this; root = this;
$ = jQuery; $ = jQuery;
$.fn.extend({ $.fn.extend({
chosen: function(data, options) { chosen: function(options) {
if ($.browser === "msie" && ($.browser.version === "6.0" || $.browser.version === "7.0")) { if ($.browser === "msie" && ($.browser.version === "6.0" || $.browser.version === "7.0")) {
return this; return this;
} }
return $(this).each(function(input_field) { return $(this).each(function(input_field) {
if (!($(this)).hasClass("chzn-done")) { if (!($(this)).hasClass("chzn-done")) {
return new Chosen(this, data, options); return new Chosen(this, options);
} }
}); });
} }
@ -258,11 +273,11 @@
var container_div, dd_top, dd_width, sf_width; var container_div, dd_top, dd_width, sf_width;
this.container_id = this.form_field.id.length ? this.form_field.id.replace(/(:|\.)/g, '_') : this.generate_field_id(); this.container_id = this.form_field.id.length ? this.form_field.id.replace(/(:|\.)/g, '_') : this.generate_field_id();
this.container_id += "_chzn"; this.container_id += "_chzn";
this.f_width = this.form_field_jq.width(); this.f_width = this.form_field_jq.outerWidth();
this.default_text = this.form_field_jq.data('placeholder') ? this.form_field_jq.data('placeholder') : this.default_text_default; this.default_text = this.form_field_jq.data('placeholder') ? this.form_field_jq.data('placeholder') : this.default_text_default;
container_div = $("<div />", { container_div = $("<div />", {
id: this.container_id, id: this.container_id,
"class": "chzn-container " + (this.is_rtl ? 'chzn-rtl' : ''), "class": "chzn-container" + (this.is_rtl ? ' chzn-rtl' : ''),
style: 'width: ' + this.f_width + 'px;' style: 'width: ' + this.f_width + 'px;'
}); });
if (this.is_multiple) { if (this.is_multiple) {
@ -273,6 +288,9 @@
this.form_field_jq.hide().after(container_div); this.form_field_jq.hide().after(container_div);
this.container = $('#' + this.container_id); this.container = $('#' + this.container_id);
this.container.addClass("chzn-container-" + (this.is_multiple ? "multi" : "single")); this.container.addClass("chzn-container-" + (this.is_multiple ? "multi" : "single"));
if (!this.is_multiple && this.form_field.options.length <= this.disable_search_threshold) {
this.container.addClass("chzn-container-single-nosearch");
}
this.dropdown = this.container.find('div.chzn-drop').first(); this.dropdown = this.container.find('div.chzn-drop').first();
dd_top = this.container.height(); dd_top = this.container.height();
dd_width = this.f_width - get_side_border_padding(this.dropdown); dd_width = this.f_width - get_side_border_padding(this.dropdown);
@ -302,6 +320,9 @@
this.container.mousedown(__bind(function(evt) { this.container.mousedown(__bind(function(evt) {
return this.container_mousedown(evt); return this.container_mousedown(evt);
}, this)); }, this));
this.container.mouseup(__bind(function(evt) {
return this.container_mouseup(evt);
}, this));
this.container.mouseenter(__bind(function(evt) { this.container.mouseenter(__bind(function(evt) {
return this.mouse_enter(evt); return this.mouse_enter(evt);
}, this)); }, this));
@ -336,17 +357,33 @@
return this.search_field.focus(__bind(function(evt) { return this.search_field.focus(__bind(function(evt) {
return this.input_focus(evt); return this.input_focus(evt);
}, this)); }, this));
}
};
Chosen.prototype.search_field_disabled = function() {
this.is_disabled = this.form_field_jq.attr('disabled');
if (this.is_disabled) {
this.container.addClass('chzn-disabled');
this.search_field.attr('disabled', true);
if (!this.is_multiple) {
this.selected_item.unbind("focus", this.activate_action);
}
return this.close_field();
} else { } else {
return this.selected_item.focus(__bind(function(evt) { this.container.removeClass('chzn-disabled');
return this.activate_field(evt); this.search_field.attr('disabled', false);
}, this)); if (!this.is_multiple) {
return this.selected_item.bind("focus", this.activate_action);
}
} }
}; };
Chosen.prototype.container_mousedown = function(evt) { Chosen.prototype.container_mousedown = function(evt) {
var target_closelink;
if (!this.is_disabled) {
target_closelink = evt != null ? ($(evt.target)).hasClass("search-choice-close") : false;
if (evt && evt.type === "mousedown") { if (evt && evt.type === "mousedown") {
evt.stopPropagation(); evt.stopPropagation();
} }
if (!this.pending_destroy_click) { if (!this.pending_destroy_click && !target_closelink) {
if (!this.active_field) { if (!this.active_field) {
if (this.is_multiple) { if (this.is_multiple) {
this.search_field.val(""); this.search_field.val("");
@ -361,6 +398,12 @@
} else { } else {
return this.pending_destroy_click = false; return this.pending_destroy_click = false;
} }
}
};
Chosen.prototype.container_mouseup = function(evt) {
if (evt.target.nodeName === "ABBR") {
return this.results_reset(evt);
}
}; };
Chosen.prototype.blur_test = function(evt) { Chosen.prototype.blur_test = function(evt) {
if (!this.active_field && this.container.hasClass("chzn-container-active")) { if (!this.active_field && this.container.hasClass("chzn-container-active")) {
@ -421,9 +464,13 @@
this.choice_build(data); this.choice_build(data);
} else if (data.selected && !this.is_multiple) { } else if (data.selected && !this.is_multiple) {
this.selected_item.find("span").text(data.text); this.selected_item.find("span").text(data.text);
if (this.allow_single_deselect) {
this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
} }
} }
} }
}
this.search_field_disabled();
this.show_search_field_default(); this.show_search_field_default();
this.search_field_scale(); this.search_field_scale();
this.search_results.html(content); this.search_results.html(content);
@ -549,8 +596,12 @@
}; };
Chosen.prototype.choice_destroy_link_click = function(evt) { Chosen.prototype.choice_destroy_link_click = function(evt) {
evt.preventDefault(); evt.preventDefault();
if (!this.is_disabled) {
this.pending_destroy_click = true; this.pending_destroy_click = true;
return this.choice_destroy($(evt.target)); return this.choice_destroy($(evt.target));
} else {
return evt.stopPropagation;
}
}; };
Chosen.prototype.choice_destroy = function(link) { Chosen.prototype.choice_destroy = function(link) {
this.choices -= 1; this.choices -= 1;
@ -561,18 +612,29 @@
this.result_deselect(link.attr("rel")); this.result_deselect(link.attr("rel"));
return link.parents('li').first().remove(); return link.parents('li').first().remove();
}; };
Chosen.prototype.results_reset = function(evt) {
this.form_field.options[0].selected = true;
this.selected_item.find("span").text(this.default_text);
this.show_search_field_default();
$(evt.target).remove();
this.form_field_jq.trigger("change");
if (this.active_field) {
return this.results_hide();
}
};
Chosen.prototype.result_select = function(evt) { Chosen.prototype.result_select = function(evt) {
var high, high_id, item, position; var high, high_id, item, position;
if (this.result_highlight) { if (this.result_highlight) {
high = this.result_highlight; high = this.result_highlight;
high_id = high.attr("id"); high_id = high.attr("id");
this.result_clear_highlight(); this.result_clear_highlight();
high.addClass("result-selected");
if (this.is_multiple) { if (this.is_multiple) {
this.result_deactivate(high); this.result_deactivate(high);
} else { } else {
this.search_results.find(".result-selected").removeClass("result-selected");
this.result_single_selected = high; this.result_single_selected = high;
} }
high.addClass("result-selected");
position = high_id.substr(high_id.lastIndexOf("_") + 1); position = high_id.substr(high_id.lastIndexOf("_") + 1);
item = this.results_data[position]; item = this.results_data[position];
item.selected = true; item.selected = true;
@ -581,6 +643,9 @@
this.choice_build(item); this.choice_build(item);
} else { } else {
this.selected_item.find("span").first().text(item.text); this.selected_item.find("span").first().text(item.text);
if (this.allow_single_deselect) {
this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
}
} }
if (!(evt.metaKey && this.is_multiple)) { if (!(evt.metaKey && this.is_multiple)) {
this.results_hide(); this.results_hide();
@ -591,10 +656,10 @@
} }
}; };
Chosen.prototype.result_activate = function(el) { Chosen.prototype.result_activate = function(el) {
return el.addClass("active-result").show(); return el.addClass("active-result");
}; };
Chosen.prototype.result_deactivate = function(el) { Chosen.prototype.result_deactivate = function(el) {
return el.removeClass("active-result").hide(); return el.removeClass("active-result");
}; };
Chosen.prototype.result_deselect = function(pos) { Chosen.prototype.result_deselect = function(pos) {
var result, result_data; var result, result_data;
@ -685,7 +750,7 @@
Chosen.prototype.winnow_results_set_highlight = function() { Chosen.prototype.winnow_results_set_highlight = function() {
var do_high, selected_results; var do_high, selected_results;
if (!this.result_highlight) { if (!this.result_highlight) {
selected_results = !this.is_multiple ? this.search_results.find(".result-selected") : []; selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first(); do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
if (do_high != null) { if (do_high != null) {
return this.result_do_highlight(do_high); return this.result_do_highlight(do_high);
@ -694,7 +759,7 @@
}; };
Chosen.prototype.no_results = function(terms) { Chosen.prototype.no_results = function(terms) {
var no_results_html; var no_results_html;
no_results_html = $('<li class="no-results">No results match "<span></span>"</li>'); no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
no_results_html.find("span").first().html(terms); no_results_html.find("span").first().html(terms);
return this.search_results.append(no_results_html); return this.search_results.append(no_results_html);
}; };

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,7 @@
// Chosen, a Select Box Enhancer for jQuery and Protoype // Chosen, a Select Box Enhancer for jQuery and Protoype
// by Patrick Filler for Harvest, http://getharvest.com // by Patrick Filler for Harvest, http://getharvest.com
// //
// Version 0.9.1 // Version 0.9.5
// Full source at https://github.com/harvesthq/chosen // Full source at https://github.com/harvesthq/chosen
// Copyright (c) 2011 Harvest http://getharvest.com // Copyright (c) 2011 Harvest http://getharvest.com
@ -53,7 +53,9 @@
html: option.innerHTML, html: option.innerHTML,
selected: option.selected, selected: option.selected,
disabled: group_disabled === true ? group_disabled : option.disabled, disabled: group_disabled === true ? group_disabled : option.disabled,
group_array_index: group_position group_array_index: group_position,
classes: option.className,
style: option.style.cssText
}); });
} else { } else {
this.parsed.push({ this.parsed.push({
@ -83,13 +85,15 @@
/* /*
Chosen source: generate output using 'cake build' Chosen source: generate output using 'cake build'
Copyright (c) 2011 by Harvest Copyright (c) 2011 by Harvest
*/ var AbstractChosen, root; */
var AbstractChosen, root;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
root = this; root = this;
AbstractChosen = (function() { AbstractChosen = (function() {
function AbstractChosen(elmn) { function AbstractChosen(form_field, options) {
this.form_field = form_field;
this.options = options != null ? options : {};
this.set_default_values(); this.set_default_values();
this.form_field = elmn;
this.is_multiple = this.form_field.multiple; this.is_multiple = this.form_field.multiple;
this.default_text_default = this.is_multiple ? "Select Some Options" : "Select an Option"; this.default_text_default = this.is_multiple ? "Select Some Options" : "Select an Option";
this.setup(); this.setup();
@ -101,12 +105,18 @@
this.click_test_action = __bind(function(evt) { this.click_test_action = __bind(function(evt) {
return this.test_active_click(evt); return this.test_active_click(evt);
}, this); }, this);
this.activate_action = __bind(function(evt) {
return this.activate_field(evt);
}, this);
this.active_field = false; this.active_field = false;
this.mouse_on_container = false; this.mouse_on_container = false;
this.results_showing = false; this.results_showing = false;
this.result_highlighted = null; this.result_highlighted = null;
this.result_single_selected = null; this.result_single_selected = null;
return this.choices = 0; this.allow_single_deselect = (this.options.allow_single_deselect != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
this.disable_search_threshold = this.options.disable_search_threshold || 0;
this.choices = 0;
return this.results_none_found = this.options.no_results_text || "No results match";
}; };
AbstractChosen.prototype.mouse_enter = function() { AbstractChosen.prototype.mouse_enter = function() {
return this.mouse_on_container = true; return this.mouse_on_container = true;
@ -130,7 +140,7 @@
} }
}; };
AbstractChosen.prototype.result_add_option = function(option) { AbstractChosen.prototype.result_add_option = function(option) {
var classes; var classes, style;
if (!option.disabled) { if (!option.disabled) {
option.dom_id = this.container_id + "_o_" + option.array_index; option.dom_id = this.container_id + "_o_" + option.array_index;
classes = option.selected && this.is_multiple ? [] : ["active-result"]; classes = option.selected && this.is_multiple ? [] : ["active-result"];
@ -140,7 +150,11 @@
if (option.group_array_index != null) { if (option.group_array_index != null) {
classes.push("group-option"); classes.push("group-option");
} }
return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.html + '</li>'; if (option.classes !== "") {
classes.push(option.classes);
}
style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : "";
return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '"' + style + '>' + option.html + '</li>';
} else { } else {
return ""; return "";
} }
@ -219,7 +233,8 @@
/* /*
Chosen source: generate output using 'cake build' Chosen source: generate output using 'cake build'
Copyright (c) 2011 by Harvest Copyright (c) 2011 by Harvest
*/ var Chosen, get_side_border_padding, root; */
var Chosen, get_side_border_padding, root;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; } function ctor() { this.constructor = child; }
@ -245,7 +260,7 @@
this.single_temp = new Template('<a href="javascript:void(0)" class="chzn-single"><span>#{default}</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>'); this.single_temp = new Template('<a href="javascript:void(0)" class="chzn-single"><span>#{default}</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>');
this.multi_temp = new Template('<ul class="chzn-choices"><li class="search-field"><input type="text" value="#{default}" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'); this.multi_temp = new Template('<ul class="chzn-choices"><li class="search-field"><input type="text" value="#{default}" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>');
this.choice_temp = new Template('<li class="search-choice" id="#{id}"><span>#{choice}</span><a href="javascript:void(0)" class="search-choice-close" rel="#{position}"></a></li>'); this.choice_temp = new Template('<li class="search-choice" id="#{id}"><span>#{choice}</span><a href="javascript:void(0)" class="search-choice-close" rel="#{position}"></a></li>');
return this.no_results_temp = new Template('<li class="no-results">No results match "<span>#{terms}</span>"</li>'); return this.no_results_temp = new Template('<li class="no-results">' + this.results_none_found + ' "<span>#{terms}</span>"</li>');
}; };
Chosen.prototype.set_up_html = function() { Chosen.prototype.set_up_html = function() {
var base_template, container_props, dd_top, dd_width, sf_width; var base_template, container_props, dd_top, dd_width, sf_width;
@ -253,7 +268,7 @@
this.f_width = this.form_field.getStyle("width") ? parseInt(this.form_field.getStyle("width"), 10) : this.form_field.getWidth(); this.f_width = this.form_field.getStyle("width") ? parseInt(this.form_field.getStyle("width"), 10) : this.form_field.getWidth();
container_props = { container_props = {
'id': this.container_id, 'id': this.container_id,
'class': "chzn-container " + (this.is_rtl ? 'chzn-rtl' : ''), 'class': "chzn-container" + (this.is_rtl ? ' chzn-rtl' : ''),
'style': 'width: ' + this.f_width + 'px' 'style': 'width: ' + this.f_width + 'px'
}; };
this.default_text = this.form_field.readAttribute('data-placeholder') ? this.form_field.readAttribute('data-placeholder') : this.default_text_default; this.default_text = this.form_field.readAttribute('data-placeholder') ? this.form_field.readAttribute('data-placeholder') : this.default_text_default;
@ -267,6 +282,9 @@
}); });
this.container = $(this.container_id); this.container = $(this.container_id);
this.container.addClassName("chzn-container-" + (this.is_multiple ? "multi" : "single")); this.container.addClassName("chzn-container-" + (this.is_multiple ? "multi" : "single"));
if (!this.is_multiple && this.form_field.options.length <= this.disable_search_threshold) {
this.container.addClassName("chzn-container-single-nosearch");
}
this.dropdown = this.container.down('div.chzn-drop'); this.dropdown = this.container.down('div.chzn-drop');
dd_top = this.container.getHeight(); dd_top = this.container.getHeight();
dd_width = this.f_width - get_side_border_padding(this.dropdown); dd_width = this.f_width - get_side_border_padding(this.dropdown);
@ -296,6 +314,9 @@
this.container.observe("mousedown", __bind(function(evt) { this.container.observe("mousedown", __bind(function(evt) {
return this.container_mousedown(evt); return this.container_mousedown(evt);
}, this)); }, this));
this.container.observe("mouseup", __bind(function(evt) {
return this.container_mouseup(evt);
}, this));
this.container.observe("mouseenter", __bind(function(evt) { this.container.observe("mouseenter", __bind(function(evt) {
return this.mouse_enter(evt); return this.mouse_enter(evt);
}, this)); }, this));
@ -330,17 +351,33 @@
return this.search_field.observe("focus", __bind(function(evt) { return this.search_field.observe("focus", __bind(function(evt) {
return this.input_focus(evt); return this.input_focus(evt);
}, this)); }, this));
}
};
Chosen.prototype.search_field_disabled = function() {
this.is_disabled = this.form_field.disabled;
if (this.is_disabled) {
this.container.addClassName('chzn-disabled');
this.search_field.disabled = true;
if (!this.is_multiple) {
this.selected_item.stopObserving("focus", this.activate_action);
}
return this.close_field();
} else { } else {
return this.selected_item.observe("focus", __bind(function(evt) { this.container.removeClassName('chzn-disabled');
return this.activate_field(evt); this.search_field.disabled = false;
}, this)); if (!this.is_multiple) {
return this.selected_item.observe("focus", this.activate_action);
}
} }
}; };
Chosen.prototype.container_mousedown = function(evt) { Chosen.prototype.container_mousedown = function(evt) {
var target_closelink;
if (!this.is_disabled) {
target_closelink = evt != null ? evt.target.hasClassName("search-choice-close") : false;
if (evt && evt.type === "mousedown") { if (evt && evt.type === "mousedown") {
evt.stop(); evt.stop();
} }
if (!this.pending_destroy_click) { if (!this.pending_destroy_click && !target_closelink) {
if (!this.active_field) { if (!this.active_field) {
if (this.is_multiple) { if (this.is_multiple) {
this.search_field.clear(); this.search_field.clear();
@ -354,6 +391,12 @@
} else { } else {
return this.pending_destroy_click = false; return this.pending_destroy_click = false;
} }
}
};
Chosen.prototype.container_mouseup = function(evt) {
if (evt.target.nodeName === "ABBR") {
return this.results_reset(evt);
}
}; };
Chosen.prototype.blur_test = function(evt) { Chosen.prototype.blur_test = function(evt) {
if (!this.active_field && this.container.hasClassName("chzn-container-active")) { if (!this.active_field && this.container.hasClassName("chzn-container-active")) {
@ -414,9 +457,15 @@
this.choice_build(data); this.choice_build(data);
} else if (data.selected && !this.is_multiple) { } else if (data.selected && !this.is_multiple) {
this.selected_item.down("span").update(data.html); this.selected_item.down("span").update(data.html);
if (this.allow_single_deselect) {
this.selected_item.down("span").insert({
after: "<abbr class=\"search-choice-close\"></abbr>"
});
} }
} }
} }
}
this.search_field_disabled();
this.show_search_field_default(); this.show_search_field_default();
this.search_field_scale(); this.search_field_scale();
this.search_results.update(content); this.search_results.update(content);
@ -546,8 +595,10 @@
}; };
Chosen.prototype.choice_destroy_link_click = function(evt) { Chosen.prototype.choice_destroy_link_click = function(evt) {
evt.preventDefault(); evt.preventDefault();
if (!this.is_disabled) {
this.pending_destroy_click = true; this.pending_destroy_click = true;
return this.choice_destroy(evt.target); return this.choice_destroy(evt.target);
}
}; };
Chosen.prototype.choice_destroy = function(link) { Chosen.prototype.choice_destroy = function(link) {
this.choices -= 1; this.choices -= 1;
@ -558,17 +609,30 @@
this.result_deselect(link.readAttribute("rel")); this.result_deselect(link.readAttribute("rel"));
return link.up('li').remove(); return link.up('li').remove();
}; };
Chosen.prototype.results_reset = function(evt) {
this.form_field.options[0].selected = true;
this.selected_item.down("span").update(this.default_text);
this.show_search_field_default();
evt.target.remove();
if (typeof Event.simulate === 'function') {
this.form_field.simulate("change");
}
if (this.active_field) {
return this.results_hide();
}
};
Chosen.prototype.result_select = function(evt) { Chosen.prototype.result_select = function(evt) {
var high, item, position; var high, item, position;
if (this.result_highlight) { if (this.result_highlight) {
high = this.result_highlight; high = this.result_highlight;
this.result_clear_highlight(); this.result_clear_highlight();
high.addClassName("result-selected");
if (this.is_multiple) { if (this.is_multiple) {
this.result_deactivate(high); this.result_deactivate(high);
} else { } else {
this.search_results.descendants(".result-selected").invoke("removeClassName", "result-selected");
this.result_single_selected = high; this.result_single_selected = high;
} }
high.addClassName("result-selected");
position = high.id.substr(high.id.lastIndexOf("_") + 1); position = high.id.substr(high.id.lastIndexOf("_") + 1);
item = this.results_data[position]; item = this.results_data[position];
item.selected = true; item.selected = true;
@ -577,6 +641,11 @@
this.choice_build(item); this.choice_build(item);
} else { } else {
this.selected_item.down("span").update(item.html); this.selected_item.down("span").update(item.html);
if (this.allow_single_deselect) {
this.selected_item.down("span").insert({
after: "<abbr class=\"search-choice-close\"></abbr>"
});
}
} }
if (!(evt.metaKey && this.is_multiple)) { if (!(evt.metaKey && this.is_multiple)) {
this.results_hide(); this.results_hide();
@ -589,10 +658,10 @@
} }
}; };
Chosen.prototype.result_activate = function(el) { Chosen.prototype.result_activate = function(el) {
return el.addClassName("active-result").show(); return el.addClassName("active-result");
}; };
Chosen.prototype.result_deactivate = function(el) { Chosen.prototype.result_deactivate = function(el) {
return el.removeClassName("active-result").hide(); return el.removeClassName("active-result");
}; };
Chosen.prototype.result_deselect = function(pos) { Chosen.prototype.result_deselect = function(pos) {
var result, result_data; var result, result_data;
@ -685,7 +754,7 @@
var do_high; var do_high;
if (!this.result_highlight) { if (!this.result_highlight) {
if (!this.is_multiple) { if (!this.is_multiple) {
do_high = this.search_results.down(".result-selected"); do_high = this.search_results.down(".result-selected.active-result");
} }
if (!(do_high != null)) { if (!(do_high != null)) {
do_high = this.search_results.down(".active-result"); do_high = this.search_results.down(".active-result");
@ -818,19 +887,6 @@
Prototype.BrowserFeatures['Version'] = new Number(RegExp.$1); Prototype.BrowserFeatures['Version'] = new Number(RegExp.$1);
} }
} }
document.observe('dom:loaded', function(evt) {
var select, selects, _i, _len, _results;
if (Prototype.Browser.IE && (Prototype.BrowserFeatures['Version'] === 6 || Prototype.BrowserFeatures['Version'] === 7)) {
return;
}
selects = $$(".chzn-select");
_results = [];
for (_i = 0, _len = selects.length; _i < _len; _i++) {
select = selects[_i];
_results.push(new Chosen(select));
}
return _results;
});
get_side_border_padding = function(elmt) { get_side_border_padding = function(elmt) {
var layout, side_border_padding; var layout, side_border_padding;
layout = new Element.Layout(elmt); layout = new Element.Layout(elmt);

File diff suppressed because one or more lines are too long

View file

@ -6,11 +6,10 @@ root = this
$ = jQuery $ = jQuery
$.fn.extend({ $.fn.extend({
chosen: (data, options) -> chosen: (options) ->
# Do no harm and return as soon as possible for unsupported browsers, namely IE6 and IE7
return this if $.browser is "msie" and ($.browser.version is "6.0" or $.browser.version is "7.0") return this if $.browser is "msie" and ($.browser.version is "6.0" or $.browser.version is "7.0")
$(this).each((input_field) -> $(this).each((input_field) ->
new Chosen(this, data, options) unless ($ this).hasClass "chzn-done" new Chosen(this, options) unless ($ this).hasClass "chzn-done"
) )
}) })
@ -27,13 +26,13 @@ class Chosen extends AbstractChosen
@container_id = if @form_field.id.length then @form_field.id.replace(/(:|\.)/g, '_') else this.generate_field_id() @container_id = if @form_field.id.length then @form_field.id.replace(/(:|\.)/g, '_') else this.generate_field_id()
@container_id += "_chzn" @container_id += "_chzn"
@f_width = @form_field_jq.width() @f_width = @form_field_jq.outerWidth()
@default_text = if @form_field_jq.data 'placeholder' then @form_field_jq.data 'placeholder' else @default_text_default @default_text = if @form_field_jq.data 'placeholder' then @form_field_jq.data 'placeholder' else @default_text_default
container_div = ($ "<div />", { container_div = ($ "<div />", {
id: @container_id id: @container_id
class: "chzn-container #{ if @is_rtl then 'chzn-rtl' else '' }" class: "chzn-container#{ if @is_rtl then ' chzn-rtl' else '' }"
style: 'width: ' + (@f_width) + 'px;' #use parens around @f_width so coffeescript doesn't think + ' px' is a function parameter style: 'width: ' + (@f_width) + 'px;' #use parens around @f_width so coffeescript doesn't think + ' px' is a function parameter
}) })
@ -45,6 +44,7 @@ class Chosen extends AbstractChosen
@form_field_jq.hide().after container_div @form_field_jq.hide().after container_div
@container = ($ '#' + @container_id) @container = ($ '#' + @container_id)
@container.addClass( "chzn-container-" + (if @is_multiple then "multi" else "single") ) @container.addClass( "chzn-container-" + (if @is_multiple then "multi" else "single") )
@container.addClass "chzn-container-single-nosearch" if not @is_multiple and @form_field.options.length <= @disable_search_threshold
@dropdown = @container.find('div.chzn-drop').first() @dropdown = @container.find('div.chzn-drop').first()
dd_top = @container.height() dd_top = @container.height()
@ -73,6 +73,7 @@ class Chosen extends AbstractChosen
register_observers: -> register_observers: ->
@container.mousedown (evt) => this.container_mousedown(evt) @container.mousedown (evt) => this.container_mousedown(evt)
@container.mouseup (evt) => this.container_mouseup(evt)
@container.mouseenter (evt) => this.mouse_enter(evt) @container.mouseenter (evt) => this.mouse_enter(evt)
@container.mouseleave (evt) => this.mouse_leave(evt) @container.mouseleave (evt) => this.mouse_leave(evt)
@ -89,13 +90,25 @@ class Chosen extends AbstractChosen
if @is_multiple if @is_multiple
@search_choices.click (evt) => this.choices_click(evt) @search_choices.click (evt) => this.choices_click(evt)
@search_field.focus (evt) => this.input_focus(evt) @search_field.focus (evt) => this.input_focus(evt)
search_field_disabled: ->
@is_disabled = @form_field_jq.attr 'disabled'
if(@is_disabled)
@container.addClass 'chzn-disabled'
@search_field.attr 'disabled', true
@selected_item.unbind "focus", @activate_action if !@is_multiple
this.close_field()
else else
@selected_item.focus (evt) => this.activate_field(evt) @container.removeClass 'chzn-disabled'
@search_field.attr 'disabled', false
@selected_item.bind "focus", @activate_action if !@is_multiple
container_mousedown: (evt) -> container_mousedown: (evt) ->
if !@is_disabled
target_closelink = if evt? then ($ evt.target).hasClass "search-choice-close" else false
if evt and evt.type is "mousedown" if evt and evt.type is "mousedown"
evt.stopPropagation() evt.stopPropagation()
if not @pending_destroy_click if not @pending_destroy_click and not target_closelink
if not @active_field if not @active_field
@search_field.val "" if @is_multiple @search_field.val "" if @is_multiple
$(document).click @click_test_action $(document).click @click_test_action
@ -108,6 +121,9 @@ class Chosen extends AbstractChosen
else else
@pending_destroy_click = false @pending_destroy_click = false
container_mouseup: (evt) ->
this.results_reset(evt) if evt.target.nodeName is "ABBR"
blur_test: (evt) -> blur_test: (evt) ->
this.close_field() if not @active_field and @container.hasClass "chzn-container-active" this.close_field() if not @active_field and @container.hasClass "chzn-container-active"
@ -167,7 +183,9 @@ class Chosen extends AbstractChosen
this.choice_build data this.choice_build data
else if data.selected and not @is_multiple else if data.selected and not @is_multiple
@selected_item.find("span").text data.text @selected_item.find("span").text data.text
@selected_item.find("span").first().after "<abbr class=\"search-choice-close\"></abbr>" if @allow_single_deselect
this.search_field_disabled()
this.show_search_field_default() this.show_search_field_default()
this.search_field_scale() this.search_field_scale()
@ -274,8 +292,11 @@ class Chosen extends AbstractChosen
choice_destroy_link_click: (evt) -> choice_destroy_link_click: (evt) ->
evt.preventDefault() evt.preventDefault()
if not @is_disabled
@pending_destroy_click = true @pending_destroy_click = true
this.choice_destroy $(evt.target) this.choice_destroy $(evt.target)
else
evt.stopPropagation
choice_destroy: (link) -> choice_destroy: (link) ->
@choices -= 1 @choices -= 1
@ -286,6 +307,14 @@ class Chosen extends AbstractChosen
this.result_deselect (link.attr "rel") this.result_deselect (link.attr "rel")
link.parents('li').first().remove() link.parents('li').first().remove()
results_reset: (evt) ->
@form_field.options[0].selected = true
@selected_item.find("span").text @default_text
this.show_search_field_default()
$(evt.target).remove();
@form_field_jq.trigger "change"
this.results_hide() if @active_field
result_select: (evt) -> result_select: (evt) ->
if @result_highlight if @result_highlight
high = @result_highlight high = @result_highlight
@ -293,13 +322,14 @@ class Chosen extends AbstractChosen
this.result_clear_highlight() this.result_clear_highlight()
high.addClass "result-selected"
if @is_multiple if @is_multiple
this.result_deactivate high this.result_deactivate high
else else
@search_results.find(".result-selected").removeClass "result-selected"
@result_single_selected = high @result_single_selected = high
high.addClass "result-selected"
position = high_id.substr(high_id.lastIndexOf("_") + 1 ) position = high_id.substr(high_id.lastIndexOf("_") + 1 )
item = @results_data[position] item = @results_data[position]
item.selected = true item.selected = true
@ -310,6 +340,7 @@ class Chosen extends AbstractChosen
this.choice_build item this.choice_build item
else else
@selected_item.find("span").first().text item.text @selected_item.find("span").first().text item.text
@selected_item.find("span").first().after "<abbr class=\"search-choice-close\"></abbr>" if @allow_single_deselect
this.results_hide() unless evt.metaKey and @is_multiple this.results_hide() unless evt.metaKey and @is_multiple
@ -319,10 +350,10 @@ class Chosen extends AbstractChosen
this.search_field_scale() this.search_field_scale()
result_activate: (el) -> result_activate: (el) ->
el.addClass("active-result").show() el.addClass("active-result")
result_deactivate: (el) -> result_deactivate: (el) ->
el.removeClass("active-result").hide() el.removeClass("active-result")
result_deselect: (pos) -> result_deselect: (pos) ->
result_data = @results_data[pos] result_data = @results_data[pos]
@ -404,13 +435,13 @@ class Chosen extends AbstractChosen
winnow_results_set_highlight: -> winnow_results_set_highlight: ->
if not @result_highlight if not @result_highlight
selected_results = if not @is_multiple then @search_results.find(".result-selected") else [] 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() 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: (terms) ->
no_results_html = $('<li class="no-results">No results match "<span></span>"</li>') no_results_html = $('<li class="no-results">' + @results_none_found + ' "<span></span>"</li>')
no_results_html.find("span").first().html(terms) no_results_html.find("span").first().html(terms)
@search_results.append no_results_html @search_results.append no_results_html
@ -475,7 +506,6 @@ class Chosen extends AbstractChosen
this.keydown_arrow() this.keydown_arrow()
break break
search_field_scale: -> search_field_scale: ->
if @is_multiple if @is_multiple
h = 0 h = 0

View file

@ -19,7 +19,7 @@ class Chosen extends AbstractChosen
@single_temp = new Template('<a href="javascript:void(0)" class="chzn-single"><span>#{default}</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>') @single_temp = new Template('<a href="javascript:void(0)" class="chzn-single"><span>#{default}</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>')
@multi_temp = new Template('<ul class="chzn-choices"><li class="search-field"><input type="text" value="#{default}" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>') @multi_temp = new Template('<ul class="chzn-choices"><li class="search-field"><input type="text" value="#{default}" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>')
@choice_temp = new Template('<li class="search-choice" id="#{id}"><span>#{choice}</span><a href="javascript:void(0)" class="search-choice-close" rel="#{position}"></a></li>') @choice_temp = new Template('<li class="search-choice" id="#{id}"><span>#{choice}</span><a href="javascript:void(0)" class="search-choice-close" rel="#{position}"></a></li>')
@no_results_temp = new Template('<li class="no-results">No results match "<span>#{terms}</span>"</li>') @no_results_temp = new Template('<li class="no-results">' + @results_none_found + ' "<span>#{terms}</span>"</li>')
set_up_html: -> set_up_html: ->
@container_id = @form_field.identify().replace(/(:|\.)/g, '_') + "_chzn" @container_id = @form_field.identify().replace(/(:|\.)/g, '_') + "_chzn"
@ -28,7 +28,7 @@ class Chosen extends AbstractChosen
container_props = container_props =
'id': @container_id 'id': @container_id
'class': "chzn-container #{ if @is_rtl then 'chzn-rtl' else '' }" 'class': "chzn-container#{ if @is_rtl then ' chzn-rtl' else '' }"
'style': 'width: ' + (@f_width) + 'px' #use parens around @f_width so coffeescript doesn't think + ' px' is a function parameter 'style': 'width: ' + (@f_width) + 'px' #use parens around @f_width so coffeescript doesn't think + ' px' is a function parameter
@default_text = if @form_field.readAttribute 'data-placeholder' then @form_field.readAttribute 'data-placeholder' else @default_text_default @default_text = if @form_field.readAttribute 'data-placeholder' then @form_field.readAttribute 'data-placeholder' else @default_text_default
@ -38,6 +38,7 @@ class Chosen extends AbstractChosen
@form_field.hide().insert({ after: base_template }) @form_field.hide().insert({ after: base_template })
@container = $(@container_id) @container = $(@container_id)
@container.addClassName( "chzn-container-" + (if @is_multiple then "multi" else "single") ) @container.addClassName( "chzn-container-" + (if @is_multiple then "multi" else "single") )
@container.addClassName "chzn-container-single-nosearch" if not @is_multiple and @form_field.options.length <= @disable_search_threshold
@dropdown = @container.down('div.chzn-drop') @dropdown = @container.down('div.chzn-drop')
dd_top = @container.getHeight() dd_top = @container.getHeight()
@ -65,6 +66,7 @@ class Chosen extends AbstractChosen
register_observers: -> register_observers: ->
@container.observe "mousedown", (evt) => this.container_mousedown(evt) @container.observe "mousedown", (evt) => this.container_mousedown(evt)
@container.observe "mouseup", (evt) => this.container_mouseup(evt)
@container.observe "mouseenter", (evt) => this.mouse_enter(evt) @container.observe "mouseenter", (evt) => this.mouse_enter(evt)
@container.observe "mouseleave", (evt) => this.mouse_leave(evt) @container.observe "mouseleave", (evt) => this.mouse_leave(evt)
@ -81,13 +83,25 @@ class Chosen extends AbstractChosen
if @is_multiple if @is_multiple
@search_choices.observe "click", (evt) => this.choices_click(evt) @search_choices.observe "click", (evt) => this.choices_click(evt)
@search_field.observe "focus", (evt) => this.input_focus(evt) @search_field.observe "focus", (evt) => this.input_focus(evt)
search_field_disabled: ->
@is_disabled = @form_field.disabled
if(@is_disabled)
@container.addClassName 'chzn-disabled'
@search_field.disabled = true
@selected_item.stopObserving "focus", @activate_action if !@is_multiple
this.close_field()
else else
@selected_item.observe "focus", (evt) => this.activate_field(evt) @container.removeClassName 'chzn-disabled'
@search_field.disabled = false
@selected_item.observe "focus", @activate_action if !@is_multiple
container_mousedown: (evt) -> container_mousedown: (evt) ->
if !@is_disabled
target_closelink = if evt? then evt.target.hasClassName "search-choice-close" else false
if evt and evt.type is "mousedown" if evt and evt.type is "mousedown"
evt.stop() evt.stop()
if not @pending_destroy_click if not @pending_destroy_click and not target_closelink
if not @active_field if not @active_field
@search_field.clear() if @is_multiple @search_field.clear() if @is_multiple
document.observe "click", @click_test_action document.observe "click", @click_test_action
@ -99,6 +113,9 @@ class Chosen extends AbstractChosen
else else
@pending_destroy_click = false @pending_destroy_click = false
container_mouseup: (evt) ->
this.results_reset(evt) if evt.target.nodeName is "ABBR"
blur_test: (evt) -> blur_test: (evt) ->
this.close_field() if not @active_field and @container.hasClassName("chzn-container-active") this.close_field() if not @active_field and @container.hasClassName("chzn-container-active")
@ -158,7 +175,9 @@ class Chosen extends AbstractChosen
this.choice_build data this.choice_build data
else if data.selected and not @is_multiple else if data.selected and not @is_multiple
@selected_item.down("span").update( data.html ) @selected_item.down("span").update( data.html )
@selected_item.down("span").insert { after: "<abbr class=\"search-choice-close\"></abbr>" } if @allow_single_deselect
this.search_field_disabled()
this.show_search_field_default() this.show_search_field_default()
this.search_field_scale() this.search_field_scale()
@ -268,6 +287,7 @@ class Chosen extends AbstractChosen
choice_destroy_link_click: (evt) -> choice_destroy_link_click: (evt) ->
evt.preventDefault() evt.preventDefault()
if not @is_disabled
@pending_destroy_click = true @pending_destroy_click = true
this.choice_destroy evt.target this.choice_destroy evt.target
@ -280,18 +300,27 @@ class Chosen extends AbstractChosen
this.result_deselect link.readAttribute("rel") this.result_deselect link.readAttribute("rel")
link.up('li').remove() link.up('li').remove()
results_reset: (evt) ->
@form_field.options[0].selected = true
@selected_item.down("span").update(@default_text)
this.show_search_field_default()
evt.target.remove()
@form_field.simulate("change") if typeof Event.simulate is 'function'
this.results_hide() if @active_field
result_select: (evt) -> result_select: (evt) ->
if @result_highlight if @result_highlight
high = @result_highlight high = @result_highlight
this.result_clear_highlight() this.result_clear_highlight()
high.addClassName("result-selected")
if @is_multiple if @is_multiple
this.result_deactivate high this.result_deactivate high
else else
@search_results.descendants(".result-selected").invoke "removeClassName", "result-selected"
@result_single_selected = high @result_single_selected = high
high.addClassName("result-selected")
position = high.id.substr(high.id.lastIndexOf("_") + 1 ) position = high.id.substr(high.id.lastIndexOf("_") + 1 )
item = @results_data[position] item = @results_data[position]
item.selected = true item.selected = true
@ -302,6 +331,7 @@ class Chosen extends AbstractChosen
this.choice_build item this.choice_build item
else else
@selected_item.down("span").update(item.html) @selected_item.down("span").update(item.html)
@selected_item.down("span").insert { after: "<abbr class=\"search-choice-close\"></abbr>" } if @allow_single_deselect
this.results_hide() unless evt.metaKey and @is_multiple this.results_hide() unless evt.metaKey and @is_multiple
@ -311,10 +341,10 @@ class Chosen extends AbstractChosen
this.search_field_scale() this.search_field_scale()
result_activate: (el) -> result_activate: (el) ->
el.addClassName("active-result").show() el.addClassName("active-result")
result_deactivate: (el) -> result_deactivate: (el) ->
el.removeClassName("active-result").hide() el.removeClassName("active-result")
result_deselect: (pos) -> result_deselect: (pos) ->
result_data = @results_data[pos] result_data = @results_data[pos]
@ -396,7 +426,7 @@ class Chosen extends AbstractChosen
if not @result_highlight if not @result_highlight
if not @is_multiple if not @is_multiple
do_high = @search_results.down(".result-selected") do_high = @search_results.down(".result-selected.active-result")
if not do_high? if not do_high?
do_high = @search_results.down(".active-result") do_high = @search_results.down(".active-result")
@ -500,13 +530,6 @@ if Prototype.Browser.IE
Prototype.BrowserFeatures['Version'] = new Number(RegExp.$1); Prototype.BrowserFeatures['Version'] = new Number(RegExp.$1);
document.observe 'dom:loaded', (evt) ->
# Do no harm and return as soon as possible for unsupported browsers, namely IE6 and IE7
return if Prototype.Browser.IE and (Prototype.BrowserFeatures['Version'] is 6 or Prototype.BrowserFeatures['Version'] is 7)
selects = $$(".chzn-select")
new Chosen select for select in selects
get_side_border_padding = (elmt) -> get_side_border_padding = (elmt) ->
layout = new Element.Layout(elmt) layout = new Element.Layout(elmt)
side_border_padding = layout.get("border-left") + layout.get("border-right") + layout.get("padding-left") + layout.get("padding-right") side_border_padding = layout.get("border-left") + layout.get("border-right") + layout.get("padding-left") + layout.get("padding-right")

View file

@ -6,10 +6,9 @@ root = this
class AbstractChosen class AbstractChosen
constructor: (elmn) -> constructor: (@form_field, @options={}) ->
this.set_default_values() this.set_default_values()
@form_field = elmn
@is_multiple = @form_field.multiple @is_multiple = @form_field.multiple
@default_text_default = if @is_multiple then "Select Some Options" else "Select an Option" @default_text_default = if @is_multiple then "Select Some Options" else "Select an Option"
@ -22,12 +21,16 @@ class AbstractChosen
set_default_values: -> set_default_values: ->
@click_test_action = (evt) => this.test_active_click(evt) @click_test_action = (evt) => this.test_active_click(evt)
@activate_action = (evt) => this.activate_field(evt)
@active_field = false @active_field = false
@mouse_on_container = false @mouse_on_container = false
@results_showing = false @results_showing = false
@result_highlighted = null @result_highlighted = null
@result_single_selected = null @result_single_selected = null
@allow_single_deselect = if @options.allow_single_deselect? and @form_field.options[0].text == "" then @options.allow_single_deselect else false
@disable_search_threshold = @options.disable_search_threshold || 0
@choices = 0 @choices = 0
@results_none_found = @options.no_results_text or "No results match"
mouse_enter: -> @mouse_on_container = true mouse_enter: -> @mouse_on_container = true
mouse_leave: -> @mouse_on_container = false mouse_leave: -> @mouse_on_container = false
@ -47,8 +50,11 @@ class AbstractChosen
classes = if option.selected and @is_multiple then [] else ["active-result"] classes = if option.selected and @is_multiple then [] else ["active-result"]
classes.push "result-selected" if option.selected classes.push "result-selected" if option.selected
classes.push "group-option" if option.group_array_index? classes.push "group-option" if option.group_array_index?
classes.push option.classes if option.classes != ""
'<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.html + '</li>' style = if option.style.cssText != "" then " style=\"#{option.style}\"" else ""
'<li id="' + option.dom_id + '" class="' + classes.join(' ') + '"'+style+'>' + option.html + '</li>'
else else
"" ""

View file

@ -34,6 +34,8 @@ class SelectParser
selected: option.selected selected: option.selected
disabled: if group_disabled is true then group_disabled else option.disabled disabled: if group_disabled is true then group_disabled else option.disabled
group_array_index: group_position group_array_index: group_position
classes: option.className
style: option.style.cssText
else else
@parsed.push @parsed.push
array_index: @parsed.length array_index: @parsed.length

View file

@ -1188,7 +1188,7 @@
</select> </select>
</div> </div>
<div> <div>
<em>Multiple Select with Groups</em> <em>Multiple Select</em>
<select data-placeholder="Your Favorite Types of Bear" style="width:350px;" multiple class="chzn-select" id="test_me" name="test_me_form" tabindex="8"> <select data-placeholder="Your Favorite Types of Bear" style="width:350px;" multiple class="chzn-select" id="test_me" name="test_me_form" tabindex="8">
<option value=""></option> <option value=""></option>
<option>American Black Bear</option> <option>American Black Bear</option>
@ -1210,6 +1210,32 @@
<p><strong>Note:</strong> on single selects, the first element is assumed to be selected by the browser. To take advantage of the default text support, you will need to include a blank option as the first element of your select list.</p> <p><strong>Note:</strong> on single selects, the first element is assumed to be selected by the browser. To take advantage of the default text support, you will need to include a blank option as the first element of your select list.</p>
</div> </div>
<h2>No Results Text Support</h2>
<div class="side-by-side clearfix">
<p>Setting the "No results" search text is as easy as passing an option when you create Chosen:</p>
<code>
$(".chzn-select").chosen({no_results_text: "No results matched"});
</code>
</div>
<h2>Allow Deselect on Single Selects</h2>
<div class="side-by-side clearfix">
<p>When a single select box isn't a required field, you can set <code>allow_single_deselect: true</code> and Chosen will add a UI element for option deselection. This will only work if the first option has blank text.</p>
<div class="side-by-side clearfix">
<select data-placeholder="Your Favorite Type of Bear" style="width:350px;" class="chzn-select-deselect" tabindex="7">
<option value=""></option>
<option>American Black Bear</option>
<option>Asiatic Black Bear</option>
<option>Brown Bear</option>
<option>Giant Panda</option>
<option selected>Sloth Bear</option>
<option>Sun Bear</option>
<option>Polar Bear</option>
<option>Spectacled Bear</option>
</select>
</div>
</div>
<h2>Right to Left Support</h2> <h2>Right to Left Support</h2>
<div class="side-by-side clearfix"> <div class="side-by-side clearfix">
<p>Chosen supports right to left select boxes too. just add <code>"chzn-rtl"</code> in addition to <code>"chzn-select"</code> to your select tags and you are good to go.</p> <p>Chosen supports right to left select boxes too. just add <code>"chzn-rtl"</code> in addition to <code>"chzn-select"</code> to your select tags and you are good to go.</p>
@ -1269,8 +1295,8 @@
</ol> </ol>
</div> </div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
<script src="chosen/chosen.jquery.js" type="text/javascript"></script> <script src="chosen/chosen.jquery.js" type="text/javascript"></script>
<script type="text/javascript"> $(".chzn-select").chosen(); </script> <script type="text/javascript"> $(".chzn-select").chosen(); $(".chzn-select-deselect").chosen({allow_single_deselect:true}); </script>
</form> </form>
</body> </body>

View file

@ -1187,7 +1187,7 @@
</select> </select>
</div> </div>
<div> <div>
<em>Multiple Select with Groups</em> <em>Multiple Select</em>
<select data-placeholder="Your Favorite Types of Bear" style="width:350px;" multiple class="chzn-select" tabindex="8"> <select data-placeholder="Your Favorite Types of Bear" style="width:350px;" multiple class="chzn-select" tabindex="8">
<option value=""></option> <option value=""></option>
<option>American Black Bear</option> <option>American Black Bear</option>
@ -1209,6 +1209,32 @@
<p><strong>Note:</strong> on single selects, the first element is assumed to be selected by the browser. To take advantage of the default text support, you will need to include a blank option as the first element of your select list.</p> <p><strong>Note:</strong> on single selects, the first element is assumed to be selected by the browser. To take advantage of the default text support, you will need to include a blank option as the first element of your select list.</p>
</div> </div>
<h2>No Results Text Support</h2>
<div class="side-by-side clearfix">
<p>Setting the "No results" search text is as easy as passing an option when you create Chosen:</p>
<code>
New Chosen($("chzn_select_field"),{no_results_text: "No results matched"});
</code>
</div>
<h2>Allow Deselect on Single Selects</h2>
<div class="side-by-side clearfix">
<p>When a single select box isn't a required field, you can set <code>allow_single_deselect: true</code> and Chosen will add a UI element for option deselection. This will only work if the first option has blank text.</p>
<div class="side-by-side clearfix">
<select data-placeholder="Your Favorite Type of Bear" style="width:350px;" class="chzn-select-deselect" tabindex="7">
<option value=""></option>
<option>American Black Bear</option>
<option>Asiatic Black Bear</option>
<option>Brown Bear</option>
<option>Giant Panda</option>
<option selected>Sloth Bear</option>
<option>Sun Bear</option>
<option>Polar Bear</option>
<option>Spectacled Bear</option>
</select>
</div>
</div>
<h2>Right to Left Support</h2> <h2>Right to Left Support</h2>
<div class="side-by-side clearfix"> <div class="side-by-side clearfix">
<p>Chosen supports right to left select boxes too. just add <code>"chzn-rtl"</code> in addition to <code>"chzn-select"</code> to your select tags and you are good to go.</p> <p>Chosen supports right to left select boxes too. just add <code>"chzn-rtl"</code> in addition to <code>"chzn-select"</code> to your select tags and you are good to go.</p>
@ -1263,11 +1289,31 @@
<p>Using Chosen is easy as can be.</p> <p>Using Chosen is easy as can be.</p>
<ol> <ol>
<li>Download the plugin and copy the chosen files to your app.</li> <li>Download the plugin and copy the chosen files to your app.</li>
<li>Add the class <em>chzn-select</em> to any select box.</li> <li>Activate the plugin by creating a new instance of Chosen: New Chosen(<em>some_form_field</em>);</li>
<li><a href="http://youtu.be/pS-RsIzb78U?t=57s">Disco</a>.</li> <li><a href="http://youtu.be/pS-RsIzb78U?t=57s">Disco</a>.</li>
</ol> </ol>
</div> </div>
<script src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js" type="text/javascript"></script> <script src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js" type="text/javascript"></script>
<script src="chosen/chosen.proto.js" type="text/javascript"></script> <script src="chosen/chosen.proto.js" type="text/javascript"></script>
<script type="text/javascript">
document.observe('dom:loaded', function(evt) {
var select, selects, _i, _len, _results;
if (Prototype.Browser.IE && (Prototype.BrowserFeatures['Version'] === 6 || Prototype.BrowserFeatures['Version'] === 7)) {
return;
}
selects = $$(".chzn-select");
_results = [];
for (_i = 0, _len = selects.length; _i < _len; _i++) {
select = selects[_i];
_results.push(new Chosen(select));
}
deselects = $$(".chzn-select-deselect");
for (_i = 0, _len = deselects.length; _i < _len; _i++) {
select = deselects[_i];
_results.push(new Chosen(select,{allow_single_deselect:true}));
}
return _results;
});
</script>
</body> </body>