Compare commits

...

123 commits

Author SHA1 Message Date
mlharvest 6a5d61b061 Merge pull request #464 from kristerkari/master
Fixes for gradients and Right to Left support
2012-02-03 12:59:59 -08:00
Krister Kari 75606a7434 Correctly working default cursor for .search-choice 2012-01-22 00:07:46 +02:00
Krister Kari 50e3db34ab Fix right to left in IE8 2012-01-21 23:58:35 +02:00
Krister Kari 4b6fe537d7 Fix gradients 2012-01-21 23:11:12 +02:00
mlharvest dc2eb014bd Merge pull request #457 from mlharvest/master
line-height: 24px
2012-01-20 07:23:59 -08:00
Matthew Lettini 7430fd54e4 single dropdown line-height 24px 2012-01-20 10:11:23 -05:00
Patrick Filler 5175cb809e Updating version numbers. 2012-01-19 17:52:30 -06:00
Patrick Filler c93a52b7e8 Version 0.9.7
- Package.json for node dependency dreaminess
- New lion-style design on single selects
2012-01-19 17:49:44 -06:00
Patrick Filler add519f2ad Merge branch 'master' of https://github.com/mlharvest/chosen into mlharvest-master
Conflicts:
	chosen/chosen.css
2012-01-19 17:44:39 -06:00
Patrick Filler dcbac1aba2 Merge branch 'cakephp-fork' of https://github.com/paulredmond/chosen into paulredmond-cakephp-fork
Conflicts:
	README.md
2012-01-19 16:41:26 -06:00
Patrick Filler 929253b6d9 Update package.json to latest versions of Coffeescript and Uglify 2012-01-19 16:14:38 -06:00
Matthew Lettini bd2cc547e4 remove trailing whitespace 2012-01-18 16:19:10 -05:00
Matthew Beale 5d23a35453 Update the README for package.json 2012-01-13 11:27:16 -05:00
Matthew Beale eb2b3285bc Update package.json to point at the older version of coffeescript (1.1.2) I believe @pfiller is using. 2012-01-13 11:13:54 -05:00
Matthew Beale 71c06c7da4 Add a package npm task and check in a generated file 2012-01-13 11:01:30 -05:00
Matthew Beale 04568d271e Merge remote branch 'snowfish/package.json' into package.json 2012-01-13 10:41:47 -05:00
Patrick Filler 8ce24bda89 Typo on Prototype example page 2012-01-12 17:17:57 -06:00
Patrick Filler 3b3eca5249 Merge branch 'master' of https://github.com/digger69/chosen into digger69-master
Conflicts:
	chosen/chosen.jquery.js
	chosen/chosen.jquery.min.js
	chosen/chosen.proto.js
	chosen/chosen.proto.min.js
2012-01-12 17:10:05 -06:00
Patrick Filler c9294d5943 Merge branch 'master' of https://github.com/mikefrey/chosen into mikefrey-master 2012-01-12 16:33:42 -06:00
Patrick Filler 0108f15866 Long overdue Version Update (0.0.6)
- Abstracted code for shared portions between Prototype/jQuery
- Trigger and event when Chosen is ready ("liszt:ready")
- Better performance for very large lists
2012-01-12 14:31:07 -06:00
Thomas Frössman 4f3a8bebdb package.json 2012-01-05 16:56:38 +01:00
Mark Nadig e400dc7a3a refs #404 - rebuilt js separately from change to .coffee for #403 - since many diffs in generated js. Want to see if harvest wants this. 2011-12-16 14:47:55 -07:00
Mark Nadig cf23dc522d resolves #403 - preventDefault for click on anchor 2011-12-16 14:32:32 -07:00
Mark Nadig 47bc14148f refs #191 - example $NODE_PATH 2011-12-16 14:30:28 -07:00
Mike Frey 5911d684f9 fixed esc keyup event propagation 2011-12-12 11:18:47 -06:00
Paul Redmond e85cf8481e Adding CakePHP plugin 2011-12-10 17:44:21 -07:00
Mike Frey a316ca88d6 Fixed: Esc key propagation stopped by implied return
https://github.com/harvesthq/chosen/issues/390
2011-12-09 16:39:35 -06:00
Patrick Filler 880a30dcb4 Change deselect icon position on Right-to-left selects.
Fixes #375
2011-12-08 12:26:21 -05:00
Matthew Lettini 7a0687e995 css for down/up arrows 2011-12-07 13:01:51 -05:00
Matthew Lettini 859425f782 updated chosen images 2011-12-07 12:20:50 -05:00
Matthew Lettini 50f2df47e7 taller default results 2011-12-06 18:04:05 -05:00
Matthew Lettini 89141f1493 update design of multi chosen, and dropdown list 2011-12-06 18:02:00 -05:00
Matthew Lettini 1ed5f7d5af update single chosen gradient and look 2011-12-06 17:37:45 -05:00
Patrick Filler 5808c97172 On container mousedown, make sure to compare the appropriate element.
Fixes #350.
2011-11-15 12:39:16 -05:00
Patrick Filler 31cd33f22b Change display property of groups to list-item when results match. Fixes #344 & Fixes #354. 2011-11-15 11:19:03 -05:00
Patrick Filler 16b6f5047a Use coffeescript existential operator and commit js changes. 2011-11-15 11:01:40 -05:00
Patrick Filler 9dd4fb51a8 Merge branch 'master' of https://github.com/jerrett/chosen into jerrett-master 2011-11-15 10:47:29 -05:00
Jerrett 5d0e5855c7 Revert "not explode on empty selects with allow_single_deselect"
This reverts commit 91502810c9.
2011-11-14 16:19:41 -08:00
Jerrett acf540ff21 changes to .coffee file instead 2011-11-14 16:18:18 -08:00
T.J. Schuck 875c800c7a Update README 2011-11-10 17:10:48 -05:00
Jerrett 91502810c9 not explode on empty selects with allow_single_deselect 2011-11-09 16:49:13 -08:00
Patrick Filler f87575cb75 Remove some old debugging code. 2011-11-04 15:51:16 -04:00
Patrick Filler f0a349d782 Remove condition made unnecessary by poorly written CoffeeScript. The text of an option was never matching this function, so why leave it there? 2011-11-04 15:48:50 -04:00
Patrick Filler 948fbcca11 Merge pull request #338 from grandall/master
JQuery performance improvements for long lists with option groups
2011-11-04 09:16:54 -07:00
Graham Randall 3ba2d65221 Fixed performance issues with large, grouped lists. 2011-11-03 18:21:02 -05:00
Patrick Filler a9d52581a5 Merge pull request #317 from kristerkari/master
Optimized Chosen sprite image 3.998 kb -> 0.396 kb
2011-11-02 12:01:02 -07:00
Patrick Filler 9bc5fdcfe0 Don't rely on jQuery's Attr function for disabled as it changes in 1.6 2011-11-02 12:41:54 -04:00
Patrick Filler 581f2073b5 Merge pull request #331 from Ownatik/master
Fixed disable_search_threshold being ignored when triggering a liszt:updated event
2011-11-02 09:22:55 -07:00
François Bernier 17c1e8e18e Fixed disable_search_threshold being ignored when triggering a liszt:updated event 2011-11-01 19:52:19 -04:00
Krister Kari 71b343ffd5 Optimize Chosen sprite 2011-10-25 00:52:10 +03:00
Patrick Filler 0f89ebef85 Merge branch 'sd-ready-event' of https://github.com/sd/chosen into sd-sd-ready-event
Conflicts:
	chosen/chosen.jquery.min.js
	chosen/chosen.proto.min.js
	coffee/chosen.proto.coffee
2011-10-24 13:36:14 -04:00
Patrick Filler c772be4cc1 Merge branch 'tab-select' of https://github.com/greatbigsolutions/chosen into greatbigsolutions-tab-select
Conflicts:
	chosen/chosen.jquery.min.js
	chosen/chosen.proto.min.js
2011-10-24 12:21:20 -04:00
Patrick Filler 84ee71187d Merge pull request #314 from seutje/patch-1
Changed Drupal module link to the more up-to-date one on drupal.org
2011-10-24 08:10:12 -07:00
Steve De Jonghe b3ff621d85 Changed Drupal module link to the more up-to-date one on drupal.org and adding main contributors to the list 2011-10-24 18:07:59 +03:00
Patrick Filler f09c117224 Remove duplicate CSS declaration. Fixes #307. 2011-10-24 11:05:37 -04:00
Patrick Filler 35e0680e75 Silly typo. 2011-10-24 11:02:26 -04:00
Patrick Filler 20a588d5b1 Remove duplicate line of CSS. Fixes #303 2011-10-20 13:54:35 -04:00
Patrick Filler fa35528d15 Make sure we have only one deselect control at a time.
Fixes #286 and #296
2011-10-17 12:30:54 -04:00
Patrick Filler 499c35b62d Merge pull request #290 from Carpe-Hora/jqueryui_dialog_compatibility
Fix: the search field did not work when in a jQueryUI modal dialog
2011-10-12 15:20:26 -07:00
Kévin Gomez Pinto a53b58f15a Fix: the search field did not work when in a jQueryUI modal dialog ; fixes #18 & #95
See https://github.com/harvesthq/chosen/issues/18#issuecomment-2311377 for more
details.

	modified:   chosen/chosen.css
2011-10-07 15:41:53 +02:00
Patrick Filler f618c69d54 Merge branch 'fix-old-ie-jquery-check' of https://github.com/greatbigsolutions/chosen into greatbigsolutions-fix-old-ie-jquery-check
Conflicts:
	chosen/chosen.jquery.js
	chosen/chosen.jquery.min.js
	coffee/chosen.jquery.coffee
2011-10-04 17:29:11 -04:00
Patrick Filler 4a48fbcd11 Merge pull request #199 from harvesthq/abstract-chosen
Introduce abstract-chosen, try to start sharing more code between platforms
2011-09-30 14:53:56 -07:00
Matthew Beale 47b7b4d6bc Merge master into abstract-chosen 2011-09-30 17:39:03 -04:00
Patrick Filler 1e49c19d20 Up version number to 0.9.5
- Allow disabling of Search on single select boxes with <= N options (#45).
- Retain original option styles
- Retain original option classes (#30)
- Fix show results bug when clicking close icon (#277)
2011-09-30 12:21:05 -04:00
Patrick Filler 1e9b4ddbe9 Single selects now allow disabled search below a certain option threshold. 2011-09-30 12:14:02 -04:00
Patrick Filler d87310ee5d Keep select option's original style, too. 2011-09-29 18:19:21 -04:00
Patrick Filler 7dd29088e8 Apply original option classes to Chosen's search results. 2011-09-29 17:32:58 -04:00
Patrick Filler cde5fc8e69 Don't show/hide results when deselecting option in single Chosen. 2011-09-29 16:48:12 -04:00
Patrick Filler 785020b189 Update chosen to 0.9.4
- Speed improvements
- Allow deselect on single select
- Support for disabled form field
- Make sure only active results get highlighted
2011-09-29 15:56:45 -04:00
Patrick Filler 6e10084329 PNG update (x icon bleeding into magnifying glass space) 2011-09-29 15:54:03 -04:00
Patrick Filler d4c7005b5c Using class-based show/hide instead of the jquery/prototype methods results in significant speed improvements for very, very large select boxes. (at least in modern web browsers) 2011-09-29 15:39:45 -04:00
Patrick Filler 953d3baa4f Fire the change event when deselecting a value. 2011-09-28 13:40:18 -04:00
Patrick Filler b7a9b218fb Insert deselect UI on initial load if a value is selected. 2011-09-28 13:30:39 -04:00
Patrick Filler fec3d3aafb Add deselect examples. 2011-09-28 13:29:00 -04:00
Patrick Filler 763eecf39f Merge pull request #274 from harvesthq/allow_deselect
Add allow deselect option
2011-09-28 09:23:02 -07:00
Patrick Filler eb2636838e When using allow_single_deselect, first element must have blank text. 2011-09-28 11:46:36 -04:00
Patrick Filler 5a783bbb96 Test for presence of event before using its target! 2011-09-28 11:31:10 -04:00
Patrick Filler 66e5da9dec Re-center deselect close icon. 2011-09-28 11:15:37 -04:00
Patrick Filler ed69a328c2 Larger delete/deselect targets for happier clicking. 2011-09-28 11:10:34 -04:00
Patrick Filler 81c084ec99 If deselecting when Chosen is open, close it up. 2011-09-27 16:57:51 -04:00
Patrick Filler 3b11f2e2d1 Create option to allow deselect on Chosen single selects. 2011-09-27 16:51:29 -04:00
Patrick Filler df394886e4 On single selects, remove the result-selected class from any previously selected options when selecting an option 2011-09-26 17:48:31 -04:00
Patrick Filler 85c436086f Make sure chosen doesn't stay "active" after form field becomes disabled. 2011-09-23 10:08:22 -05:00
Patrick Filler 6c6f3590bc If field is disabled, stop destroy choice clicks as well. 2011-09-23 09:46:01 -05:00
Patrick Filler 805a60f4a5 Renamed prototype example file. 2011-09-22 15:45:05 -05:00
Patrick Filler 255e77711e Update example to jquery 1.6.4 2011-09-22 15:44:41 -05:00
Patrick Filler 41831bb934 Fix sloppy spacing when applying chzn-rtl 2011-09-22 13:02:25 -05:00
Patrick Filler f1e1c559ea Add support for disabled form fields. 2011-09-22 12:44:00 -05:00
Adam Ford 208370bd0d Hitting Tab selects current highlighted option
While navigating through native selects using the keyboard, one can start
typing the text of the desired option to select it, then hit the Tab key
to move to the next element with the desired option remaining selected.
This doesn't work with Chosen currently (the correct option is highlighted,
but it is not selected once the Tab key is hit.)

Now the current highlighted option in a non-multiple Chosen select is
selected when the Tab key is hit.

Resolves #104.
2011-09-20 10:56:04 -06:00
Patrick Filler 91734e94ee Complied JS differs between coffescript versions. 2011-09-19 15:13:34 -05:00
Patrick Filler 6571967085 Merge branch 'highlight_active' of https://github.com/Nagyman/chosen into Nagyman-highlight_active
Conflicts:
	chosen/chosen.jquery.min.js
	chosen/chosen.proto.min.js
2011-09-19 15:10:09 -05:00
Patrick Filler b51d4a798f Merge pull request #258 from Nagyman/8922e6e85425bb48e09429a9c85b503088fbc9be
Use @ shortcut for constructor arguments
2011-09-19 13:05:17 -07:00
Nagyman 93dbe8efec Highlight the selected result only if it's active (matches the current search) 2011-09-17 07:56:53 -04:00
Nagyman 8922e6e854 Use @ shortcut for constructor arguments 2011-09-17 05:14:15 -04:00
Patrick Filler ada808db43 Make options default use the coffeescript way™ 2011-09-12 18:34:13 -04:00
Patrick Filler 8fdb2a9c1d Update example files with No Results Text details 2011-09-12 18:02:18 -04:00
Patrick Filler d9ae47eda4 Update version number to 0.9.3
- Calculate initial width based on OuterWidth, not Width (jQuery version)
- Options array implemented for jQuery / Prototype version
- Added 'no_results_text' option to override default "No Matches" text
- prototype version not created on initial load to more closely resemble jQuery version
2011-09-12 17:56:54 -04:00
Patrick Filler 2df646eaf0 Update example file to jQuery 1.6.3 2011-09-12 17:55:34 -04:00
Patrick Filler a7a8ad54e2 Make the prototype version more like the jQuery version (doesn't sniff for a class any longer) 2011-09-12 17:48:38 -04:00
Patrick Filler 800e3d5502 Add options object for both prototype and jquery version. 2011-09-12 17:31:10 -04:00
Patrick Filler 718f500c9a Merge branch 'master' of https://github.com/h3adache/chosen into h3adache-master
Conflicts:
	chosen/chosen.jquery.js
	chosen/chosen.jquery.min.js
	coffee/chosen.jquery.coffee
	example.jquery.html
2011-09-12 17:21:49 -04:00
Patrick Filler 15b9b5136f Chosen jQuery version uses outerWidth on initial load. 2011-09-12 16:03:29 -04:00
Patrick Filler eb8ee7366d Update version number in JS files, too 2011-09-12 16:02:39 -04:00
Patrick Filler 91763c7d79 Up version number:
- Display Chosen on MouseDown / Selections on MouseUp (not click)
- Don't apply Chosen to IE 7 and below
- Don't hide select fields with chzn-select class by default.
2011-09-12 15:46:40 -04:00
Adam Ford 4b9a5c68a5 Fixed jQuery check for IE6 and 7. 2011-09-02 13:09:32 -06:00
Patrick Filler 6193bd54de Merge pull request #217 from nikosd/patch-2
Fixed legend error in example (copy/paste error).
2011-08-25 08:07:33 -07:00
Nikos Dimitrakopoulos 38c32e5be9 Fixed legend error in example (copy/paste error). 2011-08-25 22:59:18 +03:00
Patrick Filler ea46e5d324 Merge pull request #216 from nikosd/patch-1
Fixed example legend (copy/paste error).
2011-08-25 08:07:12 -07:00
Nikos Dimitrakopoulos b0bc56c8ac Fixed example legend (copy/paste error). 2011-08-25 22:57:36 +03:00
Matthew Beale 4e463669d2 Introduce abstract-chosen, try to start sharing more code between platforms 2011-08-19 12:23:03 -04:00
Matthew Beale df6345465a Better report compilation errors during build 2011-08-19 11:41:59 -04:00
Patrick Filler 1d6df98c4e Fix merge conflicts caused by min version 2011-08-16 15:12:10 -04:00
Patrick Filler 57fcc576c3 Merge changes from #149 2011-08-16 14:52:18 -04:00
Patrick Filler 528d77bc04 No ctrl/command click when for single selects. 2011-08-08 11:37:56 -04:00
Patrick Filler d6137ad5be Merge branch 'master' of https://github.com/cleercode/chosen into cleercode-master 2011-08-08 11:16:12 -04:00
Patrick Filler 12a7a11720 Fix Typo in example 2011-08-05 15:16:57 -04:00
Sebastian Delmont 3bf68f6aef fire a liszt:ready event when Chosen is done generating the HTML, thus providing a hook for further customization 2011-08-05 12:25:33 -04:00
Tim Chen f9674e7db2 Make options an optional parameter 2011-08-04 09:18:40 -05:00
Patrick Filler b7a531f211 Merge pull request #141 from aziz/master
closes #139 and #140
2011-08-03 09:00:40 -07:00
Allen Bargi 8b223ec328 closes #139 and #140 2011-08-03 07:32:14 +02:00
Tim Chen 90ca300921 remove unused data constructor variable, make use of options 2011-08-02 15:16:14 -05:00
Patrick Filler 0812bc3d64 Highlight selected option in a single select on initial load.
Closes Gh-103
2011-08-01 16:14:13 -04:00
Chris Lee 110466a38f Ctrl/command-click to select without closing list. Related to #23 2011-07-22 17:27:08 -07:00
17 changed files with 1567 additions and 994 deletions

3
.gitignore vendored
View file

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

View file

@ -11,12 +11,14 @@ CoffeeScript = require 'coffee-script'
javascripts = { javascripts = {
'chosen/chosen.jquery.js': [ 'chosen/chosen.jquery.js': [
'coffee/chosen.jquery.coffee'
'coffee/lib/select-parser.coffee' 'coffee/lib/select-parser.coffee'
'coffee/lib/abstract-chosen.coffee'
'coffee/chosen.jquery.coffee'
] ]
'chosen/chosen.proto.js': [ 'chosen/chosen.proto.js': [
'coffee/chosen.proto.coffee'
'coffee/lib/select-parser.coffee' 'coffee/lib/select-parser.coffee'
'coffee/lib/abstract-chosen.coffee'
'coffee/chosen.proto.coffee'
] ]
} }
@ -57,20 +59,28 @@ write_chosen_javascript = (filename, body) ->
// This file is generated by `cake build`, do not edit it by hand. // This file is generated by `cake build`, do not edit it by hand.
#{body} #{body}
""" """
console.log "Wrote #{filename}"
# Build Chosen. # Build Chosen.
# #
task 'build', 'build Chosen from source', build = (cb) -> task 'build', 'build Chosen from source', build = (cb) ->
for javascript, sources of javascripts file_name = null; file_contents = null
code = '' try
for source in sources for javascript, sources of javascripts
code += CoffeeScript.compile "#{fs.readFileSync source}" code = ''
write_chosen_javascript javascript, code for source in sources
unless process.env.MINIFY is 'false' file_name = source
write_chosen_javascript javascript.replace(/\.js$/,'.min.js'), ( file_contents = "#{fs.readFileSync source}"
uglify.gen_code uglify.ast_squeeze uglify.ast_mangle parser.parse code code += CoffeeScript.compile file_contents
) write_chosen_javascript javascript, code
cb() if typeof cb is 'function' unless process.env.MINIFY is 'false'
write_chosen_javascript javascript.replace(/\.js$/,'.min.js'), (
uglify.gen_code uglify.ast_squeeze uglify.ast_mangle parser.parse code
)
package_npm () ->
cb() if typeof cb is 'function'
catch e
print_error e, file_name, file_contents
task 'watch', 'watch coffee/ for changes and build Chosen', -> task 'watch', 'watch coffee/ for changes and build Chosen', ->
console.log "Watching for changes in coffee/" console.log "Watching for changes in coffee/"
@ -85,6 +95,17 @@ task 'watch', 'watch coffee/ for changes and build Chosen', ->
invoke 'build' invoke 'build'
)(file) )(file)
task 'package_npm', 'generate the package.json file for npm', package_npm = (cb) ->
try
package_file = 'package.json'
package = JSON.parse("#{fs.readFileSync package_file}")
package['version'] = version()
fs.writeFileSync package_file, JSON.stringify(package, null, 2)
console.log "Wrote #{package_file}"
cb() if typeof cb is 'function'
catch e
print_error e, package_file
run = (cmd, args, cb, err_cb) -> run = (cmd, args, cb, err_cb) ->
exec "#{cmd} #{args.join(' ')}", (err, stdout, stderr) -> exec "#{cmd} #{args.join(' ')}", (err, stdout, stderr) ->
if err isnt null if err isnt null
@ -118,6 +139,28 @@ untag_release = (e) ->
push_repo = (args=[], cb, cb_err) -> push_repo = (args=[], cb, cb_err) ->
run 'git', ['push'].concat(args), cb, cb_err run 'git', ['push'].concat(args), cb, cb_err
print_error = (error, file_name, file_contents) ->
line = error.message.match /line ([0-9]+):/
if line && line[1] && line = parseInt(line[1])
contents_lines = file_contents.split "\n"
first = if line-4 < 0 then 0 else line-4
last = if line+3 > contents_lines.size then contents_lines.size else line+3
console.log "Error compiling #{file_name}. \"#{error.message}\"\n"
index = 0
for line in contents_lines[first...last]
index++
line_number = first + 1 + index
console.log "#{(' ' for [0..(3-(line_number.toString().length))]).join('')} #{line}"
else
console.log """
Error compiling #{file_name}:
#{error.message}
"""
task 'release', 'build, tag the current release, and push', -> task 'release', 'build, tag the current release, and push', ->
console.log "Trying to tag #{version_tag()}..." console.log "Trying to tag #{version_tag()}..."
with_clean_repo -> with_clean_repo ->

View file

@ -14,17 +14,20 @@ Contributions and pull requests are very welcome. Please follow these guidelines
1. Make all changes in Coffeescript files, **not** JavaScript files. 1. Make all changes in Coffeescript files, **not** JavaScript files.
2. For feature changes, update both jQuery *and* Prototype versions 2. For feature changes, update both jQuery *and* Prototype versions
3. Use 'cake build' to generate Chosen's JavaScript file and minified version. 3. Use `npm install -d` to install the correct development dependencies.
4. Don't touch the VERSION file 4. Use `cake build` or `cake watch` to generate Chosen's JavaScript file and minified version.
5. Submit a Pull Request using GitHub. 5. Don't touch the `VERSION` file
6. Submit a Pull Request using GitHub.
### Using CoffeeScript & Cake ### Using CoffeeScript & Cake
First, make sure you have the proper CoffeeScript / Cake set-up in place. First, make sure you have the proper CoffeeScript / Cake set-up in place. We have added a package.json that makes this easy:
1. Install Coffeescript: the [CoffeeScript documentation](http://jashkenas.github.com/coffee-script/) provides easy-to-follow instructions. ```
2. Install UglifyJS: <code>npm -g install uglify-js</code> npm install -d
3. Verify that your $NODE_PATH is properly configured using <code>echo $NODE_PATH</code> ```
This will install `coffee-script` and `uglifyjs`.
Once you're configured, building the JavasScript from the command line is easy: Once you're configured, building the JavasScript from the command line is easy:
@ -36,11 +39,12 @@ If you're interested, you can find the recipes in Cakefile.
### Chosen Credits ### Chosen Credits
- Built by [Harvest](http://www.getharvest.com/) - Built by [Harvest](http://www.getharvest.com/). Want to work on projects like this? [Were hiring](http://www.getharvest.com/careers)!
- Concept and development by [Patrick Filler](http://www.patrickfiller.com/) - Concept and development by [Patrick Filler](http://www.patrickfiller.com/)
- Design and CSS by [Matthew Lettini](http://matthewlettini.com/) - Design and CSS by [Matthew Lettini](http://matthewlettini.com/)
### Notable Forks ### Notable Forks
- [Chosen for MooTools](https://github.com/julesjanssen/chosen), by Jules Janssen - [Chosen for MooTools](https://github.com/julesjanssen/chosen), by Jules Janssen
- [Chosen Drupal 7 Module](https://github.com/Polzme/chosen), by Pol Dell'Aiera - [Chosen Drupal 7 Module](http://drupal.org/project/chosen), by Pol Dell'Aiera, Arshad Chummun, Bart Feenstra, Kálmán Hosszu, etc.
- [Chosen CakePHP Plugin](https://github.com/paulredmond/chosen-cakephp), by Paul Redmond

View file

@ -1 +1 @@
0.9.1 0.9.7

Binary file not shown.

Before

Width:  |  Height:  |  Size: 742 B

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,9 +1,4 @@
/* @group Base */ /* @group Base */
select.chzn-select {
visibility: hidden;
height: 28px !important;
min-height: 28px !important;
}
.chzn-container { .chzn-container {
font-size: 13px; font-size: 13px;
position: relative; position: relative;
@ -28,29 +23,32 @@ select.chzn-select {
/* @group Single Chosen */ /* @group Single Chosen */
.chzn-container-single .chzn-single { .chzn-container-single .chzn-single {
background-color: #fff; background-color: #ffffff;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white)); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0 );
background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%); background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%); background-image: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background-image: -o-linear-gradient(top, #eeeeee 0%,#ffffff 50%); background-image: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 50%); background-image: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 ); background-image: -ms-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background-image: linear-gradient(top, #eeeeee 0%,#ffffff 50%); background-image: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
-webkit-border-radius: 4px; -webkit-border-radius: 5px;
-moz-border-radius : 4px; -moz-border-radius : 5px;
border-radius : 4px; border-radius : 5px;
-moz-background-clip : padding; -moz-background-clip : padding;
-webkit-background-clip: padding-box; -webkit-background-clip: padding-box;
background-clip : padding-box; background-clip : padding-box;
border: 1px solid #aaa; border: 1px solid #aaaaaa;
-webkit-box-shadow: 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
-moz-box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
display: block; display: block;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
position: relative; position: relative;
height: 26px; height: 23px;
line-height: 26px; line-height: 24px;
padding: 0 0 0 8px; padding: 0 0 0 8px;
color: #444; color: #444444;
text-decoration: none; text-decoration: none;
} }
.chzn-container-single .chzn-single span { .chzn-container-single .chzn-single span {
@ -60,25 +58,22 @@ select.chzn-select {
white-space: nowrap; white-space: nowrap;
-o-text-overflow: ellipsis; -o-text-overflow: ellipsis;
-ms-text-overflow: ellipsis; -ms-text-overflow: ellipsis;
-moz-binding: url('/xml/ellipsis.xml#ellipsis');
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.chzn-container-single .chzn-single abbr {
display: block;
position: absolute;
right: 26px;
top: 6px;
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;
-moz-border-radius : 0 4px 4px 0;
border-radius : 0 4px 4px 0;
-moz-background-clip : padding;
-webkit-background-clip: padding-box;
background-clip : padding-box;
background: #ccc;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%);
background-image: -ms-linear-gradient(top, #cccccc 0%,#eeeeee 60%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cccccc', endColorstr='#eeeeee',GradientType=0 );
background-image: linear-gradient(top, #cccccc 0%,#eeeeee 60%);
border-left: 1px solid #aaa;
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
@ -87,25 +82,26 @@ select.chzn-select {
width: 18px; width: 18px;
} }
.chzn-container-single .chzn-single div b { .chzn-container-single .chzn-single div b {
background: url('chosen-sprite.png') no-repeat 0 1px; background: url('chosen-sprite.png') no-repeat 0 0;
display: block; display: block;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.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;
z-index: 1010;
} }
.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, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
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(top, #eeeeee 1%, #ffffff 15%);
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(top, #eeeeee 1%, #ffffff 15%);
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(top, #eeeeee 1%, #ffffff 15%);
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, #eeeeee 1%, #ffffff 15%);
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, linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background: url('chosen-sprite.png') no-repeat 100% -20px, 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;
@ -123,16 +119,20 @@ select.chzn-select {
} }
/* @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;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background-image: -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: -o-linear-gradient(bottom, white 85%, #eeeeee 99%); background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: linear-gradient(top, #ffffff 85%,#eeeeee 99%);
border: 1px solid #aaa; border: 1px solid #aaa;
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -155,6 +155,9 @@ select.chzn-select {
color: #666; color: #666;
background: transparent !important; background: transparent !important;
border: 0 !important; border: 0 !important;
font-family: sans-serif;
font-size: 100%;
height: 15px;
padding: 5px; padding: 5px;
margin: 1px 0; margin: 1px 0;
outline: 0; outline: 0;
@ -174,21 +177,22 @@ select.chzn-select {
-webkit-background-clip: padding-box; -webkit-background-clip: padding-box;
background-clip : padding-box; background-clip : padding-box;
background-color: #e4e4e4; background-color: #e4e4e4;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e4e4e4), color-stop(0.7, #eeeeee)); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 );
background-image: -webkit-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%); background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -moz-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%); background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(bottom, #e4e4e4 0%, #eeeeee 70%); background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -ms-linear-gradient(top, #e4e4e4 0%,#eeeeee 70%); background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e4e4e4', endColorstr='#eeeeee',GradientType=0 ); background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(top, #e4e4e4 0%,#eeeeee 70%); background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
-moz-box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
color: #333; color: #333;
border: 1px solid #b4b4b4; border: 1px solid #aaaaaa;
line-height: 13px; line-height: 13px;
padding: 3px 19px 3px 6px; padding: 3px 20px 3px 5px;
margin: 3px 0 3px 5px; margin: 3px 0 3px 5px;
position: relative; position: relative;
}
.chzn-container-multi .chzn-choices .search-choice span {
cursor: default; cursor: default;
} }
.chzn-container-multi .chzn-choices .search-choice-focus { .chzn-container-multi .chzn-choices .search-choice-focus {
@ -197,25 +201,25 @@ select.chzn-select {
.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 */
/* @group Results */ /* @group Results */
.chzn-container .chzn-results { .chzn-container .chzn-results {
margin: 0 4px 4px 0; margin: 0 4px 4px 0;
max-height: 190px; max-height: 240px;
padding: 0 0 0 4px; padding: 0 0 0 4px;
position: relative; position: relative;
overflow-x: hidden; overflow-x: hidden;
@ -226,16 +230,25 @@ select.chzn-select {
padding: 0; padding: 0;
} }
.chzn-container .chzn-results li { .chzn-container .chzn-results li {
line-height: 80%; display: none;
padding: 7px 7px 8px; line-height: 15px;
padding: 5px 6px;
margin: 0; margin: 0;
list-style: none; list-style: none;
} }
.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-color: #3875d7;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3875d7', endColorstr='#2a62bc', GradientType=0 );
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
background-image: -webkit-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
background-image: -moz-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
background-image: -o-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
background-image: -ms-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
background-image: linear-gradient(top, #3875d7 20%, #2a62bc 90%);
color: #fff; color: #fff;
} }
.chzn-container .chzn-results li em { .chzn-container .chzn-results li em {
@ -247,6 +260,7 @@ select.chzn-select {
} }
.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;
@ -254,11 +268,34 @@ select.chzn-select {
font-weight: bold; font-weight: bold;
} }
.chzn-container .chzn-results .group-option { .chzn-container .chzn-results .group-option {
padding-left: 20px; padding-left: 15px;
} }
.chzn-container-multi .chzn-drop .result-selected { .chzn-container-multi .chzn-drop .result-selected {
display: none; display: none;
} }
.chzn-container .chzn-results-scroll {
background: white;
margin: 0 4px;
position: absolute;
text-align: center;
width: 321px; /* This should by dynamic with js */
z-index: 1;
}
.chzn-container .chzn-results-scroll span {
display: inline-block;
height: 17px;
text-indent: -5000px;
width: 9px;
}
.chzn-container .chzn-results-scroll-down {
bottom: 0;
}
.chzn-container .chzn-results-scroll-down span {
background: url('chosen-sprite.png') no-repeat -4px -3px;
}
.chzn-container .chzn-results-scroll-up span {
background: url('chosen-sprite.png') no-repeat -22px -3px;
}
/* @end */ /* @end */
/* @group Active */ /* @group Active */
@ -276,13 +313,13 @@ select.chzn-select {
-o-box-shadow : 0 1px 0 #fff inset; -o-box-shadow : 0 1px 0 #fff inset;
box-shadow : 0 1px 0 #fff inset; box-shadow : 0 1px 0 #fff inset;
background-color: #eee; background-color: #eee;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee)); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0 );
background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%); background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%); background-image: -webkit-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%); background-image: -moz-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%); background-image: -o-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); background-image: -ms-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%); background-image: linear-gradient(top, #eeeeee 20%, #ffffff 80%);
-webkit-border-bottom-left-radius : 0; -webkit-border-bottom-left-radius : 0;
-webkit-border-bottom-right-radius: 0; -webkit-border-bottom-right-radius: 0;
-moz-border-radius-bottomleft : 0; -moz-border-radius-bottomleft : 0;
@ -309,32 +346,44 @@ select.chzn-select {
} }
/* @end */ /* @end */
/* @group Right to Left */ /* @group Disabled Support */
.chzn-rtl { direction:rtl;text-align: right; } .chzn-disabled {
.chzn-rtl .chzn-single { padding-left: 0; padding-right: 8px; } cursor: default;
.chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; } opacity:0.5 !important;
.chzn-rtl .chzn-single div {
left: 0; right: auto;
border-left: none; border-right: 1px solid #aaaaaa;
-webkit-border-radius: 4px 0 0 4px;
-moz-border-radius : 4px 0 0 4px;
border-radius : 4px 0 0 4px;
} }
.chzn-disabled .chzn-single {
cursor: default;
}
.chzn-disabled .chzn-choices .search-choice .search-choice-close {
cursor: default;
}
/* @group Right to Left */
.chzn-rtl { text-align: right; }
.chzn-rtl .chzn-single { padding: 0 8px 0 0; overflow: visible; }
.chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; direction: rtl; }
.chzn-rtl .chzn-single div { left: 3px; right: auto; }
.chzn-rtl .chzn-single abbr {
left: 26px;
right: auto;
}
.chzn-rtl .chzn-choices .search-field input { direction: rtl; }
.chzn-rtl .chzn-choices li { float: right; } .chzn-rtl .chzn-choices li { float: right; }
.chzn-rtl .chzn-choices .search-choice { padding: 3px 6px 3px 19px; margin: 3px 5px 3px 0; } .chzn-rtl .chzn-choices .search-choice { padding: 3px 5px 3px 19px; margin: 3px 5px 3px 0; }
.chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 5px; right: auto; background-position: right top;} .chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 4px; right: auto; background-position: right top;}
.chzn-rtl.chzn-container-single .chzn-results { margin-left: 4px; margin-right: 0; padding-left: 0; padding-right: 4px; } .chzn-rtl.chzn-container-single .chzn-results { margin: 0 0 4px 4px; padding: 0 4px 0 0; }
.chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 20px; } .chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 15px; }
.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: #fff url('chosen-sprite.png') no-repeat -38px -22px;
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, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
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(top, #eeeeee 1%, #ffffff 15%);
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(top, #eeeeee 1%, #ffffff 15%);
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(top, #eeeeee 1%, #ffffff 15%);
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, #eeeeee 1%, #ffffff 15%);
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, linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background: url('chosen-sprite.png') no-repeat -38px -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%);
padding: 4px 5px 4px 20px; padding: 4px 5px 4px 20px;
direction: rtl;
} }
/* @end */ /* @end */

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -6,49 +6,34 @@ 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.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"
) )
}) })
class Chosen class Chosen extends AbstractChosen
constructor: (elmn) -> setup: ->
this.set_default_values()
@form_field = elmn
@form_field_jq = $ @form_field @form_field_jq = $ @form_field
@is_multiple = @form_field.multiple
@is_rtl = @form_field_jq.hasClass "chzn-rtl" @is_rtl = @form_field_jq.hasClass "chzn-rtl"
@default_text_default = if @form_field.multiple then "Select Some Options" else "Select an Option" finish_setup: ->
this.set_up_html()
this.register_observers()
@form_field_jq.addClass "chzn-done" @form_field_jq.addClass "chzn-done"
set_default_values: ->
@click_test_action = (evt) => this.test_active_click(evt)
@active_field = false
@mouse_on_container = false
@results_showing = false
@result_highlighted = null
@result_single_selected = null
@choices = 0
set_up_html: -> set_up_html: ->
@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 #{' chzn-rtl' if @is_rtl}" 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
}) })
@ -84,14 +69,15 @@ class Chosen
this.results_build() this.results_build()
this.set_tab_index() this.set_tab_index()
@form_field_jq.trigger("liszt:ready", {chosen: this})
register_observers: -> register_observers: ->
@container.click (evt) => this.container_click(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)
@search_results.click (evt) => this.search_results_click(evt) @search_results.mouseup (evt) => this.search_results_mouseup(evt)
@search_results.mouseover (evt) => this.search_results_mouseover(evt) @search_results.mouseover (evt) => this.search_results_mouseover(evt)
@search_results.mouseout (evt) => this.search_results_mouseout(evt) @search_results.mouseout (evt) => this.search_results_mouseout(evt)
@ -105,34 +91,40 @@ class Chosen
@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)
else else
@selected_item.focus (evt) => this.activate_field(evt) @container.click (evt) => evt.preventDefault() # gobble click of anchor
container_click: (evt) -> search_field_disabled: ->
if evt and evt.type is "click" @is_disabled = @form_field_jq[0].disabled
evt.stopPropagation() if(@is_disabled)
if not @pending_destroy_click @container.addClass 'chzn-disabled'
if not @active_field @search_field[0].disabled = true
@search_field.val "" if @is_multiple @selected_item.unbind "focus", @activate_action if !@is_multiple
$(document).click @click_test_action this.close_field()
this.results_show()
else if not @is_multiple and evt and ($(evt.target) is @selected_item || $(evt.target).parents("a.chzn-single").length)
evt.preventDefault()
this.results_toggle()
this.activate_field()
else else
@pending_destroy_click = false @container.removeClass 'chzn-disabled'
@search_field[0].disabled = false
@selected_item.bind "focus", @activate_action if !@is_multiple
mouse_enter: -> @mouse_on_container = true container_mousedown: (evt) ->
mouse_leave: -> @mouse_on_container = false if !@is_disabled
target_closelink = if evt? then ($ evt.target).hasClass "search-choice-close" else false
if evt and evt.type is "mousedown"
evt.stopPropagation()
if not @pending_destroy_click and not target_closelink
if not @active_field
@search_field.val "" if @is_multiple
$(document).click @click_test_action
this.results_show()
else if not @is_multiple and evt and (($(evt.target)[0] == @selected_item[0]) || $(evt.target).parents("a.chzn-single").length)
evt.preventDefault()
this.results_toggle()
input_focus: (evt) -> this.activate_field()
setTimeout (=> this.container_click()), 50 unless @active_field else
@pending_destroy_click = false
input_blur: (evt) ->
if not @mouse_on_container container_mouseup: (evt) ->
@active_field = false this.results_reset(evt) if evt.target.nodeName is "ABBR"
setTimeout (=> this.blur_test()), 100
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"
@ -173,7 +165,6 @@ class Chosen
this.close_field() this.close_field()
results_build: -> results_build: ->
startTime = new Date()
@parsing = true @parsing = true
@results_data = root.SelectParser.select_to_array @form_field @results_data = root.SelectParser.select_to_array @form_field
@ -182,6 +173,10 @@ class Chosen
@choices = 0 @choices = 0
else if not @is_multiple else if not @is_multiple
@selected_item.find("span").text @default_text @selected_item.find("span").text @default_text
if @form_field.options.length <= @disable_search_threshold
@container.addClass "chzn-container-single-nosearch"
else
@container.removeClass "chzn-container-single-nosearch"
content = '' content = ''
for data in @results_data for data in @results_data
@ -193,7 +188,9 @@ class Chosen
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
this.single_deselect_control_build() 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()
@ -208,23 +205,6 @@ class Chosen
else else
"" ""
result_add_option: (option) ->
if not option.disabled
option.dom_id = @container_id + "_o_" + option.array_index
classes = if option.selected and @is_multiple then [] else ["active-result"]
classes.push "result-selected" if option.selected
classes.push "group-option" if option.group_array_index?
'<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.html + '</li>'
else
""
results_update_field: ->
this.result_clear_highlight()
@result_single_selected = null
this.results_build()
result_do_highlight: (el) -> result_do_highlight: (el) ->
if el.length if el.length
this.result_clear_highlight() this.result_clear_highlight()
@ -248,12 +228,6 @@ class Chosen
@result_highlight.removeClass "highlighted" if @result_highlight @result_highlight.removeClass "highlighted" if @result_highlight
@result_highlight = null @result_highlight = null
results_toggle: ->
if @results_showing
this.results_hide()
else
this.results_show()
results_show: -> results_show: ->
if not @is_multiple if not @is_multiple
@selected_item.addClass "chzn-single-with-drop" @selected_item.addClass "chzn-single-with-drop"
@ -295,11 +269,11 @@ class Chosen
@search_field.val("") @search_field.val("")
@search_field.removeClass "default" @search_field.removeClass "default"
search_results_click: (evt) -> search_results_mouseup: (evt) ->
target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first() target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first()
if target.length if target.length
@result_highlight = target @result_highlight = target
this.result_select() this.result_select(evt)
search_results_mouseover: (evt) -> search_results_mouseover: (evt) ->
target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first() target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first()
@ -323,8 +297,11 @@ class Chosen
choice_destroy_link_click: (evt) -> choice_destroy_link_click: (evt) ->
evt.preventDefault() evt.preventDefault()
@pending_destroy_click = true if not @is_disabled
this.choice_destroy $(evt.target) @pending_destroy_click = true
this.choice_destroy $(evt.target)
else
evt.stopPropagation
choice_destroy: (link) -> choice_destroy: (link) ->
@choices -= 1 @choices -= 1
@ -335,20 +312,29 @@ class Chosen
this.result_deselect (link.attr "rel") this.result_deselect (link.attr "rel")
link.parents('li').first().remove() link.parents('li').first().remove()
result_select: -> 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) ->
if @result_highlight if @result_highlight
high = @result_highlight high = @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 @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
@ -359,18 +345,20 @@ class Chosen
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
this.single_deselect_control_build() if @allow_single_deselect
this.results_hide() unless evt.metaKey and @is_multiple
this.results_hide()
@search_field.val "" @search_field.val ""
@form_field_jq.trigger "change" @form_field_jq.trigger "change"
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]
@ -386,14 +374,10 @@ class Chosen
@form_field_jq.trigger "change" @form_field_jq.trigger "change"
this.search_field_scale() this.search_field_scale()
results_search: (evt) -> single_deselect_control_build: ->
if @results_showing @selected_item.find("span").first().after "<abbr class=\"search-choice-close\"></abbr>" if @allow_single_deselect and @selected_item.find("abbr").length < 1
this.winnow_results()
else
this.results_show()
winnow_results: -> winnow_results: ->
startTime = new Date()
this.no_results_clear() this.no_results_clear()
results = 0 results = 0
@ -405,10 +389,11 @@ class Chosen
for option in @results_data for option in @results_data
if not option.disabled and not option.empty if not option.disabled and not option.empty
if option.group if option.group
$('#' + option.dom_id).hide() $('#' + option.dom_id).css('display', 'none')
else if not (@is_multiple and option.selected) else if not (@is_multiple and option.selected)
found = false found = false
result_id = option.dom_id result_id = option.dom_id
result = $("#" + result_id)
if regex.test option.html if regex.test option.html
found = true found = true
@ -429,16 +414,15 @@ class Chosen
text = text.substr(0, startpos) + '<em>' + text.substr(startpos) text = text.substr(0, startpos) + '<em>' + text.substr(startpos)
else else
text = option.html text = option.html
result.html(text)
this.result_activate result
$("#" + result_id).html text if $("#" + result_id).html != text $("#" + @results_data[option.group_array_index].dom_id).css('display', 'list-item') if option.group_array_index?
this.result_activate $("#" + result_id)
$("#" + @results_data[option.group_array_index].dom_id).show() if option.group_array_index?
else else
this.result_clear_highlight() if @result_highlight and result_id is @result_highlight.attr 'id' this.result_clear_highlight() if @result_highlight and result_id is @result_highlight.attr 'id'
this.result_deactivate $("#" + result_id) this.result_deactivate result
if results < 1 and searchText.length if results < 1 and searchText.length
this.no_results searchText this.no_results searchText
else else
@ -451,18 +435,20 @@ class Chosen
for li in lis for li in lis
li = $(li) li = $(li)
if li.hasClass "group-result" if li.hasClass "group-result"
li.show() li.css('display', 'auto')
else if not @is_multiple or not li.hasClass "result-selected" else if not @is_multiple or not li.hasClass "result-selected"
this.result_activate li this.result_activate li
winnow_results_set_highlight: -> winnow_results_set_highlight: ->
if not @result_highlight if not @result_highlight
do_high = @search_results.find(".active-result").first()
if(do_high) selected_results = if not @is_multiple then @search_results.find(".result-selected.active-result") else []
this.result_do_highlight do_high 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?
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
@ -503,31 +489,10 @@ class Chosen
@pending_backstroke.removeClass "search-choice-focus" if @pending_backstroke @pending_backstroke.removeClass "search-choice-focus" if @pending_backstroke
@pending_backstroke = null @pending_backstroke = null
keyup_checker: (evt) ->
stroke = evt.which ? evt.keyCode
this.search_field_scale()
switch stroke
when 8
if @is_multiple and @backstroke_length < 1 and @choices > 0
this.keydown_backstroke()
else if not @pending_backstroke
this.result_clear_highlight()
this.results_search()
when 13
evt.preventDefault()
this.result_select() if this.results_showing
when 27
this.results_hide() if @results_showing
when 9, 38, 40, 16
# don't do anything on these keys
else this.results_search()
keydown_checker: (evt) -> keydown_checker: (evt) ->
stroke = evt.which ? evt.keyCode stroke = evt.which ? evt.keyCode
this.search_field_scale() this.search_field_scale()
this.clear_backstroke() if stroke != 8 and this.pending_backstroke this.clear_backstroke() if stroke != 8 and this.pending_backstroke
switch stroke switch stroke
@ -535,6 +500,7 @@ class Chosen
@backstroke_length = this.search_field.val().length @backstroke_length = this.search_field.val().length
break break
when 9 when 9
this.result_select(evt) if this.results_showing and not @is_multiple
@mouse_on_container = false @mouse_on_container = false
break break
when 13 when 13
@ -547,8 +513,7 @@ class Chosen
when 40 when 40
this.keydown_arrow() this.keydown_arrow()
break break
search_field_scale: -> search_field_scale: ->
if @is_multiple if @is_multiple
h = 0 h = 0
@ -575,22 +540,12 @@ class Chosen
dd_top = @container.height() dd_top = @container.height()
@dropdown.css({"top": dd_top + "px"}) @dropdown.css({"top": dd_top + "px"})
generate_field_id: ->
new_id = this.generate_random_id()
@form_field.id = new_id
new_id
generate_random_id: -> generate_random_id: ->
string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char() string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char()
while $("#" + string).length > 0 while $("#" + string).length > 0
string += this.generate_random_char() string += this.generate_random_char()
string string
generate_random_char: ->
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ";
rand = Math.floor(Math.random() * chars.length)
newchar = chars.substring rand, rand+1
get_side_border_padding = (elmt) -> get_side_border_padding = (elmt) ->
side_border_padding = elmt.outerWidth() - elmt.width() side_border_padding = elmt.outerWidth() - elmt.width()

View file

@ -4,37 +4,22 @@ Copyright (c) 2011 by Harvest
### ###
root = this root = this
class Chosen class Chosen extends AbstractChosen
constructor: (elmn) -> setup: ->
this.set_default_values()
@form_field = elmn
@is_multiple = @form_field.multiple
@is_rtl = @form_field.hasClassName "chzn-rtl" @is_rtl = @form_field.hasClassName "chzn-rtl"
@default_text_default = if @form_field.multiple then "Select Some Options" else "Select an Option" finish_setup: ->
@form_field.addClassName "chzn-done"
this.set_up_html()
this.register_observers()
set_default_values: -> set_default_values: ->
super()
@click_test_action = (evt) => this.test_active_click(evt)
@active_field = false
@mouse_on_container = false
@results_showing = false
@result_highlighted = null
@result_single_selected = null
@choices = 0
# HTML Templates # HTML Templates
@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"
@ -43,7 +28,7 @@ class Chosen
container_props = container_props =
'id': @container_id 'id': @container_id
'class': "chzn-container #{' chzn-rtl' if @is_rtl}" '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
@ -77,14 +62,15 @@ class Chosen
this.results_build() this.results_build()
this.set_tab_index() this.set_tab_index()
@form_field.fire("liszt:ready", {chosen: this})
register_observers: -> register_observers: ->
@container.observe "click", (evt) => this.container_click(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)
@search_results.observe "click", (evt) => this.search_results_click(evt) @search_results.observe "mouseup", (evt) => this.search_results_mouseup(evt)
@search_results.observe "mouseover", (evt) => this.search_results_mouseover(evt) @search_results.observe "mouseover", (evt) => this.search_results_mouseover(evt)
@search_results.observe "mouseout", (evt) => this.search_results_mouseout(evt) @search_results.observe "mouseout", (evt) => this.search_results_mouseout(evt)
@ -98,34 +84,39 @@ class Chosen
@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)
else else
@selected_item.observe "focus", (evt) => this.activate_field(evt) @container.observe "click", (evt) => evt.preventDefault() # gobble click of anchor
search_field_disabled: ->
container_click: (evt) -> @is_disabled = @form_field.disabled
if evt and evt.type is "click" if(@is_disabled)
evt.stop() @container.addClassName 'chzn-disabled'
if not @pending_destroy_click @search_field.disabled = true
if not @active_field @selected_item.stopObserving "focus", @activate_action if !@is_multiple
@search_field.clear() if @is_multiple this.close_field()
document.observe "click", @click_test_action
this.results_show()
else if not @is_multiple and evt and (evt.target is @selected_item || evt.target.up("a.chzn-single"))
this.results_toggle()
this.activate_field()
else else
@pending_destroy_click = false @container.removeClassName 'chzn-disabled'
@search_field.disabled = false
@selected_item.observe "focus", @activate_action if !@is_multiple
mouse_enter: -> @mouse_on_container = true container_mousedown: (evt) ->
mouse_leave: -> @mouse_on_container = false if !@is_disabled
target_closelink = if evt? then evt.target.hasClassName "search-choice-close" else false
if evt and evt.type is "mousedown"
evt.stop()
if not @pending_destroy_click and not target_closelink
if not @active_field
@search_field.clear() if @is_multiple
document.observe "click", @click_test_action
this.results_show()
else if not @is_multiple and evt and (evt.target is @selected_item || evt.target.up("a.chzn-single"))
this.results_toggle()
input_focus: (evt) -> this.activate_field()
setTimeout this.container_click.bind(this), 50 unless @active_field else
@pending_destroy_click = false
input_blur: (evt) -> container_mouseup: (evt) ->
if not @mouse_on_container this.results_reset(evt) if evt.target.nodeName is "ABBR"
@active_field = false
setTimeout this.blur_test.bind(this), 100
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")
@ -166,7 +157,6 @@ class Chosen
this.close_field() this.close_field()
results_build: -> results_build: ->
startTime = new Date()
@parsing = true @parsing = true
@results_data = root.SelectParser.select_to_array @form_field @results_data = root.SelectParser.select_to_array @form_field
@ -175,6 +165,10 @@ class Chosen
@choices = 0 @choices = 0
else if not @is_multiple else if not @is_multiple
@selected_item.down("span").update(@default_text) @selected_item.down("span").update(@default_text)
if @form_field.options.length <= @disable_search_threshold
@container.addClassName "chzn-container-single-nosearch"
else
@container.removeClassName "chzn-container-single-nosearch"
content = '' content = ''
for data in @results_data for data in @results_data
@ -186,7 +180,9 @@ class Chosen
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 )
this.single_deselect_control_build() 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()
@ -201,23 +197,6 @@ class Chosen
else else
"" ""
result_add_option: (option) ->
if not option.disabled
option.dom_id = @container_id + "_o_" + option.array_index
classes = if option.selected and @is_multiple then [] else ["active-result"]
classes.push "result-selected" if option.selected
classes.push "group-option" if option.group_array_index?
'<li id="' + option.dom_id + '" class="' + classes.join(' ') + '">' + option.html + '</li>'
else
""
results_update_field: ->
this.result_clear_highlight()
@result_single_selected = null
this.results_build()
result_do_highlight: (el) -> result_do_highlight: (el) ->
this.result_clear_highlight() this.result_clear_highlight()
@ -240,12 +219,6 @@ class Chosen
@result_highlight.removeClassName('highlighted') if @result_highlight @result_highlight.removeClassName('highlighted') if @result_highlight
@result_highlight = null @result_highlight = null
results_toggle: ->
if @results_showing
this.results_hide()
else
this.results_show()
results_show: -> results_show: ->
if not @is_multiple if not @is_multiple
@selected_item.addClassName('chzn-single-with-drop') @selected_item.addClassName('chzn-single-with-drop')
@ -287,11 +260,11 @@ class Chosen
@search_field.value = "" @search_field.value = ""
@search_field.removeClassName "default" @search_field.removeClassName "default"
search_results_click: (evt) -> search_results_mouseup: (evt) ->
target = if evt.target.hasClassName("active-result") then evt.target else evt.target.up(".active-result") target = if evt.target.hasClassName("active-result") then evt.target else evt.target.up(".active-result")
if target if target
@result_highlight = target @result_highlight = target
this.result_select() this.result_select(evt)
search_results_mouseover: (evt) -> search_results_mouseover: (evt) ->
target = if evt.target.hasClassName("active-result") then evt.target else evt.target.up(".active-result") target = if evt.target.hasClassName("active-result") then evt.target else evt.target.up(".active-result")
@ -319,8 +292,9 @@ class Chosen
choice_destroy_link_click: (evt) -> choice_destroy_link_click: (evt) ->
evt.preventDefault() evt.preventDefault()
@pending_destroy_click = true if not @is_disabled
this.choice_destroy evt.target @pending_destroy_click = true
this.choice_destroy evt.target
choice_destroy: (link) -> choice_destroy: (link) ->
@choices -= 1 @choices -= 1
@ -331,17 +305,26 @@ class Chosen
this.result_deselect link.readAttribute("rel") this.result_deselect link.readAttribute("rel")
link.up('li').remove() link.up('li').remove()
result_select: -> 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) ->
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]
@ -353,18 +336,20 @@ class Chosen
this.choice_build item this.choice_build item
else else
@selected_item.down("span").update(item.html) @selected_item.down("span").update(item.html)
this.single_deselect_control_build() if @allow_single_deselect
this.results_hide() unless evt.metaKey and @is_multiple
this.results_hide()
@search_field.value = "" @search_field.value = ""
@form_field.simulate("change") if typeof Event.simulate is 'function' @form_field.simulate("change") if typeof Event.simulate is 'function'
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]
@ -379,15 +364,11 @@ class Chosen
@form_field.simulate("change") if typeof Event.simulate is 'function' @form_field.simulate("change") if typeof Event.simulate is 'function'
this.search_field_scale() this.search_field_scale()
results_search: (evt) -> single_deselect_control_build: ->
if @results_showing @selected_item.down("span").insert { after: "<abbr class=\"search-choice-close\"></abbr>" } if @allow_single_deselect and not @selected_item.down("abbr")
this.winnow_results()
else
this.results_show()
winnow_results: -> winnow_results: ->
startTime = new Date()
this.no_results_clear() this.no_results_clear()
results = 0 results = 0
@ -428,7 +409,7 @@ class Chosen
this.result_activate $(result_id) this.result_activate $(result_id)
$(@results_data[option.group_array_index].dom_id).show() if option.group_array_index? $(@results_data[option.group_array_index].dom_id).setStyle({display: 'list-item'}) if option.group_array_index?
else else
this.result_clear_highlight() if $(result_id) is @result_highlight this.result_clear_highlight() if $(result_id) is @result_highlight
this.result_deactivate $(result_id) this.result_deactivate $(result_id)
@ -450,9 +431,14 @@ class Chosen
winnow_results_set_highlight: -> winnow_results_set_highlight: ->
if not @result_highlight if not @result_highlight
do_high = @search_results.down(".active-result")
if(do_high) if not @is_multiple
this.result_do_highlight do_high do_high = @search_results.down(".result-selected.active-result")
if not do_high?
do_high = @search_results.down(".active-result")
this.result_do_highlight do_high if do_high?
no_results: (terms) -> no_results: (terms) ->
@search_results.insert @no_results_temp.evaluate( terms: terms ) @search_results.insert @no_results_temp.evaluate( terms: terms )
@ -499,27 +485,6 @@ class Chosen
@pending_backstroke.removeClassName("search-choice-focus") if @pending_backstroke @pending_backstroke.removeClassName("search-choice-focus") if @pending_backstroke
@pending_backstroke = null @pending_backstroke = null
keyup_checker: (evt) ->
stroke = evt.which ? evt.keyCode
this.search_field_scale()
switch stroke
when 8
if @is_multiple and @backstroke_length < 1 and @choices > 0
this.keydown_backstroke()
else if not @pending_backstroke
this.result_clear_highlight()
this.results_search()
when 13
evt.preventDefault()
this.result_select() if this.results_showing
when 27
this.results_hide() if @results_showing
when 9, 38, 40, 16
# don't do anything on these keys
else this.results_search()
keydown_checker: (evt) -> keydown_checker: (evt) ->
stroke = evt.which ? evt.keyCode stroke = evt.which ? evt.keyCode
this.search_field_scale() this.search_field_scale()
@ -529,16 +494,21 @@ class Chosen
switch stroke switch stroke
when 8 when 8
@backstroke_length = this.search_field.value.length @backstroke_length = this.search_field.value.length
break
when 9 when 9
this.result_select(evt) if this.results_showing and not @is_multiple
@mouse_on_container = false @mouse_on_container = false
break
when 13 when 13
evt.preventDefault() evt.preventDefault()
break
when 38 when 38
evt.preventDefault() evt.preventDefault()
this.keyup_arrow() this.keyup_arrow()
break
when 40 when 40
this.keydown_arrow() this.keydown_arrow()
break
search_field_scale: -> search_field_scale: ->
if @is_multiple if @is_multiple
@ -567,9 +537,11 @@ class Chosen
root.Chosen = Chosen root.Chosen = Chosen
document.observe 'dom:loaded', (evt) -> # Prototype does not support version numbers so we add it ourselves
selects = $$(".chzn-select") if Prototype.Browser.IE
new Chosen select for select in selects if /MSIE (\d+\.\d+);/.test(navigator.userAgent)
Prototype.BrowserFeatures['Version'] = new Number(RegExp.$1);
get_side_border_padding = (elmt) -> get_side_border_padding = (elmt) ->
layout = new Element.Layout(elmt) layout = new Element.Layout(elmt)

View file

@ -0,0 +1,109 @@
###
Chosen source: generate output using 'cake build'
Copyright (c) 2011 by Harvest
###
root = this
class AbstractChosen
constructor: (@form_field, @options={}) ->
this.set_default_values()
@is_multiple = @form_field.multiple
@default_text_default = if @is_multiple then "Select Some Options" else "Select an Option"
this.setup()
this.set_up_html()
this.register_observers()
this.finish_setup()
set_default_values: ->
@click_test_action = (evt) => this.test_active_click(evt)
@activate_action = (evt) => this.activate_field(evt)
@active_field = false
@mouse_on_container = false
@results_showing = false
@result_highlighted = null
@result_single_selected = null
@allow_single_deselect = if @options.allow_single_deselect? and @form_field.options[0]? and @form_field.options[0].text is "" then @options.allow_single_deselect else false
@disable_search_threshold = @options.disable_search_threshold || 0
@choices = 0
@results_none_found = @options.no_results_text or "No results match"
mouse_enter: -> @mouse_on_container = true
mouse_leave: -> @mouse_on_container = false
input_focus: (evt) ->
setTimeout (=> this.container_mousedown()), 50 unless @active_field
input_blur: (evt) ->
if not @mouse_on_container
@active_field = false
setTimeout (=> this.blur_test()), 100
result_add_option: (option) ->
if not option.disabled
option.dom_id = @container_id + "_o_" + option.array_index
classes = if option.selected and @is_multiple then [] else ["active-result"]
classes.push "result-selected" if option.selected
classes.push "group-option" if option.group_array_index?
classes.push option.classes if option.classes != ""
style = if option.style.cssText != "" then " style=\"#{option.style}\"" else ""
'<li id="' + option.dom_id + '" class="' + classes.join(' ') + '"'+style+'>' + option.html + '</li>'
else
""
results_update_field: ->
this.result_clear_highlight()
@result_single_selected = null
this.results_build()
results_toggle: ->
if @results_showing
this.results_hide()
else
this.results_show()
results_search: (evt) ->
if @results_showing
this.winnow_results()
else
this.results_show()
keyup_checker: (evt) ->
stroke = evt.which ? evt.keyCode
this.search_field_scale()
switch stroke
when 8
if @is_multiple and @backstroke_length < 1 and @choices > 0
this.keydown_backstroke()
else if not @pending_backstroke
this.result_clear_highlight()
this.results_search()
when 13
evt.preventDefault()
this.result_select(evt) if this.results_showing
when 27
this.results_hide() if @results_showing
return true
when 9, 38, 40, 16, 91, 17
# don't do anything on these keys
else this.results_search()
generate_field_id: ->
new_id = this.generate_random_id()
@form_field.id = new_id
new_id
generate_random_char: ->
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ"
rand = Math.floor(Math.random() * chars.length)
newchar = chars.substring rand, rand+1
root.AbstractChosen = AbstractChosen

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

@ -50,6 +50,7 @@
<link rel="stylesheet" href="chosen/chosen.css" /> <link rel="stylesheet" href="chosen/chosen.css" />
</head> </head>
<body> <body>
<form>
<div id="container"> <div id="container">
<h1>Chosen</h1> <h1>Chosen</h1>
<p>Chosen is a JavaScript plugin for Prototype and jQuery that makes long, unwieldy select boxes much more user-friendly. For more information (including usage, explanation and faqs), check out the <a href="http://harvesthq.github.com/chosen/">online documentation</a>.</p> <p>Chosen is a JavaScript plugin for Prototype and jQuery that makes long, unwieldy select boxes much more user-friendly. For more information (including usage, explanation and faqs), check out the <a href="http://harvesthq.github.com/chosen/">online documentation</a>.</p>
@ -1063,7 +1064,7 @@
<em>Single Select with Groups</em> <em>Single Select with Groups</em>
<select data-placeholder="Your Favorite Football Team" style="width:350px;" class="chzn-select" tabindex="5"> <select data-placeholder="Your Favorite Football Team" style="width:350px;" class="chzn-select" tabindex="5">
<option value=""></option> <option value=""></option>
<optgroup label="NFC East"> <optgroup label="NFC EAST">
<option>Dallas Cowboys</option> <option>Dallas Cowboys</option>
<option>New York Giants</option> <option>New York Giants</option>
<option>Philadelphia Eagles</option> <option>Philadelphia Eagles</option>
@ -1117,7 +1118,7 @@
<em>Multiple Select with Groups</em> <em>Multiple Select with Groups</em>
<select data-placeholder="Your Favorite Football Team" style="width:350px;" class="chzn-select" multiple tabindex="6"> <select data-placeholder="Your Favorite Football Team" style="width:350px;" class="chzn-select" multiple tabindex="6">
<option value=""></option> <option value=""></option>
<optgroup label="NFC East"> <optgroup label="NFC EAST">
<option>Dallas Cowboys</option> <option>Dallas Cowboys</option>
<option>New York Giants</option> <option>New York Giants</option>
<option>Philadelphia Eagles</option> <option>Philadelphia Eagles</option>
@ -1187,8 +1188,8 @@
</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" 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>
<option>Asiatic Black Bear</option> <option>Asiatic Black Bear</option>
@ -1205,9 +1206,35 @@
<h2>Default Text Support</h2> <h2>Default Text Support</h2>
<div class="side-by-side clearfix"> <div class="side-by-side clearfix">
<p>Chosen automatically sets the default field text ("Choose a country...") by reading the select element's data-placeholder value. If no data-placeholder value is present, it will default to "Select Some Option" or "Select Some Options" depending on whether the select is single or multiple. You can change these elements in the plugin js file as you see fit.</p> <p>Chosen automatically sets the default field text ("Choose a country...") by reading the select element's data-placeholder value. If no data-placeholder value is present, it will default to "Select Some Option" or "Select Some Options" depending on whether the select is single or multiple. You can change these elements in the plugin js file as you see fit.</p>
<code>&lt;select <strong>data-placehoder="Choose a country..."</strong> style="width:350px;" multiple class="chzn-select"&gt;</code> <code>&lt;select <strong>data-placeholder="Choose a country..."</strong> style="width:350px;" multiple class="chzn-select"&gt;</code>
<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">
@ -1268,7 +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>
</body> </body>

View file

@ -1063,7 +1063,7 @@
<em>Single Select with Groups</em> <em>Single Select with Groups</em>
<select data-placeholder="Your Favorite Football Team" style="width:350px;" class="chzn-select" tabindex="5"> <select data-placeholder="Your Favorite Football Team" style="width:350px;" class="chzn-select" tabindex="5">
<option value=""></option> <option value=""></option>
<optgroup label="NFC East"> <optgroup label="NFC EAST">
<option>Dallas Cowboys</option> <option>Dallas Cowboys</option>
<option>New York Giants</option> <option>New York Giants</option>
<option>Philadelphia Eagles</option> <option>Philadelphia Eagles</option>
@ -1117,7 +1117,7 @@
<em>Multiple Select with Groups</em> <em>Multiple Select with Groups</em>
<select data-placeholder="Your Favorite Football Team" style="width:350px;" class="chzn-select" multiple tabindex="6"> <select data-placeholder="Your Favorite Football Team" style="width:350px;" class="chzn-select" multiple tabindex="6">
<option value=""></option> <option value=""></option>
<optgroup label="NFC East"> <optgroup label="NFC EAST">
<option>Dallas Cowboys</option> <option>Dallas Cowboys</option>
<option>New York Giants</option> <option>New York Giants</option>
<option>Philadelphia Eagles</option> <option>Philadelphia Eagles</option>
@ -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>

18
package.json Normal file
View file

@ -0,0 +1,18 @@
{
"author": "harvest",
"name": "chosen",
"version": "0.9.7",
"description": "Chosen is a JavaScript plugin that makes long, unwieldy select boxes much more user-friendly. It is currently available in both jQuery and Prototype flavors.",
"repository": {
"type": "git",
"url": "https://github.com/harvesthq/chosen"
},
"engines": {
"node": ">=0.4.0"
},
"dependencies": {},
"devDependencies": {
"coffee-script": ">= 1.2",
"uglify-js": ">= 1.2.5"
}
}