From 05b69c89b67d49d8a77184ac422ab7030c3b61b8 Mon Sep 17 00:00:00 2001 From: "AppleGrew (applegrew)" Date: Sat, 2 Mar 2013 11:25:00 +0530 Subject: [PATCH] * Multi-process support. * Updated Select2 to 3.3.1. --- README | 10 + README.md | 10 + django_select2/__init__.py | 10 +- django_select2/db_client.py | 26 + django_select2/memcache_client.py | 29 + django_select2/memcache_wrapped_db_client.py | 35 + django_select2/models.py | 9 + django_select2/static/css/all.min.css | 2 +- .../css/{spinner.gif => select2-spinner.gif} | Bin django_select2/static/css/select2.css | 597 +++++---- django_select2/static/js/heavy_data.min.js | 2 +- django_select2/static/js/select2.js | 1134 +++++++++++------ django_select2/static/js/select2.min.js | 2 +- django_select2/util.py | 27 +- docs/get_started.rst | 32 +- testapp/test.db | Bin 2334720 -> 2367488 bytes testapp/testapp/settings.py | 13 + 17 files changed, 1256 insertions(+), 682 deletions(-) create mode 100644 django_select2/db_client.py create mode 100644 django_select2/memcache_client.py create mode 100644 django_select2/memcache_wrapped_db_client.py create mode 100644 django_select2/models.py rename django_select2/static/css/{spinner.gif => select2-spinner.gif} (100%) diff --git a/README b/README index 99adc45..6bb89b3 100644 --- a/README +++ b/README @@ -33,6 +33,7 @@ External Dependencies * Django - This is obvious. * jQuery - This is not included in the package since it is expected that in most scenarios this would already be available. +* Memcached (python-memcached) - If you plan on running multiple python processes, then you need to turn on ``ENABLE_SELECT2_MULTI_PROCESS_SUPPORT``. In that mode it is highly recommended that you use Memcached, to minimize DB hits. Example Application =================== @@ -48,6 +49,15 @@ Special Thanks Changelog Summary ================= +### v3.3.0 + +* Updated Select2 to version 3.3.1. +* Added multi-process support. ([Issue#28](https://github.com/applegrew/django-select2/issues/28)). +* Addressed issue[#26](https://github.com/applegrew/django-select2/issues/26). +* Addressed issue[#24](https://github.com/applegrew/django-select2/issues/24). +* Addressed issue[#23](https://github.com/applegrew/django-select2/issues/23). +* Addressed some typos. + ### v3.2.0 * Fixed issue[#20](https://github.com/applegrew/django-select2/issues/20). Infact while fixing that I realised that heavy components do not need the help of cookies, infact due to a logic error in previous code the cookies were not being used anyway. Now Django Select2 does not use cookies etc. diff --git a/README.md b/README.md index 99adc45..6bb89b3 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ External Dependencies * Django - This is obvious. * jQuery - This is not included in the package since it is expected that in most scenarios this would already be available. +* Memcached (python-memcached) - If you plan on running multiple python processes, then you need to turn on ``ENABLE_SELECT2_MULTI_PROCESS_SUPPORT``. In that mode it is highly recommended that you use Memcached, to minimize DB hits. Example Application =================== @@ -48,6 +49,15 @@ Special Thanks Changelog Summary ================= +### v3.3.0 + +* Updated Select2 to version 3.3.1. +* Added multi-process support. ([Issue#28](https://github.com/applegrew/django-select2/issues/28)). +* Addressed issue[#26](https://github.com/applegrew/django-select2/issues/26). +* Addressed issue[#24](https://github.com/applegrew/django-select2/issues/24). +* Addressed issue[#23](https://github.com/applegrew/django-select2/issues/23). +* Addressed some typos. + ### v3.2.0 * Fixed issue[#20](https://github.com/applegrew/django-select2/issues/20). Infact while fixing that I realised that heavy components do not need the help of cookies, infact due to a logic error in previous code the cookies were not being used anyway. Now Django Select2 does not use cookies etc. diff --git a/django_select2/__init__.py b/django_select2/__init__.py index 75526cb..8c2246b 100644 --- a/django_select2/__init__.py +++ b/django_select2/__init__.py @@ -74,14 +74,22 @@ The view - `Select2View`, exposed here is meant to be used with 'Heavy' fields a """ -__version__ = "3.2.1" +__version__ = "3.3.0" __RENDER_SELECT2_STATICS = False +__ENABLE_MULTI_PROCESS_SUPPORT = False +__MEMCACHE_HOST = None +__MEMCACHE_PORT = None +__MEMCACHE_TTL = 900 try: from django.conf import settings if settings.configured: __RENDER_SELECT2_STATICS = getattr(settings, 'AUTO_RENDER_SELECT2_STATICS', True) + __ENABLE_MULTI_PROCESS_SUPPORT = getattr(settings, 'ENABLE_SELECT2_MULTI_PROCESS_SUPPORT', False) + __MEMCACHE_HOST = getattr(settings, 'SELECT2_MEMCACHE_HOST', None) + __MEMCACHE_PORT = getattr(settings, 'SELECT2_MEMCACHE_PORT', None) + __MEMCACHE_TTL = getattr(settings, 'SELECT2_MEMCACHE_TTL', 900) from .widgets import Select2Widget, Select2MultipleWidget, HeavySelect2Widget, HeavySelect2MultipleWidget, \ AutoHeavySelect2Widget, AutoHeavySelect2MultipleWidget diff --git a/django_select2/db_client.py b/django_select2/db_client.py new file mode 100644 index 0000000..bcb5336 --- /dev/null +++ b/django_select2/db_client.py @@ -0,0 +1,26 @@ +from models import KeyMap + +class Client(object): + + def set(self, key, value): + """ + This method is used to set a new value + in the db. + """ + o = self.get(key) + if o is None: + o = KeyMap() + o.key = key + + o.value = value + o.save() + + def get(self, key): + """ + This method is used to retrieve a value + from the db. + """ + try: + return KeyMap.objects.get(key=key).value + except KeyMap.DoesNotExist: + return None diff --git a/django_select2/memcache_client.py b/django_select2/memcache_client.py new file mode 100644 index 0000000..7a34a32 --- /dev/null +++ b/django_select2/memcache_client.py @@ -0,0 +1,29 @@ +import memcache + +class Client(object): + host = "" + server = "" + expiry = 900 + def __init__(self, hostname="127.0.0.1", port="11211", expiry=900): + self.host = "%s:%s" % (hostname, port) + self.server = memcache.Client([self.host]) + self.expiry = expiry + + def set(self, key, value): + """ + This method is used to set a new value + in the memcache server. + """ + self.server.set(self.normalize_key(key), value, self.expiry) + + def get(self, key): + """ + This method is used to retrieve a value + from the memcache server. + """ + return self.server.get(self.normalize_key(key)) + + def normalize_key(self, key): + key = str(key) + key = key.replace(' ', '-') + return key diff --git a/django_select2/memcache_wrapped_db_client.py b/django_select2/memcache_wrapped_db_client.py new file mode 100644 index 0000000..eb129eb --- /dev/null +++ b/django_select2/memcache_wrapped_db_client.py @@ -0,0 +1,35 @@ +class Client(object): + cache = None + db = None + def __init__(self, hostname="127.0.0.1", port="11211", expiry=900): + if hostname and port: + import memcache_client + self.cache = memcache_client.Client(hostname, port, expiry) + + import db_client + self.db = db_client.Client() + + def set(self, key, value): + """ + This method is used to set a new value + in the memcache server and the db. + """ + self.db.set(key, value) + if self.cache: + self.cache.set(key, value) + + def get(self, key): + """ + This method is used to retrieve a value + from the memcache server, if found, else it + is fetched from db. + """ + if self.cache: + v = self.cache.get(key) + if v is None: + v = self.db.get(key) + if v is not None: + self.cache.set(key, v) + else: + v = self.db.get(key) + return v diff --git a/django_select2/models.py b/django_select2/models.py new file mode 100644 index 0000000..4bc2f74 --- /dev/null +++ b/django_select2/models.py @@ -0,0 +1,9 @@ +from django.db import models + +class KeyMap(models.Model): + key = models.CharField(max_length=40, unique=True) + value = models.CharField(max_length=100) + accessed_on = models.DateTimeField(auto_now_add=True, auto_now=True) + + def __unicode__(self): + return unicode("%s => %s" % (self.key, self.value)) diff --git a/django_select2/static/css/all.min.css b/django_select2/static/css/all.min.css index 14dc0ce..df02542 100644 --- a/django_select2/static/css/all.min.css +++ b/django_select2/static/css/all.min.css @@ -1 +1 @@ -.select2-container{position:relative;display:inline-block;zoom:1;*display:inline;vertical-align:top}.select2-container,.select2-drop,.select2-search,.select2-search input{-moz-box-sizing:border-box;-ms-box-sizing:border-box;-webkit-box-sizing:border-box;-khtml-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{background-color:#fff;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#eee),color-stop(0.5,white));background-image:-webkit-linear-gradient(center bottom,#eee 0,white 50%);background-image:-moz-linear-gradient(center bottom,#eee 0,white 50%);background-image:-o-linear-gradient(bottom,#eee 0,#fff 50%);background-image:-ms-linear-gradient(top,#eee 0,#fff 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee',endColorstr = '#ffffff',GradientType = 0);background-image:linear-gradient(top,#eee 0,#fff 50%);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #aaa;display:block;overflow:hidden;white-space:nowrap;position:relative;height:26px;line-height:26px;padding:0 0 0 8px;color:#444;text-decoration:none}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#aaa;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#eee),color-stop(0.9,white));background-image:-webkit-linear-gradient(center bottom,#eee 0,white 90%);background-image:-moz-linear-gradient(center bottom,#eee 0,white 90%);background-image:-o-linear-gradient(bottom,#eee 0,white 90%);background-image:-ms-linear-gradient(top,#eee 0,#fff 90%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee',endColorstr='#ffffff',GradientType=0);background-image:linear-gradient(top,#eee 0,#fff 90%)}.select2-container .select2-choice span{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis;text-overflow:ellipsis}.select2-container .select2-choice abbr{display:block;position:absolute;right:26px;top:8px;width:12px;height:12px;font-size:1px;background:url('select2.png') right top no-repeat;cursor:pointer;text-decoration:none;border:0;outline:0}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop{background:#fff;color:#000;border:1px solid #aaa;border-top:0;position:absolute;top:100%;-webkit-box-shadow:0 4px 5px rgba(0,0,0,.15);-moz-box-shadow:0 4px 5px rgba(0,0,0,.15);-o-box-shadow:0 4px 5px rgba(0,0,0,.15);box-shadow:0 4px 5px rgba(0,0,0,.15);z-index:9999;width:100%;margin-top:-1px;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.select2-drop.select2-drop-above{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;margin-top:1px;border-top:1px solid #aaa;border-bottom:0;-webkit-box-shadow:0 -4px 5px rgba(0,0,0,.15);-moz-box-shadow:0 -4px 5px rgba(0,0,0,.15);-o-box-shadow:0 -4px 5px rgba(0,0,0,.15);box-shadow:0 -4px 5px rgba(0,0,0,.15)}.select2-container .select2-choice 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,#ccc 0,#eee 60%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr = '#cccccc',endColorstr = '#eeeeee',GradientType = 0);background-image:linear-gradient(top,#ccc 0,#eee 60%);border-left:1px solid #aaa;position:absolute;right:0;top:0;display:block;height:100%;width:18px}.select2-container .select2-choice div b{background:url('select2.png') no-repeat 0 1px;display:block;width:100%;height:100%}.select2-search{display:inline-block;white-space:nowrap;z-index:10000;min-height:26px;width:100%;margin:0;padding-left:4px;padding-right:4px}.select2-search-hidden{display:block;position:absolute;left:-10000px}.select2-search input{background:#fff url('select2.png') no-repeat 100% -22px;background:url('select2.png') no-repeat 100% -22px,-webkit-gradient(linear,left bottom,left top,color-stop(0.85,white),color-stop(0.99,#eee));background:url('select2.png') no-repeat 100% -22px,-webkit-linear-gradient(center bottom,white 85%,#eee 99%);background:url('select2.png') no-repeat 100% -22px,-moz-linear-gradient(center bottom,white 85%,#eee 99%);background:url('select2.png') no-repeat 100% -22px,-o-linear-gradient(bottom,white 85%,#eee 99%);background:url('select2.png') no-repeat 100% -22px,-ms-linear-gradient(top,#fff 85%,#eee 99%);background:url('select2.png') no-repeat 100% -22px,linear-gradient(top,#fff 85%,#eee 99%);padding:4px 20px 4px 5px;outline:0;border:1px solid #aaa;font-family:sans-serif;font-size:1em;width:100%;margin:0;height:auto!important;min-height:26px;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border-radius:0;-moz-border-radius:0;-webkit-border-radius:0}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:#fff url('spinner.gif') no-repeat 100%;background:url('spinner.gif') no-repeat 100%,-webkit-gradient(linear,left bottom,left top,color-stop(0.85,white),color-stop(0.99,#eee));background:url('spinner.gif') no-repeat 100%,-webkit-linear-gradient(center bottom,white 85%,#eee 99%);background:url('spinner.gif') no-repeat 100%,-moz-linear-gradient(center bottom,white 85%,#eee 99%);background:url('spinner.gif') no-repeat 100%,-o-linear-gradient(bottom,white 85%,#eee 99%);background:url('spinner.gif') no-repeat 100%,-ms-linear-gradient(top,#fff 85%,#eee 99%);background:url('spinner.gif') no-repeat 100%,linear-gradient(top,#fff 85%,#eee 99%)}.select2-container-active .select2-choice,.select2-container-active .select2-choices{-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);-moz-box-shadow:0 0 5px rgba(0,0,0,.3);-o-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3);border:1px solid #5897fb;outline:0}.select2-dropdown-open .select2-choice{border:1px solid #aaa;border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;-moz-box-shadow:0 1px 0 #fff inset;-o-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background-color:#eee;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,white),color-stop(0.5,#eee));background-image:-webkit-linear-gradient(center bottom,white 0,#eee 50%);background-image:-moz-linear-gradient(center bottom,white 0,#eee 50%);background-image:-o-linear-gradient(bottom,white 0,#eee 50%);background-image:-ms-linear-gradient(top,#fff 0,#eee 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#eeeeee',GradientType=0);background-image:linear-gradient(top,#fff 0,#eee 50%);-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;-moz-border-radius-bottomright:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice div{background:transparent;border-left:none}.select2-dropdown-open .select2-choice div b{background-position:-18px 1px}.select2-results{margin:4px 4px 4px 0;padding:0 0 0 4px;position:relative;overflow-x:hidden;overflow-y:auto;max-height:200px}.select2-results ul.select2-result-sub{margin:0}.select2-results ul.select2-result-sub>li .select2-result-label{padding-left:20px}.select2-results ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:40px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:60px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:80px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:100px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:110px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:120px}.select2-results li{list-style:none;display:list-item}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:bold}.select2-results .select2-result-label{padding:3px 7px 4px;margin:0;cursor:pointer}.select2-results .select2-highlighted{background:#3875d7;color:#fff}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:transparent}.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item}.select2-results .select2-disabled{display:none}.select2-more-results.select2-active{background:#f4f4f4 url('spinner.gif') no-repeat 100%}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice div{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container-multi .select2-choices{background-color:#fff;background-image:-webkit-gradient(linear,0% 0,0% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(top,#eee 1%,#fff 15%);background-image:-moz-linear-gradient(top,#eee 1%,#fff 15%);background-image:-o-linear-gradient(top,#eee 1%,#fff 15%);background-image:-ms-linear-gradient(top,#eee 1%,#fff 15%);background-image:linear-gradient(top,#eee 1%,#fff 15%);border:1px solid #aaa;margin:0;padding:0;cursor:text;overflow:hidden;height:auto!important;height:1%;position:relative}.select2-container-multi .select2-choices{min-height:26px}.select2-container-multi.select2-container-active .select2-choices{-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);-moz-box-shadow:0 0 5px rgba(0,0,0,.3);-o-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3);border:1px solid #5897fb;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}.select2-container-multi .select2-choices .select2-search-field{white-space:nowrap;margin:0;padding:0}.select2-container-multi .select2-choices .select2-search-field input{color:#666;background:transparent!important;font-family:sans-serif;font-size:100%;height:15px;padding:5px;margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;-moz-box-shadow:none;-o-box-shadow:none;box-shadow:none}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:#fff url('spinner.gif') no-repeat 100%!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#e4e4e4;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4f4f4',endColorstr='#eeeeee',GradientType=0);background-image:-webkit-gradient(linear,0% 0,0% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-ms-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);-webkit-box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,0.05);-moz-box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,0.05);box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,0.05);color:#333;border:1px solid #aaa;line-height:13px;padding:3px 5px 3px 18px;margin:3px 0 3px 5px;position:relative;cursor:default}.select2-container-multi .select2-choices .select2-search-choice span{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;position:absolute;right:3px;top:4px;width:12px;height:13px;font-size:1px;background:url('select2.png') right top no-repeat;outline:0}.select2-container-multi .select2-search-choice-close{left:3px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover{background-position:right -11px}.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{background-image:none;background-color:#f4f4f4;border:1px solid #ddd;padding:3px 5px 3px 5px}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-result-selectable .select2-match{text-decoration:underline}.select2-result-unselectable .select2-match{text-decoration:none}.select2-offscreen{position:absolute;left:-10000px}@media only screen and (-webkit-min-device-pixel-ratio:1.5){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice div b{background-image:url(select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important}.select2-search input{background-position:100% -21px!important}}.error a.select2-choice{border:1px solid #b94a48}.select2-container{min-width:150px}.select2-container.select2-container-multi{width:300px} \ No newline at end of file +.select2-container{position:relative;display:inline-block;zoom:1;*display:inline;vertical-align:top}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-khtml-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;height:26px;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #aaa;white-space:nowrap;line-height:26px;color:#444;text-decoration:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#eee),color-stop(0.5,white));background-image:-webkit-linear-gradient(center bottom,#eee 0,white 50%);background-image:-moz-linear-gradient(center bottom,#eee 0,white 50%);background-image:-o-linear-gradient(bottom,#eee 0,#fff 50%);background-image:-ms-linear-gradient(top,#fff 0,#eee 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff',endColorstr = '#eeeeee',GradientType = 0);background-image:linear-gradient(top,#fff 0,#eee 50%)}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#aaa;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#eee),color-stop(0.9,white));background-image:-webkit-linear-gradient(center bottom,#eee 0,white 90%);background-image:-moz-linear-gradient(center bottom,#eee 0,white 90%);background-image:-o-linear-gradient(bottom,#eee 0,white 90%);background-image:-ms-linear-gradient(top,#eee 0,#fff 90%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#eeeeee',GradientType=0);background-image:linear-gradient(top,#eee 0,#fff 90%)}.select2-container .select2-choice span{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis}.select2-container .select2-choice abbr{display:block;width:12px;height:12px;position:absolute;right:26px;top:8px;font-size:1px;text-decoration:none;border:0;background:url('select2.png') right top no-repeat;cursor:pointer;outline:0}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{position:absolute;left:0;top:0;z-index:9998;opacity:0}.select2-drop{width:100%;margin-top:-1px;position:absolute;z-index:9999;top:100%;background:#fff;color:#000;border:1px solid #aaa;border-top:0;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-webkit-box-shadow:0 4px 5px rgba(0,0,0,.15);-moz-box-shadow:0 4px 5px rgba(0,0,0,.15);box-shadow:0 4px 5px rgba(0,0,0,.15)}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #aaa;border-bottom:0;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;-webkit-box-shadow:0 -4px 5px rgba(0,0,0,.15);-moz-box-shadow:0 -4px 5px rgba(0,0,0,.15);box-shadow:0 -4px 5px rgba(0,0,0,.15)}.select2-container .select2-choice div{display:block;width:18px;height:100%;position:absolute;right:0;top:0;border-left:1px solid #aaa;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;-webkit-background-clip:padding-box;-moz-background-clip:padding;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,#ccc 0,#eee 60%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee',endColorstr = '#cccccc',GradientType = 0);background-image:linear-gradient(top,#ccc 0,#eee 60%)}.select2-container .select2-choice div b{display:block;width:100%;height:100%;background:url('select2.png') no-repeat 0 1px}.select2-search{display:inline-block;width:100%;min-height:26px;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap}.select2-search-hidden{display:block;position:absolute;left:-10000px}.select2-search input{width:100%;height:auto!important;min-height:26px;padding:4px 20px 4px 5px;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #aaa;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:#fff url('select2.png') no-repeat 100% -22px;background:url('select2.png') no-repeat 100% -22px,-webkit-gradient(linear,left bottom,left top,color-stop(0.85,white),color-stop(0.99,#eee));background:url('select2.png') no-repeat 100% -22px,-webkit-linear-gradient(center bottom,white 85%,#eee 99%);background:url('select2.png') no-repeat 100% -22px,-moz-linear-gradient(center bottom,white 85%,#eee 99%);background:url('select2.png') no-repeat 100% -22px,-o-linear-gradient(bottom,white 85%,#eee 99%);background:url('select2.png') no-repeat 100% -22px,-ms-linear-gradient(top,#fff 85%,#eee 99%);background:url('select2.png') no-repeat 100% -22px,linear-gradient(top,#fff 85%,#eee 99%)}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:#fff url('select2-spinner.gif') no-repeat 100%;background:url('select2-spinner.gif') no-repeat 100%,-webkit-gradient(linear,left bottom,left top,color-stop(0.85,white),color-stop(0.99,#eee));background:url('select2-spinner.gif') no-repeat 100%,-webkit-linear-gradient(center bottom,white 85%,#eee 99%);background:url('select2-spinner.gif') no-repeat 100%,-moz-linear-gradient(center bottom,white 85%,#eee 99%);background:url('select2-spinner.gif') no-repeat 100%,-o-linear-gradient(bottom,white 85%,#eee 99%);background:url('select2-spinner.gif') no-repeat 100%,-ms-linear-gradient(top,#fff 85%,#eee 99%);background:url('select2-spinner.gif') no-repeat 100%,linear-gradient(top,#fff 85%,#eee 99%)}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #5897fb;outline:0;-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);-moz-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3)}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;-moz-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;background-color:#eee;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,white),color-stop(0.5,#eee));background-image:-webkit-linear-gradient(center bottom,white 0,#eee 50%);background-image:-moz-linear-gradient(center bottom,white 0,#eee 50%);background-image:-o-linear-gradient(bottom,white 0,#eee 50%);background-image:-ms-linear-gradient(top,#fff 0,#eee 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee',endColorstr='#ffffff',GradientType=0);background-image:linear-gradient(top,#fff 0,#eee 50%)}.select2-dropdown-open .select2-choice div{background:transparent;border-left:none;filter:none}.select2-dropdown-open .select2-choice div b{background-position:-18px 1px}.select2-results{max-height:200px;padding:0 0 0 4px;margin:4px 4px 4px 0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:rgba(0,0,0,0)}.select2-results ul.select2-result-sub{margin:0}.select2-results ul.select2-result-sub>li .select2-result-label{padding-left:20px}.select2-results ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:40px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:60px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:80px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:100px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:110px}.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub>li .select2-result-label{padding-left:120px}.select2-results li{list-style:none;display:list-item;background-image:none}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:bold}.select2-results .select2-result-label{padding:3px 7px 4px;margin:0;cursor:pointer;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results .select2-highlighted{background:#3875d7;color:#fff}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:transparent}.select2-results .select2-highlighted ul{background:white;color:#000}.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:#f4f4f4 url('select2-spinner.gif') no-repeat 100%}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice div{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0;position:relative;border:1px solid #aaa;cursor:text;overflow:hidden;background-color:#fff;background-image:-webkit-gradient(linear,0% 0,0% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(top,#eee 1%,#fff 15%);background-image:-moz-linear-gradient(top,#eee 1%,#fff 15%);background-image:-o-linear-gradient(top,#eee 1%,#fff 15%);background-image:-ms-linear-gradient(top,#eee 1%,#fff 15%);background-image:linear-gradient(top,#eee 1%,#fff 15%)}.select2-locked{padding:3px 5px 3px 5px!important}.select2-container-multi .select2-choices{min-height:26px}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #5897fb;outline:0;-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);-moz-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3)}.select2-container-multi .select2-choices li{float:left;list-style:none}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field input{padding:5px;margin:1px 0;font-family:sans-serif;font-size:100%;color:#666;outline:0;border:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:transparent!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:#fff url('select2-spinner.gif') no-repeat 100%!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:3px 5px 3px 18px;margin:3px 0 3px 5px;position:relative;line-height:13px;color:#333;cursor:default;border:1px solid #aaa;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,0.05);-moz-box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,0.05);box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,0.05);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee',endColorstr='#f4f4f4',GradientType=0);background-image:-webkit-gradient(linear,0% 0,0% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-ms-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%)}.select2-container-multi .select2-choices .select2-search-choice span{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:3px;top:4px;font-size:1px;outline:0;background:url('select2.png') right top no-repeat}.select2-container-multi .select2-search-choice-close{left:3px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover{background-position:right -11px}.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px 3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen{position:absolute;left:-10000px}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:144dpi){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice div b{background-image:url('select2x2.png')!important;background-repeat:no-repeat!important;background-size:60px 40px!important}.select2-search input{background-position:100% -21px!important}}.error a.select2-choice{border:1px solid #b94a48}.select2-container{min-width:150px}.select2-container.select2-container-multi{width:300px} \ No newline at end of file diff --git a/django_select2/static/css/spinner.gif b/django_select2/static/css/select2-spinner.gif similarity index 100% rename from django_select2/static/css/spinner.gif rename to django_select2/static/css/select2-spinner.gif diff --git a/django_select2/static/css/select2.css b/django_select2/static/css/select2.css index d5aa280..1ff2abb 100755 --- a/django_select2/static/css/select2.css +++ b/django_select2/static/css/select2.css @@ -1,5 +1,5 @@ /* -Version: 3.2 Timestamp: Mon Sep 10 10:38:04 PDT 2012 +Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013 */ .select2-container { position: relative; @@ -20,52 +20,64 @@ Version: 3.2 Timestamp: Mon Sep 10 10:38:04 PDT 2012 More Info : http://www.quirksmode.org/css/box.html */ - -moz-box-sizing: border-box; /* firefox */ - -ms-box-sizing: border-box; /* ie */ -webkit-box-sizing: border-box; /* webkit */ - -khtml-box-sizing: border-box; /* konqueror */ - box-sizing: border-box; /* css3 */ + -khtml-box-sizing: border-box; /* konqueror */ + -moz-box-sizing: border-box; /* firefox */ + -ms-box-sizing: border-box; /* ie */ + box-sizing: border-box; /* css3 */ } .select2-container .select2-choice { + display: block; + height: 26px; + padding: 0 0 0 8px; + overflow: hidden; + position: relative; + + border: 1px solid #aaa; + white-space: nowrap; + line-height: 26px; + color: #444; + text-decoration: none; + + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: #fff; background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white)); background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%); background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%); background-image: -o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%); - background-image: -ms-linear-gradient(top, #eeeeee 0%, #ffffff 50%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#ffffff', GradientType = 0); - background-image: linear-gradient(top, #eeeeee 0%, #ffffff 50%); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -moz-background-clip: padding; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid #aaa; - display: block; - overflow: hidden; - white-space: nowrap; - position: relative; - height: 26px; - line-height: 26px; - padding: 0 0 0 8px; - color: #444; - text-decoration: none; + background-image: -ms-linear-gradient(top, #ffffff 0%, #eeeeee 50%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0); + background-image: linear-gradient(top, #ffffff 0%, #eeeeee 50%); } -.select2-container.select2-drop-above .select2-choice -{ +.select2-container.select2-drop-above .select2-choice { border-bottom-color: #aaa; - -webkit-border-radius:0px 0px 4px 4px; - -moz-border-radius:0px 0px 4px 4px; - border-radius:0px 0px 4px 4px; + + -webkit-border-radius:0 0 4px 4px; + -moz-border-radius:0 0 4px 4px; + border-radius:0 0 4px 4px; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.9, white)); background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 90%); background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 90%); background-image: -o-linear-gradient(bottom, #eeeeee 0%, white 90%); background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 90%); - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 ); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); background-image: linear-gradient(top, #eeeeee 0%,#ffffff 90%); } @@ -73,114 +85,152 @@ Version: 3.2 Timestamp: Mon Sep 10 10:38:04 PDT 2012 margin-right: 26px; display: block; overflow: hidden; + white-space: nowrap; - -o-text-overflow: ellipsis; + -ms-text-overflow: ellipsis; - text-overflow: ellipsis; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; } .select2-container .select2-choice abbr { - display: block; - position: absolute; - right: 26px; - top: 8px; - width: 12px; - height: 12px; - font-size: 1px; - background: url('select2.png') right top no-repeat; - cursor: pointer; - text-decoration: none; - border:0; - outline: 0; + display: block; + width: 12px; + height: 12px; + position: absolute; + right: 26px; + top: 8px; + + font-size: 1px; + text-decoration: none; + + border: 0; + background: url('select2.png') right top no-repeat; + cursor: pointer; + outline: 0; } .select2-container .select2-choice abbr:hover { - background-position: right -11px; - cursor: pointer; + background-position: right -11px; + cursor: pointer; +} + +.select2-drop-mask { + position: absolute; + left: 0; + top: 0; + z-index: 9998; + opacity: 0; } .select2-drop { + width: 100%; + margin-top:-1px; + position: absolute; + z-index: 9999; + top: 100%; + background: #fff; color: #000; border: 1px solid #aaa; border-top: 0; - position: absolute; - top: 100%; - -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); - -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); - -o-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); - box-shadow: 0 4px 5px rgba(0, 0, 0, .15); - z-index: 9999; - width:100%; - margin-top:-1px; - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; + + -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); + -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15); + box-shadow: 0 4px 5px rgba(0, 0, 0, .15); } .select2-drop.select2-drop-above { - -webkit-border-radius: 4px 4px 0px 0px; - -moz-border-radius: 4px 4px 0px 0px; - border-radius: 4px 4px 0px 0px; - margin-top:1px; + margin-top: 1px; border-top: 1px solid #aaa; border-bottom: 0; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; + -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); - -moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); - -o-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); - box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); + -moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); + box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); } .select2-container .select2-choice div { + display: block; + width: 18px; + height: 100%; + position: absolute; + right: 0; + top: 0; + + border-left: 1px solid #aaa; -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; - -moz-background-clip: padding; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; + -webkit-background-clip: padding-box; - background-clip: padding-box; + -moz-background-clip: padding; + 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); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0); background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%); - border-left: 1px solid #aaa; - position: absolute; - right: 0; - top: 0; - display: block; - height: 100%; - width: 18px; } .select2-container .select2-choice div b { - background: url('select2.png') no-repeat 0 1px; display: block; width: 100%; height: 100%; + background: url('select2.png') no-repeat 0 1px; } .select2-search { - display: inline-block; - white-space: nowrap; + display: inline-block; + width: 100%; + min-height: 26px; + margin: 0; + padding-left: 4px; + padding-right: 4px; + + position: relative; z-index: 10000; - min-height: 26px; - width: 100%; - margin: 0; - padding-left: 4px; - padding-right: 4px; + + white-space: nowrap; } .select2-search-hidden { - display: block; - position: absolute; - left: -10000px; + display: block; + position: absolute; + left: -10000px; } .select2-search input { + width: 100%; + height: auto !important; + min-height: 26px; + padding: 4px 20px 4px 5px; + margin: 0; + + outline: 0; + font-family: sans-serif; + font-size: 1em; + + border: 1px solid #aaa; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: #fff url('select2.png') no-repeat 100% -22px; background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); @@ -188,92 +238,78 @@ Version: 3.2 Timestamp: Mon Sep 10 10:38:04 PDT 2012 background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); background: url('select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%); background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%); - padding: 4px 20px 4px 5px; - outline: 0; - border: 1px solid #aaa; - font-family: sans-serif; - font-size: 1em; - width:100%; - margin:0; - height:auto !important; - min-height: 26px; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - border-radius: 0; - -moz-border-radius: 0; - -webkit-border-radius: 0; } -.select2-drop.select2-drop-above .select2-search input -{ - margin-top:4px; +.select2-drop.select2-drop-above .select2-search input { + margin-top: 4px; } .select2-search input.select2-active { - background: #fff url('spinner.gif') no-repeat 100%; - background: url('spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); - background: url('spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); - background: url('spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); - background: url('spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); - background: url('spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%); - background: url('spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%); + background: #fff url('select2-spinner.gif') no-repeat 100%; + background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); + background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('select2-spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); + background: url('select2-spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%); + background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%); } - .select2-container-active .select2-choice, .select2-container-active .select2-choices { - -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); - -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); - -o-box-shadow : 0 0 5px rgba(0,0,0,.3); - box-shadow : 0 0 5px rgba(0,0,0,.3); border: 1px solid #5897fb; outline: none; + + -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); + -moz-box-shadow: 0 0 5px rgba(0,0,0,.3); + box-shadow: 0 0 5px rgba(0,0,0,.3); } .select2-dropdown-open .select2-choice { - border: 1px solid #aaa; - border-bottom-color: transparent; - -webkit-box-shadow: 0 1px 0 #fff inset; - -moz-box-shadow : 0 1px 0 #fff inset; - -o-box-shadow : 0 1px 0 #fff inset; - box-shadow : 0 1px 0 #fff inset; - background-color: #eee; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee)); - background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%); - background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%); - background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%); - background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%); - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); - background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%); - -webkit-border-bottom-left-radius : 0; - -webkit-border-bottom-right-radius: 0; - -moz-border-radius-bottomleft : 0; - -moz-border-radius-bottomright: 0; - border-bottom-left-radius : 0; - border-bottom-right-radius: 0; + border-bottom-color: transparent; + -webkit-box-shadow: 0 1px 0 #fff inset; + -moz-box-shadow: 0 1px 0 #fff inset; + box-shadow: 0 1px 0 #fff inset; + + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; + border-bottom-left-radius: 0; + + -webkit-border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; + border-bottom-right-radius: 0; + + background-color: #eee; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee)); + background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%); + background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%); + background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%); + background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 ); + background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%); } .select2-dropdown-open .select2-choice div { - background: transparent; - border-left: none; + background: transparent; + border-left: none; + filter: none; } .select2-dropdown-open .select2-choice div b { - background-position: -18px 1px; + background-position: -18px 1px; } /* results */ .select2-results { - margin: 4px 4px 4px 0; - padding: 0 0 0 4px; - position: relative; - overflow-x: hidden; - overflow-y: auto; - max-height: 200px; + max-height: 200px; + padding: 0 0 0 4px; + margin: 4px 4px 4px 0; + position: relative; + overflow-x: hidden; + overflow-y: auto; + -webkit-tap-highlight-color: rgba(0,0,0,0); } .select2-results ul.select2-result-sub { - margin: 0 0 0 0; + margin: 0; } .select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px } @@ -285,40 +321,58 @@ Version: 3.2 Timestamp: Mon Sep 10 10:38:04 PDT 2012 .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px } .select2-results li { - list-style: none; - display: list-item; + list-style: none; + display: list-item; + background-image: none; } .select2-results li.select2-result-with-children > .select2-result-label { - font-weight: bold; + font-weight: bold; } .select2-results .select2-result-label { - padding: 3px 7px 4px; - margin: 0; - cursor: pointer; + padding: 3px 7px 4px; + margin: 0; + cursor: pointer; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } .select2-results .select2-highlighted { - background: #3875d7; - color: #fff; + background: #3875d7; + color: #fff; } + .select2-results li em { - background: #feffde; - font-style: normal; + background: #feffde; + font-style: normal; } + .select2-results .select2-highlighted em { - background: transparent; + background: transparent; } + +.select2-results .select2-highlighted ul { + background: white; + color: #000; +} + + .select2-results .select2-no-results, .select2-results .select2-searching, .select2-results .select2-selection-limit { - background: #f4f4f4; - display: list-item; + background: #f4f4f4; + display: list-item; } /* -disabled look for already selected choices in the results dropdown +disabled look for disabled choices in the results dropdown +*/ .select2-results .select2-disabled.select2-highlighted { color: #666; background: #f4f4f4; @@ -330,18 +384,18 @@ disabled look for already selected choices in the results dropdown display: list-item; cursor: default; } -*/ -.select2-results .select2-disabled { + +.select2-results .select2-selected { display: none; } .select2-more-results.select2-active { - background: #f4f4f4 url('spinner.gif') no-repeat 100%; + background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%; } .select2-more-results { - background: #f4f4f4; - display: list-item; + background: #f4f4f4; + display: list-item; } /* disabled styles */ @@ -359,25 +413,35 @@ disabled look for already selected choices in the results dropdown border-left: 0; } +.select2-container.select2-container-disabled .select2-choice abbr { + display: none +} + /* multiselect */ .select2-container-multi .select2-choices { + height: auto !important; + height: 1%; + margin: 0; + padding: 0; + position: relative; + + border: 1px solid #aaa; + cursor: text; + overflow: hidden; + background-color: #fff; - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); - background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); - background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); - background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); - background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%); - background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%); - border: 1px solid #aaa; - margin: 0; - padding: 0; - cursor: text; - overflow: hidden; - height: auto !important; - height: 1%; - position: relative; + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); + background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%); +} + +.select2-locked { + padding: 3px 5px 3px 5px !important; } .select2-container-multi .select2-choices { @@ -385,106 +449,116 @@ disabled look for already selected choices in the results dropdown } .select2-container-multi.select2-container-active .select2-choices { - -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); - -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); - -o-box-shadow : 0 0 5px rgba(0,0,0,.3); - box-shadow : 0 0 5px rgba(0,0,0,.3); border: 1px solid #5897fb; outline: none; + + -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); + -moz-box-shadow: 0 0 5px rgba(0,0,0,.3); + box-shadow: 0 0 5px rgba(0,0,0,.3); } .select2-container-multi .select2-choices li { - float: left; - list-style: none; + float: left; + list-style: none; } .select2-container-multi .select2-choices .select2-search-field { - white-space: nowrap; - margin: 0; - padding: 0; + margin: 0; + padding: 0; + white-space: nowrap; } .select2-container-multi .select2-choices .select2-search-field input { - color: #666; - background: transparent !important; - font-family: sans-serif; - font-size: 100%; - height: 15px; - padding: 5px; - margin: 1px 0; - outline: 0; - border: 0; - -webkit-box-shadow: none; - -moz-box-shadow : none; - -o-box-shadow : none; - box-shadow : none; + padding: 5px; + margin: 1px 0; + + font-family: sans-serif; + font-size: 100%; + color: #666; + outline: 0; + border: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background: transparent !important; } .select2-container-multi .select2-choices .select2-search-field input.select2-active { - background: #fff url('spinner.gif') no-repeat 100% !important; + background: #fff url('select2-spinner.gif') no-repeat 100% !important; } .select2-default { - color: #999 !important; + color: #999 !important; } .select2-container-multi .select2-choices .select2-search-choice { - -webkit-border-radius: 3px; - -moz-border-radius : 3px; - border-radius : 3px; - -moz-background-clip : padding; - -webkit-background-clip: padding-box; - background-clip : padding-box; - background-color: #e4e4e4; - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 ); - 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: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - 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; - border: 1px solid #aaaaaa; - line-height: 13px; - padding: 3px 5px 3px 18px; - margin: 3px 0 3px 5px; - position: relative; - cursor: default; + padding: 3px 5px 3px 18px; + margin: 3px 0 3px 5px; + position: relative; + + line-height: 13px; + color: #333; + cursor: default; + border: 1px solid #aaaaaa; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + + -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); + + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + background-color: #e4e4e4; + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0 ); + 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: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); } .select2-container-multi .select2-choices .select2-search-choice span { - cursor: default; + cursor: default; } .select2-container-multi .select2-choices .select2-search-choice-focus { - background: #d4d4d4; + background: #d4d4d4; } .select2-search-choice-close { - display: block; - position: absolute; - right: 3px; - top: 4px; - width: 12px; - height: 13px; - font-size: 1px; - background: url('select2.png') right top no-repeat; - outline: none; + display: block; + width: 12px; + height: 13px; + position: absolute; + right: 3px; + top: 4px; + + font-size: 1px; + outline: none; + background: url('select2.png') right top no-repeat; } .select2-container-multi .select2-search-choice-close { - left: 3px; + left: 3px; } - .select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover { background-position: right -11px; } .select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close { - background-position: right -11px; + background-position: right -11px; } /* disabled styles */ - .select2-container-multi.select2-container-disabled .select2-choices{ background-color: #f4f4f4; background-image: none; @@ -493,10 +567,10 @@ disabled look for already selected choices in the results dropdown } .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice { + padding: 3px 5px 3px 5px; + border: 1px solid #ddd; background-image: none; background-color: #f4f4f4; - border: 1px solid #ddd; - padding: 3px 5px 3px 5px; } .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { @@ -504,21 +578,26 @@ disabled look for already selected choices in the results dropdown } /* end multiselect */ -.select2-result-selectable .select2-match, -.select2-result-unselectable .select2-result-selectable .select2-match { text-decoration: underline; } -.select2-result-unselectable .select2-match { text-decoration: none; } -.select2-offscreen { position: absolute; left: -10000px; } +.select2-result-selectable .select2-match, +.select2-result-unselectable .select2-match { + text-decoration: underline; +} + +.select2-offscreen { + position: absolute; + left: -10000px; +} /* Retina-ize icons */ -@media only screen and (-webkit-min-device-pixel-ratio: 1.5) { - .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b { - background-image: url(select2x2.png) !important; - background-repeat: no-repeat !important; - background-size: 60px 40px !important; - } - .select2-search input { - background-position: 100% -21px !important; - } +@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) { + .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b { + background-image: url('select2x2.png') !important; + background-repeat: no-repeat !important; + background-size: 60px 40px !important; + } + .select2-search input { + background-position: 100% -21px !important; + } } diff --git a/django_select2/static/js/heavy_data.min.js b/django_select2/static/js/heavy_data.min.js index 818815d..9bd5401 100644 --- a/django_select2/static/js/heavy_data.min.js +++ b/django_select2/static/js/heavy_data.min.js @@ -1 +1 @@ -if(!window.django_select2){var django_select2={MULTISEPARATOR:String.fromCharCode(0),get_url_params:function(c,e,b){var d=$(this).data("field_id"),a={term:c,page:e,context:b};if(d){a.field_id=d}return a},process_results:function(d,c,b){var a;if(d.err&&d.err.toLowerCase()==="nil"){a={results:d.results};if(b){a.context=b}if(d.more===true||d.more===false){a.more=d.more}}else{a={results:[]}}if(a.results){$(this).data("results",a.results)}else{$(this).removeData("results")}return a},onValChange:function(){django_select2.updateText($(this))},prepareValText:function(d,a,c){var b=[];$(d).each(function(e){b.push({id:this,text:a[e]})});if(c){return b}else{if(b.length>0){return b[0]}else{return null}}},updateText:function(b){var f=b.select2("val"),d=b.select2("data"),a=b.txt(),c=!!b.attr("multiple"),e;if(f||f===0){if(c){if(f.length!==a.length){a=[];$(f).each(function(g){var h,j=this,k;for(h in d){k=d[h].id;if(k instanceof String){k=k.valueOf()}if(k==j){a.push(d[h].text)}}})}}else{a=d.text}b.txt(a)}else{b.txt("")}},getValText:function(b){var g=b.select2("val"),c=b.data("results"),a=b.txt(),e=!!b.attr("multiple"),d,h=b.attr("id");if(g||g===0){if(!e){g=[g];if(a||a===0){a=[a]}}if(a===0||(a&&g.length===a.length)){return[g,a]}d=b.data("userGetValText");if(d){a=d(b,g,e);if(a||a===0){return[g,a]}}if(c){a=[];$(g).each(function(f){var j,k=this;for(j in c){if(c[j].id==k){g[f]=c[j].id;a.push(c[j].text)}}});if(a||a===0){return[g,a]}}}return null},onInit:function(b,f){b=$(b);var d=b.attr("id"),a=null,c=b.select2("val");if(!c&&c!==0){c=b.data("initVal")}if(c||c===0){a=django_select2.getValText(b);if(a&&a[0]){a=django_select2.prepareValText(a[0],a[1],!!b.attr("multiple"))}}if(!a){b.val(null)}f(a);django_select2.updateText(b)},onMultipleHiddenChange:function(){var b=$(this),d=b.data("valContainer"),a=b.data("name"),c=b.val();d.empty();if(c){c=c.split(django_select2.MULTISEPARATOR);$(c).each(function(){var e=$('').appendTo(d);e.attr("name",a);e.val(this)})}},initMultipleHidden:function(a){var b;a.data("name",a.attr("name"));a.attr("name","");b=$("
").insertAfter(a).css({display:"none"});a.data("valContainer",b);a.change(django_select2.onMultipleHiddenChange);if(a.val()){a.change()}},convertArrToStr:function(a){return a.join(django_select2.MULTISEPARATOR)},runInContextHelper:function(a,b){return function(){var c=Array.prototype.slice.call(arguments);return a.apply($("#"+b).get(0),c)}},logErr:function(){if(console&&console.error){args=Array.prototype.slice.call(arguments);console.error.apply(console,args)}}};(function(a){a.fn.txt=function(b){if(typeof(b)!=="undefined"){if(b){if(b instanceof Array){if(this.attr("multiple")){b=django_select2.convertArrToStr(b)}else{b=b[0]}}this.attr("txt",b)}else{this.removeAttr("txt")}return this}else{b=this.attr("txt");if(this.attr("multiple")){if(b){b=b.split(django_select2.MULTISEPARATOR)}else{b=[]}}return b}}})(jQuery)}; +if(!window.django_select2){var django_select2={MULTISEPARATOR:String.fromCharCode(0),get_url_params:function(c,e,b){var d=$(this).data("field_id"),a={term:c,page:e,context:b};if(d){a.field_id=d}return a},process_results:function(d,c,b){var a;if(d.err&&d.err.toLowerCase()==="nil"){a={results:d.results};if(b){a.context=b}if(d.more===true||d.more===false){a.more=d.more}}else{a={results:[]}}if(a.results){$(this).data("results",a.results)}else{$(this).removeData("results")}return a},onValChange:function(){django_select2.updateText($(this))},prepareValText:function(d,a,c){var b=[];$(d).each(function(e){b.push({id:this,text:a[e]})});if(c){return b}else{if(b.length>0){return b[0]}else{return null}}},updateText:function(b){var f=b.select2("val"),d=b.select2("data"),a=b.txt(),c=!!b.attr("multiple"),e;if(f||f===0){if(c){if(f.length!==a.length){a=[];$(f).each(function(g){var h,j=this,k;for(h in d){k=d[h].id;if(k instanceof String){k=k.valueOf()}if(k==j){a.push(d[h].text)}}})}}else{a=d.text}b.txt(a)}else{b.txt("")}},getValText:function(b){var g=b.select2("val"),c=b.data("results"),a=b.txt(),e=!!b.attr("multiple"),d,h=b.attr("id");if(g||g===0){if(!e){g=[g];if(a||a===0){a=[a]}}if(a===0||(a&&g.length===a.length)){return[g,a]}d=b.data("userGetValText");if(d){a=d(b,g,e);if(a||a===0){return[g,a]}}if(c){a=[];$(g).each(function(f){var j,k=this;for(j in c){if(c[j].id==k){g[f]=c[j].id;a.push(c[j].text)}}});if(a||a===0){return[g,a]}}}return null},onInit:function(b,f){b=$(b);var d=b.attr("id"),a=null,c=b.select2("val");if(!c&&c!==0){c=b.data("initVal")}if(c||c===0){a=django_select2.getValText(b);if(a&&a[0]){a=django_select2.prepareValText(a[0],a[1],!!b.attr("multiple"))}}if(!a){b.val(null)}f(a);django_select2.updateText(b)},onMultipleHiddenChange:function(){var b=$(this),d=b.data("valContainer"),a=b.data("name"),c=b.val();d.empty();if(c){c=c.split(django_select2.MULTISEPARATOR);$(c).each(function(){var e=$('').appendTo(d);e.attr("name",a);e.val(this)})}},initMultipleHidden:function(a){var b;a.data("name",a.attr("name"));a.attr("name","");b=$("
").insertAfter(a).css({display:"none"});a.data("valContainer",b);a.change(django_select2.onMultipleHiddenChange);if(a.val()){a.change()}},convertArrToStr:function(a){return a.join(django_select2.MULTISEPARATOR)},runInContextHelper:function(a,b){return function(){var c=Array.prototype.slice.call(arguments);return a.apply($("#"+b).get(0),c)}},logErr:function(){if(console&&console.error){args=Array.prototype.slice.call(arguments);console.error.apply(console,args)}}};(function(a){a.fn.txt=function(b){if(typeof(b)!=="undefined"){if(b){if(b instanceof Array){if(this.attr("multiple")){b=django_select2.convertArrToStr(b)}else{b=b[0]}}this.attr("txt",b)}else{this.removeAttr("txt")}return this}else{b=this.attr("txt");if(this.attr("multiple")){if(b){b=b.split(django_select2.MULTISEPARATOR)}else{b=[]}}return b}}})(jQuery)}; \ No newline at end of file diff --git a/django_select2/static/js/select2.js b/django_select2/static/js/select2.js index 213f4cf..8be2c7e 100755 --- a/django_select2/static/js/select2.js +++ b/django_select2/static/js/select2.js @@ -1,17 +1,23 @@ /* - Copyright 2012 Igor Vaynberg +Copyright 2012 Igor Vaynberg - Version: 3.2 Timestamp: Mon Sep 10 10:38:04 PDT 2012 +Version: 3.3.1 Timestamp: Wed Feb 20 09:57:22 PST 2013 - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in - compliance with the License. You may obtain a copy of the License in the LICENSE file, or at: +This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU +General Public License version 2 (the "GPL License"). You may choose either license to govern your +use of this software only upon the condition that you accept all of the terms of either the Apache +License or the GPL License. - http://www.apache.org/licenses/LICENSE-2.0 +You may obtain a copy of the Apache License and the GPL License at: - Unless required by applicable law or agreed to in writing, software distributed under the License is - distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and limitations under the License. - */ + http://www.apache.org/licenses/LICENSE-2.0 + http://www.gnu.org/licenses/gpl-2.0.html + +Unless required by applicable law or agreed to in writing, software distributed under the +Apache License or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for +the specific language governing permissions and limitations under the Apache License and the GPL License. +*/ (function ($) { if(typeof $.fn.each2 == "undefined"){ $.fn.extend({ @@ -40,7 +46,8 @@ return; } - var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer; + var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer, + lastMousePosition, $document; KEY = { TAB: 9, @@ -90,32 +97,20 @@ } }; + $document = $(document); + nextUid=(function() { var counter=1; return function() { return counter++; }; }()); function indexOf(value, array) { - var i = 0, l = array.length, v; - - if (typeof value === "undefined") { - return -1; - } - - if (value.constructor === String) { - for (; i < l; i = i + 1) if (value.localeCompare(array[i]) === 0) return i; - } else { - for (; i < l; i = i + 1) { - v = array[i]; - if (v.constructor === String) { - if (v.localeCompare(value) === 0) return i; - } else { - if (v === value) return i; - } - } + var i = 0, l = array.length; + for (; i < l; i = i + 1) { + if (equal(value, array[i])) return i; } return -1; } /** - * Compares equality of a and b taking into account that a and b may be strings, in which case localeCompare is used + * Compares equality of a and b * @param a * @param b */ @@ -123,8 +118,8 @@ if (a === b) return true; if (a === undefined || b === undefined) return false; if (a === null || b === null) return false; - if (a.constructor === String) return a.localeCompare(b) === 0; - if (b.constructor === String) return b.localeCompare(a) === 0; + if (a.constructor === String) return a === b+''; + if (b.constructor === String) return b === a+''; return false; } @@ -143,7 +138,7 @@ } function getSideBorderPadding(element) { - return element.outerWidth() - element.width(); + return element.outerWidth(false) - element.width(); } function installKeyUpChangeEvent(element) { @@ -162,8 +157,8 @@ }); } - $(document).delegate("body", "mousemove", function (e) { - $.data(document, "select2-lastpos", {x: e.pageX, y: e.pageY}); + $document.bind("mousemove", function (e) { + lastMousePosition = {x: e.pageX, y: e.pageY}; }); /** @@ -174,7 +169,7 @@ */ function installFilteredMouseMove(element) { element.bind("mousemove", function (e) { - var lastpos = $.data(document, "select2-lastpos"); + var lastpos = lastMousePosition; if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) { $(e.target).trigger("mousemove-filtered", e); } @@ -223,15 +218,47 @@ }); } + function focus($el) { + if ($el[0] === document.activeElement) return; + + /* set the focus in a 0 timeout - that way the focus is set after the processing + of the current event has finished - which seems like the only reliable way + to set focus */ + window.setTimeout(function() { + var el=$el[0], pos=$el.val().length, range; + + $el.focus(); + + /* after the focus is set move the caret to the end, necessary when we val() + just before setting focus */ + if(el.setSelectionRange) + { + el.setSelectionRange(pos, pos); + } + else if (el.createTextRange) { + range = el.createTextRange(); + range.collapse(true); + range.moveEnd('character', pos); + range.moveStart('character', pos); + range.select(); + } + + }, 0); + } + function killEvent(event) { event.preventDefault(); event.stopPropagation(); } + function killEventImmediately(event) { + event.preventDefault(); + event.stopImmediatePropagation(); + } function measureTextWidth(e) { if (!sizer){ var style = e[0].currentStyle || window.getComputedStyle(e[0], null); - sizer = $("
").css({ + sizer = $(document.createElement("div")).css({ position: "absolute", left: "-10000px", top: "-10000px", @@ -244,26 +271,53 @@ textTransform: style.textTransform, whiteSpace: "nowrap" }); + sizer.attr("class","select2-sizer"); $("body").append(sizer); } sizer.text(e.val()); return sizer.width(); } - function markMatch(text, term, markup) { + function syncCssClasses(dest, src, adapter) { + var classes, replacements = [], adapted; + + classes = dest.attr("class"); + if (typeof classes === "string") { + $(classes.split(" ")).each2(function() { + if (this.indexOf("select2-") === 0) { + replacements.push(this); + } + }); + } + classes = src.attr("class"); + if (typeof classes === "string") { + $(classes.split(" ")).each2(function() { + if (this.indexOf("select2-") !== 0) { + adapted = adapter(this); + if (typeof adapted === "string" && adapted.length > 0) { + replacements.push(this); + } + } + }); + } + dest.attr("class", replacements.join(" ")); + } + + + function markMatch(text, term, markup, escapeMarkup) { var match=text.toUpperCase().indexOf(term.toUpperCase()), tl=term.length; if (match<0) { - markup.push(text); + markup.push(escapeMarkup(text)); return; } - markup.push(text.substring(0, match)); + markup.push(escapeMarkup(text.substring(0, match))); markup.push(""); - markup.push(text.substring(match, match + tl)); + markup.push(escapeMarkup(text.substring(match, match + tl))); markup.push(""); - markup.push(text.substring(match + tl, text.length)); + markup.push(escapeMarkup(text.substring(match + tl, text.length))); } /** @@ -286,7 +340,9 @@ var timeout, // current scheduled but not yet executed request requestSequence = 0, // sequence used to drop out-of-order responses handler = null, - quietMillis = options.quietMillis || 100; + quietMillis = options.quietMillis || 100, + ajaxUrl = options.url, + self = this; return function (query) { window.clearTimeout(timeout); @@ -294,29 +350,40 @@ requestSequence += 1; // increment the sequence var requestNumber = requestSequence, // this request's sequence number data = options.data, // ajax data function + url = ajaxUrl, // ajax url string or function transport = options.transport || $.ajax, - traditional = options.traditional || false, - type = options.type || 'GET'; // set type of request (GET or POST) + type = options.type || 'GET', // set type of request (GET or POST) + params = {}; - data = data.call(this, query.term, query.page, query.context); + data = data ? data.call(self, query.term, query.page, query.context) : null; + url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url; if( null !== handler) { handler.abort(); } - handler = transport.call(null, { - url: options.url, + if (options.params) { + if ($.isFunction(options.params)) { + $.extend(params, options.params.call(self)); + } else { + $.extend(params, options.params); + } + } + + $.extend(params, { + url: url, dataType: options.dataType, data: data, type: type, - traditional: traditional, + cache: false, success: function (data) { if (requestNumber < requestSequence) { return; } - // TODO 3.0 - replace query.page with query so users have access to term, page, etc. + // TODO - replace query.page with query so users have access to term, page, etc. var results = options.results(data, query.page); query.callback(results); } }); + handler = transport.call(self, params); }, quietMillis); }; } @@ -338,22 +405,33 @@ function local(options) { var data = options, // data elements dataText, + tmp, text = function (item) { return ""+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search - if (!$.isArray(data)) { - text = data.text; + if ($.isArray(data)) { + tmp = data; + data = { results: tmp }; + } + + if ($.isFunction(data) === false) { + tmp = data; + data = function() { return tmp; }; + } + + var dataItem = data(); + if (dataItem.text) { + text = dataItem.text; // if text is not a function we assume it to be a key name if (!$.isFunction(text)) { - dataText = data.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available - text = function (item) { return item[dataText]; }; + dataText = data.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available + text = function (item) { return item[dataText]; }; } - data = data.results; } return function (query) { var t = query.term, filtered = { results: [] }, process; if (t === "") { - query.callback({results: data}); + query.callback(data()); return; } @@ -367,34 +445,27 @@ } group.children=[]; $(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); }); - if (group.children.length) { + if (group.children.length || query.matcher(t, text(group), datum)) { collection.push(group); } } else { - if (query.matcher(t, text(datum))) { + if (query.matcher(t, text(datum), datum)) { collection.push(datum); } } }; - $(data).each2(function(i, datum) { process(datum, filtered.results); }); + $(data().results).each2(function(i, datum) { process(datum, filtered.results); }); query.callback(filtered); }; } // TODO javadoc function tags(data) { - // TODO even for a function we should probably return a wrapper that does the same object/string check as - // the function for arrays. otherwise only functions that return objects are supported. - if ($.isFunction(data)) { - return data; - } - - // if not a function we assume it to be an array - + var isFunc = $.isFunction(data); return function (query) { var t = query.term, filtered = {results: []}; - $(data).each(function () { + $(isFunc ? data() : data).each(function () { var isObject = this.text !== undefined, text = isObject ? this.text : this; if (t === "" || query.matcher(t, text)) { @@ -485,38 +556,9 @@ } } - if (original.localeCompare(input) != 0) return input; + if (original!==input) return input; } - /** - * blurs any Select2 container that has focus when an element outside them was clicked or received focus - * - * also takes care of clicks on label tags that point to the source element - */ - $(document).ready(function () { - $(document).delegate("body", "mousedown touchend", function (e) { - var target = $(e.target).closest("div.select2-container").get(0), attr; - if (target) { - $(document).find("div.select2-container-active").each(function () { - if (this !== target) $(this).data("select2").blur(); - }); - } else { - target = $(e.target).closest("div.select2-drop").get(0); - $(document).find("div.select2-drop-active").each(function () { - if (this !== target) $(this).data("select2").blur(); - }); - } - - target=$(e.target); - attr = target.attr("for"); - if ("LABEL" === e.target.tagName && attr && attr.length > 0) { - target = $("#"+attr); - target = target.data("select2"); - if (target !== undefined) { target.focus(); e.preventDefault();} - } - }); - }); - /** * Creates a new class * @@ -544,7 +586,7 @@ // abstract init: function (opts) { - var results, search, resultsSelector = ".select2-results"; + var results, search, resultsSelector = ".select2-results", mask; // prepare options this.opts = opts = this.prepareOpts(opts); @@ -567,17 +609,19 @@ // cache the body so future lookups are cheap this.body = thunk(function() { return opts.element.closest("body"); }); - if (opts.element.attr("class") !== undefined) { - this.container.addClass(opts.element.attr("class").replace(/validate\[[\S ]+] ?/, '')); - } + syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass); this.container.css(evaluate(opts.containerCss)); this.container.addClass(evaluate(opts.containerCssClass)); + this.elementTabIndex = this.opts.element.attr("tabIndex"); + // swap container for the element this.opts.element .data("select2", this) - .hide() + .addClass("select2-offscreen") + .bind("focus.select2", function() { $(this).select2("focus"); }) + .attr("tabIndex", "-1") .before(this.container); this.container.data("select2", this); @@ -588,17 +632,16 @@ this.results = results = this.container.find(resultsSelector); this.search = search = this.container.find("input.select2-input"); - search.attr("tabIndex", this.opts.element.attr("tabIndex")); + search.attr("tabIndex", this.elementTabIndex); this.resultsPage = 0; this.context = null; // initialize the container this.initContainer(); - this.initContainerWidth(); installFilteredMouseMove(this.results); - this.dropdown.delegate(resultsSelector, "mousemove-filtered", this.bind(this.highlightUnderEvent)); + this.dropdown.delegate(resultsSelector, "mousemove-filtered touchstart touchmove touchend", this.bind(this.highlightUnderEvent)); installDebouncedScroll(80, this.results); this.dropdown.delegate(resultsSelector, "scroll-debounced", this.bind(this.loadMoreIfNeeded)); @@ -618,18 +661,15 @@ } installKeyUpChangeEvent(search); - search.bind("keyup-change", this.bind(this.updateResults)); - search.bind("focus", function () { search.addClass("select2-focused"); if (search.val() === " ") search.val(""); }); + search.bind("keyup-change input paste", this.bind(this.updateResults)); + search.bind("focus", function () { search.addClass("select2-focused"); }); search.bind("blur", function () { search.removeClass("select2-focused");}); this.dropdown.delegate(resultsSelector, "mouseup", this.bind(function (e) { - if ($(e.target).closest(".select2-result-selectable:not(.select2-disabled)").length > 0) { + if ($(e.target).closest(".select2-result-selectable").length > 0) { this.highlightUnderEvent(e); this.selectHighlighted(e); - } else { - this.focusSearch(); } - killEvent(e); })); // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening @@ -652,12 +692,18 @@ // abstract destroy: function () { var select2 = this.opts.element.data("select2"); + + if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; } + if (select2 !== undefined) { + select2.container.remove(); select2.dropdown.remove(); select2.opts.element + .removeClass("select2-offscreen") .removeData("select2") .unbind(".select2") + .attr({"tabIndex": this.elementTabIndex}) .show(); } }, @@ -687,26 +733,33 @@ populate=function(results, container, depth) { - var i, l, result, selectable, compound, node, label, innerContainer, formatted; + var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted; + + results = opts.sortResults(results, container, query); + for (i = 0, l = results.length; i < l; i = i + 1) { result=results[i]; - selectable=id(result) !== undefined; + + disabled = (result.disabled === true); + selectable = (!disabled) && (id(result) !== undefined); + compound=result.children && result.children.length > 0; node=$("
  • "); node.addClass("select2-results-dept-"+depth); node.addClass("select2-result"); node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable"); + if (disabled) { node.addClass("select2-disabled"); } if (compound) { node.addClass("select2-result-with-children"); } node.addClass(self.opts.formatResultCssClass(result)); - label=$("
    "); + label=$(document.createElement("div")); label.addClass("select2-result-label"); - formatted=opts.formatResult(result, label, query); + formatted=opts.formatResult(result, label, query, self.opts.escapeMarkup); if (formatted!==undefined) { - label.html(self.opts.escapeMarkup(formatted)); + label.html(formatted); } node.append(label); @@ -733,6 +786,13 @@ opts.id = function (e) { return e[idKey]; }; } + if ($.isArray(opts.element.data("select2Tags"))) { + if ("tags" in opts) { + throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id"); + } + opts.tags=opts.element.attr("data-select2-tags"); + } + if (select) { opts.query = this.bind(function (query) { var data = { results: [], more: false }, @@ -743,7 +803,7 @@ var group; if (element.is("option")) { if (query.matcher(term, element.text(), element)) { - collection.push({id:element.attr("value"), text:element.text(), element: element.get(), css: element.attr("class")}); + collection.push({id:element.attr("value"), text:element.text(), element: element.get(), css: element.attr("class"), disabled: equal(element.attr("disabled"), "disabled") }); } } else if (element.is("optgroup")) { group={text:element.attr("label"), children:[], element: element.get(), css: element.attr("class")}; @@ -770,31 +830,36 @@ }); // this is needed because inside val() we construct choices from options and there id is hardcoded opts.id=function(e) { return e.id; }; - opts.formatResultCssClass = function(data) { return data.css; } + opts.formatResultCssClass = function(data) { return data.css; }; } else { if (!("query" in opts)) { + if ("ajax" in opts) { ajaxUrl = opts.element.data("ajax-url"); if (ajaxUrl && ajaxUrl.length > 0) { opts.ajax.url = ajaxUrl; } - opts.query = ajax(opts.ajax); + opts.query = ajax.call(opts.element, opts.ajax); } else if ("data" in opts) { opts.query = local(opts.data); } else if ("tags" in opts) { opts.query = tags(opts.tags); - opts.createSearchChoice = function (term) { return {id: term, text: term}; }; - opts.initSelection = function (element, callback) { - var data = []; - $(splitVal(element.val(), opts.separator)).each(function () { - var id = this, text = this, tags=opts.tags; - if ($.isFunction(tags)) tags=tags(); - $(tags).each(function() { if (equal(this.id, id)) { text = this.text; return false; } }); - data.push({id: id, text: text}); - }); + if (opts.createSearchChoice === undefined) { + opts.createSearchChoice = function (term) { return {id: term, text: term}; }; + } + if (opts.initSelection === undefined) { + opts.initSelection = function (element, callback) { + var data = []; + $(splitVal(element.val(), opts.separator)).each(function () { + var id = this, text = this, tags=opts.tags; + if ($.isFunction(tags)) tags=tags(); + $(tags).each(function() { if (equal(this.id, id)) { text = this.text; return false; } }); + data.push({id: id, text: text}); + }); - callback(data); - }; + callback(data); + }; + } } } } @@ -810,11 +875,52 @@ */ // abstract monitorSource: function () { - this.opts.element.bind("change.select2", this.bind(function (e) { + var el = this.opts.element, sync; + + el.bind("change.select2", this.bind(function (e) { if (this.opts.element.data("select2-change-triggered") !== true) { this.initSelection(); } })); + + sync = this.bind(function () { + + var enabled, readonly, self = this; + + // sync enabled state + + enabled = this.opts.element.attr("disabled") !== "disabled"; + readonly = this.opts.element.attr("readonly") === "readonly"; + + enabled = enabled && !readonly; + + if (this.enabled !== enabled) { + if (enabled) { + this.enable(); + } else { + this.disable(); + } + } + + + syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass); + this.container.addClass(evaluate(this.opts.containerCssClass)); + + syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass); + this.dropdown.addClass(evaluate(this.opts.dropdownCssClass)); + + }); + + // mozilla and IE + el.bind("propertychange.select2 DOMAttrModified.select2", sync); + // safari and chrome + if (typeof WebKitMutationObserver !== "undefined") { + if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; } + this.propertyObserver = new WebKitMutationObserver(function (mutations) { + mutations.forEach(sync); + }); + this.propertyObserver.observe(el.get(0), { attributes:true, subtree:false }); + } }, /** @@ -840,13 +946,13 @@ this.opts.element.blur(); }, - // abstract enable: function() { if (this.enabled) return; this.enabled=true; this.container.removeClass("select2-container-disabled"); + this.opts.element.removeAttr("disabled"); }, // abstract @@ -857,6 +963,7 @@ this.enabled=false; this.container.addClass("select2-container-disabled"); + this.opts.element.attr("disabled", "disabled"); }, // abstract @@ -867,21 +974,24 @@ // abstract positionDropdown: function() { var offset = this.container.offset(), - height = this.container.outerHeight(), - width = this.container.outerWidth(), - dropHeight = this.dropdown.outerHeight(), - viewportBottom = $(window).scrollTop() + document.documentElement.clientHeight, + height = this.container.outerHeight(false), + width = this.container.outerWidth(false), + dropHeight = this.dropdown.outerHeight(false), + viewPortRight = $(window).scrollLeft() + $(window).width(), + viewportBottom = $(window).scrollTop() + $(window).height(), dropTop = offset.top + height, dropLeft = offset.left, enoughRoomBelow = dropTop + dropHeight <= viewportBottom, enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(), + dropWidth = this.dropdown.outerWidth(false), + enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight, aboveNow = this.dropdown.hasClass("select2-drop-above"), bodyOffset, above, css; - // console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow); - // console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body().scrollTop(), "enough?", enoughRoomAbove); + //console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow); + //console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body().scrollTop(), "enough?", enoughRoomAbove); // fix positioning when body has an offset and is not position: static @@ -901,6 +1011,10 @@ if (!enoughRoomBelow && enoughRoomAbove) above = true; } + if (!enoughRoomOnRight) { + dropLeft = offset.left + width - dropWidth; + } + if (above) { dropTop = offset.top - dropHeight; this.container.addClass("select2-drop-above"); @@ -926,7 +1040,7 @@ if (this.opened()) return false; - event = $.Event("open"); + event = $.Event("opening"); this.opts.element.trigger(event); return !event.isDefaultPrevented(); }, @@ -959,46 +1073,74 @@ */ // abstract opening: function() { - var cid = this.containerId, selector = this.containerSelector, - scroll = "scroll." + cid, resize = "resize." + cid; - - this.container.parents().each(function() { - $(this).bind(scroll, function() { - var s2 = $(selector); - if (s2.length == 0) { - $(this).unbind(scroll); - } - s2.select2("close"); - }); - }); - - $(window).bind(resize, function() { - var s2 = $(selector); - if (s2.length == 0) { - $(window).unbind(resize); - } - s2.select2("close"); - }); + var cid = this.containerId, + scroll = "scroll." + cid, + resize = "resize."+cid, + orient = "orientationchange."+cid, + mask; this.clearDropdownAlignmentPreference(); - if (this.search.val() === " ") { this.search.val(""); } - this.container.addClass("select2-dropdown-open").addClass("select2-container-active"); - this.updateResults(true); if(this.dropdown[0] !== this.body().children().last()[0]) { this.dropdown.detach().appendTo(this.body()); } + this.updateResults(true); + + // create the dropdown mask if doesnt already exist + mask = $("#select2-drop-mask"); + if (mask.length == 0) { + mask = $(document.createElement("div")); + mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask"); + mask.hide(); + mask.appendTo(this.body()); + mask.bind("mousedown touchstart", function (e) { + var dropdown = $("#select2-drop"), self; + if (dropdown.length > 0) { + self=dropdown.data("select2"); + if (self.opts.selectOnBlur) { + self.selectHighlighted({noFocus: true}); + } + self.close(); + } + }); + } + + // ensure the mask is always right before the dropdown + if (this.dropdown.prev()[0] !== mask[0]) { + this.dropdown.before(mask); + } + + // move the global id to the correct dropdown + $("#select2-drop").removeAttr("id"); + this.dropdown.attr("id", "select2-drop"); + + // show the elements + mask.css({ + width: document.documentElement.scrollWidth, + height: document.documentElement.scrollHeight}); + mask.show(); this.dropdown.show(); - this.positionDropdown(); - this.dropdown.addClass("select2-drop-active"); + this.dropdown.addClass("select2-drop-active"); this.ensureHighlightVisible(); + // attach listeners to events that can change the position of the container and thus require + // the position of the dropdown to be updated as well so it does not come unglued from the container + var that = this; + this.container.parents().add(window).each(function () { + $(this).bind(resize+" "+scroll+" "+orient, function (e) { + $("#select2-drop-mask").css({ + width:document.documentElement.scrollWidth, + height:document.documentElement.scrollHeight}); + that.positionDropdown(); + }); + }); + this.focusSearch(); }, @@ -1006,17 +1148,20 @@ close: function () { if (!this.opened()) return; - var self = this; + var cid = this.containerId, + scroll = "scroll." + cid, + resize = "resize."+cid, + orient = "orientationchange."+cid; - this.container.parents().each(function() { - $(this).unbind("scroll." + self.containerId); - }); - $(window).unbind("resize." + this.containerId); + // unbind event listeners + this.container.parents().add(window).each(function () { $(this).unbind(scroll).unbind(resize).unbind(orient); }); this.clearDropdownAlignmentPreference(); + $("#select2-drop-mask").hide(); + this.dropdown.removeAttr("id"); // only the active dropdown has the select2-drop id this.dropdown.hide(); - this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active"); + this.container.removeClass("select2-dropdown-open"); this.results.empty(); this.clearSearch(); @@ -1028,6 +1173,11 @@ }, + //abstract + getMaximumSelectionSize: function() { + return evaluate(this.opts.maximumSelectionSize); + }, + // abstract ensureHighlightVisible: function () { var results = this.results, children, index, child, hb, rb, y, more; @@ -1046,41 +1196,47 @@ return; } - children = results.find(".select2-result-selectable"); + children = this.findHighlightableChoices(); child = $(children[index]); - hb = child.offset().top + child.outerHeight(); + hb = child.offset().top + child.outerHeight(true); // if this is the last child lets also make sure select2-more-results is visible if (index === children.length - 1) { more = results.find("li.select2-more-results"); if (more.length > 0) { - hb = more.offset().top + more.outerHeight(); + hb = more.offset().top + more.outerHeight(true); } } - rb = results.offset().top + results.outerHeight(); + rb = results.offset().top + results.outerHeight(true); if (hb > rb) { results.scrollTop(results.scrollTop() + (hb - rb)); } y = child.offset().top - results.offset().top; // make sure the top of the element is visible - if (y < 0) { + if (y < 0 && child.css('display') != 'none' ) { results.scrollTop(results.scrollTop() + y); // y is negative } }, + // abstract + findHighlightableChoices: function() { + var h=this.results.find(".select2-result-selectable:not(.select2-selected):not(.select2-disabled)"); + return this.results.find(".select2-result-selectable:not(.select2-selected):not(.select2-disabled)"); + }, + // abstract moveHighlight: function (delta) { - var choices = this.results.find(".select2-result-selectable"), + var choices = this.findHighlightableChoices(), index = this.highlight(); while (index > -1 && index < choices.length) { index += delta; var choice = $(choices[index]); - if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled")) { + if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled") && !choice.hasClass("select2-selected")) { this.highlight(index); break; } @@ -1089,7 +1245,9 @@ // abstract highlight: function (index) { - var choices = this.results.find(".select2-result-selectable").not(".select2-disabled"); + var choices = this.findHighlightableChoices(), + choice, + data; if (arguments.length === 0) { return indexOf(choices.filter(".select2-highlighted")[0], choices.get()); @@ -1098,23 +1256,29 @@ if (index >= choices.length) index = choices.length - 1; if (index < 0) index = 0; - choices.removeClass("select2-highlighted"); + this.results.find(".select2-highlighted").removeClass("select2-highlighted"); + + choice = $(choices[index]); + choice.addClass("select2-highlighted"); - $(choices[index]).addClass("select2-highlighted"); this.ensureHighlightVisible(); + data = choice.data("select2-data"); + if (data) { + this.opts.element.trigger({ type: "highlight", val: this.id(data), choice: data }); + } }, // abstract countSelectableResults: function() { - return this.results.find(".select2-result-selectable").not(".select2-disabled").length; + return this.findHighlightableChoices().length; }, // abstract highlightUnderEvent: function (event) { var el = $(event.target).closest(".select2-result-selectable"); if (el.length > 0 && !el.is(".select2-highlighted")) { - var choices = this.results.find('.select2-result-selectable'); + var choices = this.findHighlightableChoices(); this.highlight(choices.index(el)); } else if (el.length == 0) { // if we are over an unselectable item remove al highlights @@ -1136,9 +1300,10 @@ if (more.length === 0) return; below = more.offset().top - results.offset().top - results.height(); - if (below <= 0) { + if (below <= this.opts.loadMorePadding) { more.addClass("select2-active"); this.opts.query({ + element: this.opts.element, term: term, page: page, context: context, @@ -1159,6 +1324,7 @@ } self.positionDropdown(); self.resultsPage = page; + self.context = data.context; })}); } }, @@ -1191,26 +1357,40 @@ } function render(html) { - results.html(self.opts.escapeMarkup(html)); + results.html(html); postRender(); } - if (opts.maximumSelectionSize >=1) { + var maxSelSize = this.getMaximumSelectionSize(); + if (maxSelSize >=1) { data = this.data(); - if ($.isArray(data) && data.length >= opts.maximumSelectionSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) { - render("
  • " + opts.formatSelectionTooBig(opts.maximumSelectionSize) + "
  • "); + if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) { + render("
  • " + opts.formatSelectionTooBig(maxSelSize) + "
  • "); return; } } - if (search.val().length < opts.minimumInputLength && checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) { - render("
  • " + opts.formatInputTooShort(search.val(), opts.minimumInputLength) + "
  • "); + if (search.val().length < opts.minimumInputLength) { + if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) { + render("
  • " + opts.formatInputTooShort(search.val(), opts.minimumInputLength) + "
  • "); + } else { + render(""); + } return; } - else { + else if (opts.formatSearching() && initial===true) { render("
  • " + opts.formatSearching() + "
  • "); } + if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) { + if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) { + render("
  • " + opts.formatInputTooLong(search.val(), opts.maximumInputLength) + "
  • "); + } else { + render(""); + } + return; + } + // give the tokenizer a chance to pre-process the input input = this.tokenize(); if (input != undefined && input != null) { @@ -1218,7 +1398,9 @@ } this.resultsPage = 1; + opts.query({ + element: opts.element, term: search.val(), page: this.resultsPage, context: null, @@ -1231,7 +1413,6 @@ // save context, if any this.context = (data.context===undefined) ? null : data.context; - // create a default choice and prepend it to the list if (this.opts.createSearchChoice && search.val() !== "") { def = this.opts.createSearchChoice.call(null, search.val(), data.results); @@ -1271,9 +1452,12 @@ // abstract blur: function () { + // if selectOnBlur == true, select the currently highlighted option + if (this.opts.selectOnBlur) + this.selectHighlighted({noFocus: true}); + this.close(); this.container.removeClass("select2-container-active"); - this.dropdown.removeClass("select2-drop-active"); // synonymous to .is(':focus'), which is available in jquery >= 1.6 if (this.search[0] === document.activeElement) { this.search.blur(); } this.clearSearch(); @@ -1282,29 +1466,18 @@ // abstract focusSearch: function () { - // need to do it here as well as in timeout so it works in IE - this.search.show(); - this.search.focus(); - - /* we do this in a timeout so that current event processing can complete before this code is executed. - this makes sure the search field is focussed even if the current event would blur it */ - window.setTimeout(this.bind(function () { - // reset the value so IE places the cursor at the end of the input box - this.search.show(); - this.search.focus(); - this.search.val(this.search.val()); - }), 10); + focus(this.search); }, // abstract - selectHighlighted: function () { + selectHighlighted: function (options) { var index=this.highlight(), - highlighted=this.results.find(".select2-highlighted").not(".select2-disabled"), - data = highlighted.closest('.select2-result-selectable').data("select2-data"); + highlighted=this.results.find(".select2-highlighted"), + data = highlighted.closest('.select2-result').data("select2-data"); + if (data) { - highlighted.addClass("select2-disabled"); this.highlight(index); - this.onSelect(data); + this.onSelect(data, options); } }, @@ -1330,7 +1503,7 @@ if (this.opts.width === "off") { return null; } else if (this.opts.width === "element"){ - return this.opts.element.outerWidth() === 0 ? 'auto' : this.opts.element.outerWidth() + 'px'; + return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px'; } else if (this.opts.width === "copy" || this.opts.width === "resolve") { // check if there is inline style on the element that contains width style = this.opts.element.attr('style'); @@ -1351,7 +1524,7 @@ if (style.indexOf("%") > 0) return style; // finally, fallback on the calculated width of the element - return (this.opts.element.outerWidth() === 0 ? 'auto' : this.opts.element.outerWidth() + 'px'); + return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px'); } return null; @@ -1364,7 +1537,7 @@ var width = resolveContainerWidth.call(this); if (width !== null) { - this.container.attr("style", "width: "+width); + this.container.css("width", width); } } }); @@ -1374,14 +1547,15 @@ // single createContainer: function () { - var container = $("
    ", { + var container = $(document.createElement("div")).attr({ "class": "select2-container" }).html([ - " ", + "", " ", "
    " , "
    ", - "
    " , + "", + "","
      ","
    ","
    "].join(""));return C},opening:function(){this.search.show();this.parent.opening.apply(this,arguments);this.dropdown.removeClass("select2-offscreen")},close:function(){if(!this.opened()){return}this.parent.close.apply(this,arguments);this.dropdown.removeAttr("style").addClass("select2-offscreen").insertAfter(this.selection).show()},focus:function(){this.close();this.selection.focus()},isFocused:function(){return this.selection[0]===document.activeElement},cancel:function(){this.parent.cancel.apply(this,arguments);this.selection.focus()},initContainer:function(){var E,D=this.container,F=this.dropdown,C=false;this.selection=E=D.find(".select2-choice");this.search.bind("keydown",this.bind(function(G){if(!this.enabled){return}if(G.which===c.PAGE_UP||G.which===c.PAGE_DOWN){d(G);return}if(this.opened()){switch(G.which){case c.UP:case c.DOWN:this.moveHighlight((G.which===c.UP)?-1:1);d(G);return;case c.TAB:case c.ENTER:this.selectHighlighted();d(G);return;case c.ESC:this.cancel(G);d(G);return}}else{if(G.which===c.TAB||c.isControl(G)||c.isFunctionKey(G)||G.which===c.ESC){return}if(this.opts.openOnEnter===false&&G.which===c.ENTER){return}this.open();if(G.which===c.ENTER){return}}}));this.search.bind("focus",this.bind(function(){this.selection.attr("tabIndex","-1")}));this.search.bind("blur",this.bind(function(){if(!this.opened()){this.container.removeClass("select2-container-active")}window.setTimeout(this.bind(function(){this.selection.attr("tabIndex",this.opts.element.attr("tabIndex"))}),10)}));E.bind("mousedown",this.bind(function(G){C=true;if(this.opened()){this.close();this.selection.focus()}else{if(this.enabled){this.open()}}C=false}));F.bind("mousedown",this.bind(function(){this.search.focus()}));E.bind("focus",this.bind(function(){this.container.addClass("select2-container-active");this.search.attr("tabIndex","-1")}));E.bind("blur",this.bind(function(){if(!this.opened()){this.container.removeClass("select2-container-active")}window.setTimeout(this.bind(function(){this.search.attr("tabIndex",this.opts.element.attr("tabIndex"))}),10)}));E.bind("keydown",this.bind(function(H){if(!this.enabled){return}if(H.which===c.PAGE_UP||H.which===c.PAGE_DOWN){d(H);return}if(H.which===c.TAB||c.isControl(H)||c.isFunctionKey(H)||H.which===c.ESC){return}if(this.opts.openOnEnter===false&&H.which===c.ENTER){return}if(H.which==c.DELETE){if(this.opts.allowClear){this.clear()}return}this.open();if(H.which===c.ENTER){d(H);return}if(H.which<48){d(H);return}var G=String.fromCharCode(H.which).toLowerCase();if(H.shiftKey){G=G.toUpperCase()}this.search.focus();this.search.val(G);d(H)}));E.delegate("abbr","mousedown",this.bind(function(G){if(!this.enabled){return}this.clear();d(G);this.close();this.triggerChange();this.selection.focus()}));this.setPlaceholder();this.search.bind("focus",this.bind(function(){this.container.addClass("select2-container-active")}))},clear:function(){this.opts.element.val("");this.selection.find("span").empty();this.selection.removeData("select2-data");this.setPlaceholder()},initSelection:function(){var D;if(this.opts.element.val()===""){this.close();this.setPlaceholder()}else{var C=this;this.opts.initSelection.call(null,this.opts.element,function(E){if(E!==l&&E!==null){C.updateSelection(E);C.close();C.setPlaceholder()}})}},prepareOpts:function(){var C=this.parent.prepareOpts.apply(this,arguments);if(C.element.get(0).tagName.toLowerCase()==="select"){C.initSelection=function(D,F){var E=D.find(":selected");if(j.isFunction(F)){F({id:E.attr("value"),text:E.text()})}}}return C},setPlaceholder:function(){var C=this.getPlaceholder();if(this.opts.element.val()===""&&C!==l){if(this.select&&this.select.find("option:first").text()!==""){return}this.selection.find("span").html(this.opts.escapeMarkup(C));this.selection.addClass("select2-default");this.selection.find("abbr").hide()}},postprocessResults:function(F,D){var E=0,C=this,G=true;this.results.find(".select2-result-selectable").each2(function(H,I){if(q(C.id(I.data("select2-data")),C.opts.element.val())){E=H;return false}});this.highlight(E);if(D===true){G=this.showSearchInput=h(F.results)>=this.opts.minimumResultsForSearch;this.dropdown.find(".select2-search")[G?"removeClass":"addClass"]("select2-search-hidden");j(this.dropdown,this.container)[G?"addClass":"removeClass"]("select2-with-searchbox")}},onSelect:function(D){var C=this.opts.element.val();this.opts.element.val(this.id(D));this.updateSelection(D);this.close();this.selection.focus();if(!q(C,this.id(D))){this.triggerChange()}},updateSelection:function(E){var C=this.selection.find("span"),D;this.selection.data("select2-data",E);C.empty();D=this.opts.formatSelection(E,C);if(D!==l){C.append(this.opts.escapeMarkup(D))}this.selection.removeClass("select2-default");if(this.opts.allowClear&&this.getPlaceholder()!==l){this.selection.find("abbr").show()}},val:function(){var E,D=null,C=this;if(arguments.length===0){return this.opts.element.val()}E=arguments[0];if(this.select){this.select.val(E).find(":selected").each2(function(F,G){D={id:G.attr("value"),text:G.text()};return false});this.updateSelection(D);this.setPlaceholder()}else{if(this.opts.initSelection===l){throw new Error("cannot call val() if initSelection() is not defined")}if(!E){this.clear();return}this.opts.element.val(E);this.opts.initSelection(this.opts.element,function(F){C.opts.element.val(!F?"":C.id(F));C.updateSelection(F);C.setPlaceholder()})}},clearSearch:function(){this.search.val("")},data:function(D){var C;if(arguments.length===0){C=this.selection.data("select2-data");if(C==l){C=null}return C}else{if(!D||D===""){this.clear()}else{this.opts.element.val(!D?"":this.id(D));this.updateSelection(D)}}}});B=w(e,{createContainer:function(){var C=j("
    ",{"class":"select2-container select2-container-multi"}).html(["
      ","
    • "," ","
    • ","
    ",""].join(""));return C},prepareOpts:function(){var C=this.parent.prepareOpts.apply(this,arguments);if(C.element.get(0).tagName.toLowerCase()==="select"){C.initSelection=function(D,F){var E=[];D.find(":selected").each2(function(G,H){E.push({id:H.attr("value"),text:H.text()})});if(j.isFunction(F)){F(E)}}}return C},initContainer:function(){var C=".select2-choices",D;this.searchContainer=this.container.find(".select2-search-field");this.selection=D=this.container.find(C);this.search.bind("keydown",this.bind(function(F){if(!this.enabled){return}if(F.which===c.BACKSPACE&&this.search.val()===""){this.close();var G,E=D.find(".select2-search-choice-focus");if(E.length>0){this.unselect(E.first());this.search.width(10);d(F);return}G=D.find(".select2-search-choice");if(G.length>0){G.last().addClass("select2-search-choice-focus")}}else{D.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")}if(this.opened()){switch(F.which){case c.UP:case c.DOWN:this.moveHighlight((F.which===c.UP)?-1:1);d(F);return;case c.ENTER:case c.TAB:this.selectHighlighted();d(F);return;case c.ESC:this.cancel(F);d(F);return}}if(F.which===c.TAB||c.isControl(F)||c.isFunctionKey(F)||F.which===c.BACKSPACE||F.which===c.ESC){return}if(this.opts.openOnEnter===false&&F.which===c.ENTER){return}this.open();if(F.which===c.PAGE_UP||F.which===c.PAGE_DOWN){d(F)}}));this.search.bind("keyup",this.bind(this.resizeSearch));this.search.bind("blur",this.bind(function(E){this.container.removeClass("select2-container-active");this.search.removeClass("select2-focused");this.clearSearch();E.stopImmediatePropagation()}));this.container.delegate(C,"mousedown",this.bind(function(E){if(!this.enabled){return}if(j(E.target).closest(".select2-search-choice").length>0){return}this.clearPlaceholder();this.open();this.focusSearch();E.preventDefault()}));this.container.delegate(C,"focus",this.bind(function(){if(!this.enabled){return}this.container.addClass("select2-container-active");this.dropdown.addClass("select2-drop-active");this.clearPlaceholder()}));this.clearSearch()},enable:function(){if(this.enabled){return}this.parent.enable.apply(this,arguments);this.search.removeAttr("disabled")},disable:function(){if(!this.enabled){return}this.parent.disable.apply(this,arguments);this.search.attr("disabled",true)},initSelection:function(){var D;if(this.opts.element.val()===""){this.updateSelection([]);this.close();this.clearSearch()}if(this.select||this.opts.element.val()!==""){var C=this;this.opts.initSelection.call(null,this.opts.element,function(E){if(E!==l&&E!==null){C.updateSelection(E);C.close();C.clearSearch()}})}},clearSearch:function(){var C=this.getPlaceholder();if(C!==l&&this.getVal().length===0&&this.search.hasClass("select2-focused")===false){this.search.val(C).addClass("select2-default");this.resizeSearch()}else{this.search.val(" ").width(10)}},clearPlaceholder:function(){if(this.search.hasClass("select2-default")){this.search.val("").removeClass("select2-default")}else{if(this.search.val()===" "){this.search.val("")}}},opening:function(){this.parent.opening.apply(this,arguments);this.clearPlaceholder();this.resizeSearch();this.focusSearch()},close:function(){if(!this.opened()){return}this.parent.close.apply(this,arguments)},focus:function(){this.close();this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(F){var E=[],D=[],C=this;j(F).each(function(){if(b(C.id(this),E)<0){E.push(C.id(this));D.push(this)}});F=D;this.selection.find(".select2-search-choice").remove();j(F).each(function(){C.addSelectedChoice(this)});C.postprocessResults()},tokenize:function(){var C=this.search.val();C=this.opts.tokenizer(C,this.data(),this.bind(this.onSelect),this.opts);if(C!=null&&C!=l){this.search.val(C);if(C.length>0){this.open()}}},onSelect:function(C){this.addSelectedChoice(C);if(this.select){this.postprocessResults()}if(this.opts.closeOnSelect){this.close();this.search.width(10)}else{if(this.countSelectableResults()>0){this.search.width(10);this.resizeSearch();this.positionDropdown()}else{this.close()}}this.triggerChange({added:C});this.focusSearch()},cancel:function(){this.close();this.focusSearch()},addSelectedChoice:function(E){var C=j("
  • "),G=this.id(E),F=this.getVal(),D;D=this.opts.formatSelection(E,C);C.find("div").replaceWith("
    "+this.opts.escapeMarkup(D)+"
    ");C.find(".select2-search-choice-close").bind("mousedown",d).bind("click dblclick",this.bind(function(H){if(!this.enabled){return}j(H.target).closest(".select2-search-choice").fadeOut("fast",this.bind(function(){this.unselect(j(H.target));this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");this.close();this.focusSearch()})).dequeue();d(H)})).bind("focus",this.bind(function(){if(!this.enabled){return}this.container.addClass("select2-container-active");this.dropdown.addClass("select2-drop-active")}));C.data("select2-data",E);C.insertBefore(this.searchContainer);F.push(G);this.setVal(F)},unselect:function(D){var F=this.getVal(),E,C;D=D.closest(".select2-search-choice");if(D.length===0){throw"Invalid argument: "+D+". Must be .select2-search-choice"}E=D.data("select2-data");C=b(this.id(E),F);if(C>=0){F.splice(C,1);this.setVal(F);if(this.select){this.postprocessResults()}}D.remove();this.triggerChange({removed:E})},postprocessResults:function(){var E=this.getVal(),F=this.results.find(".select2-result-selectable"),D=this.results.find(".select2-result-with-children"),C=this;F.each2(function(H,G){var I=C.id(G.data("select2-data"));if(b(I,E)>=0){G.addClass("select2-disabled").removeClass("select2-result-selectable")}else{G.removeClass("select2-disabled").addClass("select2-result-selectable")}});D.each2(function(G,H){if(H.find(".select2-result-selectable").length==0){H.addClass("select2-disabled")}else{H.removeClass("select2-disabled")}});F.each2(function(H,G){if(!G.hasClass("select2-disabled")&&G.hasClass("select2-result-selectable")){C.highlight(0);return false}})},resizeSearch:function(){var H,F,E,C,D,G=n(this.search);H=x(this.search)+10;F=this.search.offset().left;E=this.selection.width();C=this.selection.offset().left;D=E-(F-C)-G;if(D. Attach to instead.")}this.search.width(0);this.searchContainer.hide()},onSortEnd:function(){var D=[],C=this;this.searchContainer.show();this.searchContainer.appendTo(this.searchContainer.parent());this.resizeSearch();this.selection.find(".select2-search-choice").each(function(){D.push(C.opts.id(j(this).data("select2-data")))});this.setVal(D);this.triggerChange()},data:function(D){var C=this,E;if(arguments.length===0){return this.selection.find(".select2-search-choice").map(function(){return j(this).data("select2-data")}).get()}else{if(!D){D=[]}E=j.map(D,function(F){return C.opts.id(F)});this.setVal(E);this.updateSelection(D);this.clearSearch()}}});j.fn.select2=function(){var F=Array.prototype.slice.call(arguments,0),G,E,H,D,C=["val","destroy","opened","open","close","focus","isFocused","container","onSortStart","onSortEnd","enable","disable","positionDropdown","data"];this.each(function(){if(F.length===0||typeof(F[0])==="object"){G=F.length===0?{}:j.extend({},F[0]);G.element=j(this);if(G.element.get(0).tagName.toLowerCase()==="select"){D=G.element.attr("multiple")}else{D=G.multiple||false;if("tags" in G){G.multiple=D=true}}E=D?new B():new v();E.init(G)}else{if(typeof(F[0])==="string"){if(b(F[0],C)<0){throw"Unknown method: "+F[0]}H=l;E=j(this).data("select2");if(E===l){return}if(F[0]==="container"){H=E.container}else{H=E[F[0]].apply(E,F.slice(1))}if(H!==l){return false}}else{throw"Invalid arguments to select2 plugin: "+F}}});return(H===l)?this:H};j.fn.select2.defaults={width:"copy",closeOnSelect:true,openOnEnter:true,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(C,D,F){var E=[];i(C.text,F.term,E);return E.join("")},formatSelection:function(D,C){return D?D.text:l},formatResultCssClass:function(C){return l},formatNoMatches:function(){return"No matches found"},formatInputTooShort:function(C,D){return"Please enter "+(D-C.length)+" more characters"},formatSelectionTooBig:function(C){return"You can only select "+C+" item"+(C==1?"":"s")},formatLoadMore:function(C){return"Loading more results..."},formatSearching:function(){return"Searching..."},minimumResultsForSearch:0,minimumInputLength:0,maximumSelectionSize:0,id:function(C){return C.id},matcher:function(C,D){return D.toUpperCase().indexOf(C.toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:y,escapeMarkup:function(C){if(C&&typeof(C)==="string"){return C.replace(/&/g,"&")}return C},blurOnChange:false};window.Select2={query:{ajax:p,local:r,tags:o},util:{debounce:f,markMatch:i},"class":{"abstract":e,single:v,multi:B}}}(jQuery)); \ No newline at end of file +(function(a){if(typeof a.fn.each2=="undefined"){a.fn.extend({each2:function(f){var d=a([0]),e=-1,b=this.length;while(++e=112&&H<=123}};D=j(document);u=(function(){var H=1;return function(){return H++}}());function b(J,K){var I=0,H=K.length;for(;I=0){I(K)}})}function r(H){if(H[0]===document.activeElement){return}window.setTimeout(function(){var J=H[0],K=H.val().length,I;H.focus();if(J.setSelectionRange){J.setSelectionRange(K,K)}else{if(J.createTextRange){I=J.createTextRange();I.collapse(true);I.moveEnd("character",K);I.moveStart("character",K);I.select()}}},0)}function d(H){H.preventDefault();H.stopPropagation()}function F(H){H.preventDefault();H.stopImmediatePropagation()}function z(I){if(!a){var H=I[0].currentStyle||window.getComputedStyle(I[0],null);a=j(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:H.fontSize,fontFamily:H.fontFamily,fontStyle:H.fontStyle,fontWeight:H.fontWeight,letterSpacing:H.letterSpacing,textTransform:H.textTransform,whiteSpace:"nowrap"});a.attr("class","select2-sizer");j("body").append(a)}a.text(I.val());return a.width()}function y(I,M,H){var K,L=[],J;K=I.attr("class");if(typeof K==="string"){j(K.split(" ")).each2(function(){if(this.indexOf("select2-")===0){L.push(this)}})}K=M.attr("class");if(typeof K==="string"){j(K.split(" ")).each2(function(){if(this.indexOf("select2-")!==0){J=H(this);if(typeof J==="string"&&J.length>0){L.push(this)}}})}I.attr("class",L.join(" "))}function i(M,L,J,H){var K=M.toUpperCase().indexOf(L.toUpperCase()),I=L.length;if(K<0){J.push(H(M));return}J.push(H(M.substring(0,K)));J.push("");J.push(H(M.substring(K,K+I)));J.push("");J.push(H(M.substring(K+I,M.length)))}function p(J){var M,I=0,K=null,N=J.quietMillis||100,L=J.url,H=this;return function(O){window.clearTimeout(M);M=window.setTimeout(function(){I+=1;var Q=I,S=J.data,P=L,U=J.transport||j.ajax,R=J.type||"GET",T={};S=S?S.call(H,O.term,O.page,O.context):null;P=(typeof P==="function")?P.call(H,O.term,O.page,O.context):P;if(null!==K){K.abort()}if(J.params){if(j.isFunction(J.params)){j.extend(T,J.params.call(H))}else{j.extend(T,J.params)}}j.extend(T,{url:P,dataType:J.dataType,data:S,type:R,cache:false,success:function(W){if(Q=0){break}}if(O<0){break}K=P.substring(0,O);P=P.substring(O+M.length);if(K.length>0){K=H.createSearchChoice(K,Q);if(K!==l&&K!==null&&H.id(K)!==l&&H.id(K)!==null){R=false;for(L=0,J=Q.length;L\|])/g,"\$1");this.container.attr("id",this.containerId);this.body=E(function(){return K.element.closest("body")});y(this.container,this.opts.element,this.opts.adaptContainerCssClass);this.container.css(t(K.containerCss));this.container.addClass(t(K.containerCssClass));this.elementTabIndex=this.opts.element.attr("tabIndex");this.opts.element.data("select2",this).addClass("select2-offscreen").bind("focus.select2",function(){j(this).select2("focus")}).attr("tabIndex","-1").before(this.container);this.container.data("select2",this);this.dropdown=this.container.find(".select2-drop");this.dropdown.addClass(t(K.dropdownCssClass));this.dropdown.data("select2",this);this.results=J=this.container.find(L);this.search=I=this.container.find("input.select2-input");I.attr("tabIndex",this.elementTabIndex);this.resultsPage=0;this.context=null;this.initContainer();v(this.results);this.dropdown.delegate(L,"mousemove-filtered touchstart touchmove touchend",this.bind(this.highlightUnderEvent));f(80,this.results);this.dropdown.delegate(L,"scroll-debounced",this.bind(this.loadMoreIfNeeded));if(j.fn.mousewheel){J.mousewheel(function(Q,R,O,N){var P=J.scrollTop(),M;if(N>0&&P-N<=0){J.scrollTop(0);d(Q)}else{if(N<0&&J.get(0).scrollHeight-J.scrollTop()+N<=J.height()){J.scrollTop(J.get(0).scrollHeight-J.height());d(Q)}}})}B(I);I.bind("keyup-change input paste",this.bind(this.updateResults));I.bind("focus",function(){I.addClass("select2-focused")});I.bind("blur",function(){I.removeClass("select2-focused")});this.dropdown.delegate(L,"mouseup",this.bind(function(M){if(j(M.target).closest(".select2-result-selectable").length>0){this.highlightUnderEvent(M);this.selectHighlighted(M)}}));this.dropdown.bind("click mouseup mousedown",function(M){M.stopPropagation()});if(j.isFunction(this.opts.initSelection)){this.initSelection();this.monitorSource()}if(K.element.is(":disabled")||K.element.is("[readonly='readonly']")){this.disable()}},destroy:function(){var H=this.opts.element.data("select2");if(this.propertyObserver){delete this.propertyObserver;this.propertyObserver=null}if(H!==l){H.container.remove();H.dropdown.remove();H.opts.element.removeClass("select2-offscreen").removeData("select2").unbind(".select2").attr({tabIndex:this.elementTabIndex}).show()}},prepareOpts:function(L){var J,I,H,K;J=L.element;if(J.get(0).tagName.toLowerCase()==="select"){this.select=I=L.element}if(I){j.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in L){throw new Error("Option '"+this+"' is not allowed for Select2 when attached to a ",""].join(""));return H},disable:function(){if(!this.enabled){return}this.parent.disable.apply(this,arguments);this.focusser.attr("disabled","disabled")},enable:function(){if(this.enabled){return}this.parent.enable.apply(this,arguments);this.focusser.removeAttr("disabled")},opening:function(){this.parent.opening.apply(this,arguments);this.focusser.attr("disabled","disabled");this.opts.element.trigger(j.Event("open"))},close:function(){if(!this.opened()){return}this.parent.close.apply(this,arguments);this.focusser.removeAttr("disabled");r(this.focusser)},focus:function(){if(this.opened()){this.close()}else{this.focusser.removeAttr("disabled");this.focusser.focus()}},isFocused:function(){return this.container.hasClass("select2-container-active")},cancel:function(){this.parent.cancel.apply(this,arguments);this.focusser.removeAttr("disabled");this.focusser.focus()},initContainer:function(){var J,I=this.container,K=this.dropdown,H=false;this.showSearch(this.opts.minimumResultsForSearch>=0);this.selection=J=I.find(".select2-choice");this.focusser=I.find(".select2-focusser");this.search.bind("keydown",this.bind(function(L){if(!this.enabled){return}if(L.which===c.PAGE_UP||L.which===c.PAGE_DOWN){d(L);return}switch(L.which){case c.UP:case c.DOWN:this.moveHighlight((L.which===c.UP)?-1:1);d(L);return;case c.TAB:case c.ENTER:this.selectHighlighted();d(L);return;case c.ESC:this.cancel(L);d(L);return}}));this.focusser.bind("keydown",this.bind(function(L){if(!this.enabled){return}if(L.which===c.TAB||c.isControl(L)||c.isFunctionKey(L)||L.which===c.ESC){return}if(this.opts.openOnEnter===false&&L.which===c.ENTER){d(L);return}if(L.which==c.DOWN||L.which==c.UP||(L.which==c.ENTER&&this.opts.openOnEnter)){this.open();d(L);return}if(L.which==c.DELETE||L.which==c.BACKSPACE){if(this.opts.allowClear){this.clear()}d(L);return}}));B(this.focusser);this.focusser.bind("keyup-change input",this.bind(function(L){if(this.opened()){return}this.open();if(this.showSearchInput!==false){this.search.val(this.focusser.val())}this.focusser.val("");d(L)}));J.delegate("abbr","mousedown",this.bind(function(L){if(!this.enabled){return}this.clear();F(L);this.close();this.selection.focus()}));J.bind("mousedown",this.bind(function(L){H=true;if(this.opened()){this.close()}else{if(this.enabled){this.open()}}d(L);H=false}));K.bind("mousedown",this.bind(function(){this.search.focus()}));J.bind("focus",this.bind(function(L){d(L)}));this.focusser.bind("focus",this.bind(function(){this.container.addClass("select2-container-active")})).bind("blur",this.bind(function(){if(!this.opened()){this.container.removeClass("select2-container-active")}}));this.search.bind("focus",this.bind(function(){this.container.addClass("select2-container-active")}));this.initContainerWidth();this.setPlaceholder()},clear:function(){var H=this.selection.data("select2-data");this.opts.element.val("");this.selection.find("span").empty();this.selection.removeData("select2-data");this.setPlaceholder();this.opts.element.trigger({type:"removed",val:this.id(H),choice:H});this.triggerChange({removed:H})},initSelection:function(){var I;if(this.opts.element.val()===""&&this.opts.element.text()===""){this.close();this.setPlaceholder()}else{var H=this;this.opts.initSelection.call(null,this.opts.element,function(J){if(J!==l&&J!==null){H.updateSelection(J);H.close();H.setPlaceholder()}})}},prepareOpts:function(){var H=this.parent.prepareOpts.apply(this,arguments);if(H.element.get(0).tagName.toLowerCase()==="select"){H.initSelection=function(I,K){var J=I.find(":selected");if(j.isFunction(K)){K({id:J.attr("value"),text:J.text(),element:J})}}}else{if("data" in H){H.initSelection=H.initSelection||function(I,K){var J=I.val();H.query({matcher:function(L,N,M){return q(J,H.id(M))},callback:!j.isFunction(K)?j.noop:function(L){K(L.results.length?L.results[0]:null)}})}}}return H},getPlaceholder:function(){if(this.select){if(this.select.find("option").first().text()!==""){return l}}return this.parent.getPlaceholder.apply(this,arguments)},setPlaceholder:function(){var H=this.getPlaceholder();if(this.opts.element.val()===""&&H!==l){if(this.select&&this.select.find("option:first").text()!==""){return}this.selection.find("span").html(this.opts.escapeMarkup(H));this.selection.addClass("select2-default");this.selection.find("abbr").hide()}},postprocessResults:function(L,I){var K=0,H=this,M=true;this.findHighlightableChoices().each2(function(N,O){if(q(H.id(O.data("select2-data")),H.opts.element.val())){K=N;return false}});this.highlight(K);if(I===true){var J=this.opts.minimumResultsForSearch;M=J<0?false:h(L.results)>=J;this.showSearch(M)}},showSearch:function(H){this.showSearchInput=H;this.dropdown.find(".select2-search")[H?"removeClass":"addClass"]("select2-search-hidden");j(this.dropdown,this.container)[H?"addClass":"removeClass"]("select2-with-searchbox")},onSelect:function(J,I){var H=this.opts.element.val();this.opts.element.val(this.id(J));this.updateSelection(J);this.opts.element.trigger({type:"selected",val:this.id(J),choice:J});this.close();if(!I||!I.noFocus){this.selection.focus()}if(!q(H,this.id(J))){this.triggerChange()}},updateSelection:function(J){var H=this.selection.find("span"),I;this.selection.data("select2-data",J);H.empty();I=this.opts.formatSelection(J,H);if(I!==l){H.append(this.opts.escapeMarkup(I))}this.selection.removeClass("select2-default");if(this.opts.allowClear&&this.getPlaceholder()!==l){this.selection.find("abbr").show()}},val:function(){var K,I=false,J=null,H=this;if(arguments.length===0){return this.opts.element.val()}K=arguments[0];if(arguments.length>1){I=arguments[1]}if(this.select){this.select.val(K).find(":selected").each2(function(L,M){J={id:M.attr("value"),text:M.text()};return false});this.updateSelection(J);this.setPlaceholder();if(I){this.triggerChange()}}else{if(this.opts.initSelection===l){throw new Error("cannot call val() if initSelection() is not defined")}if(!K&&K!==0){this.clear();if(I){this.triggerChange()}return}this.opts.element.val(K);this.opts.initSelection(this.opts.element,function(L){H.opts.element.val(!L?"":H.id(L));H.updateSelection(L);H.setPlaceholder();if(I){H.triggerChange()}})}},clearSearch:function(){this.search.val("");this.focusser.val("")},data:function(I){var H;if(arguments.length===0){H=this.selection.data("select2-data");if(H==l){H=null}return H}else{if(!I||I===""){this.clear()}else{this.opts.element.val(!I?"":this.id(I));this.updateSelection(I)}}}});G=x(e,{createContainer:function(){var H=j(document.createElement("div")).attr({"class":"select2-container select2-container-multi"}).html(["
      ","
    • "," ","
    • ","
    ",""].join(""));return H},prepareOpts:function(){var H=this.parent.prepareOpts.apply(this,arguments);if(H.element.get(0).tagName.toLowerCase()==="select"){H.initSelection=function(I,K){var J=[];I.find(":selected").each2(function(L,M){J.push({id:M.attr("value"),text:M.text(),element:M[0]})});K(J)}}else{if("data" in H){H.initSelection=H.initSelection||function(I,K){var J=m(I.val(),H.separator);H.query({matcher:function(L,N,M){return j.grep(J,function(O){return q(O,H.id(M))}).length},callback:!j.isFunction(K)?j.noop:function(L){K(L.results)}})}}}return H},initContainer:function(){var H=".select2-choices",I;this.searchContainer=this.container.find(".select2-search-field");this.selection=I=this.container.find(H);this.search.bind("input paste",this.bind(function(){if(!this.enabled){return}if(!this.opened()){this.open()}}));this.search.bind("keydown",this.bind(function(K){if(!this.enabled){return}if(K.which===c.BACKSPACE&&this.search.val()===""){this.close();var L,J=I.find(".select2-search-choice-focus");if(J.length>0){this.unselect(J.first());this.search.width(10);d(K);return}L=I.find(".select2-search-choice:not(.select2-locked)");if(L.length>0){L.last().addClass("select2-search-choice-focus")}}else{I.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")}if(this.opened()){switch(K.which){case c.UP:case c.DOWN:this.moveHighlight((K.which===c.UP)?-1:1);d(K);return;case c.ENTER:case c.TAB:this.selectHighlighted();d(K);return;case c.ESC:this.cancel(K);d(K);return}}if(K.which===c.TAB||c.isControl(K)||c.isFunctionKey(K)||K.which===c.BACKSPACE||K.which===c.ESC){return}if(K.which===c.ENTER){if(this.opts.openOnEnter===false){return}else{if(K.altKey||K.ctrlKey||K.shiftKey||K.metaKey){return}}}this.open();if(K.which===c.PAGE_UP||K.which===c.PAGE_DOWN){d(K)}}));this.search.bind("keyup",this.bind(this.resizeSearch));this.search.bind("blur",this.bind(function(J){this.container.removeClass("select2-container-active");this.search.removeClass("select2-focused");if(!this.opened()){this.clearSearch()}J.stopImmediatePropagation()}));this.container.delegate(H,"mousedown",this.bind(function(J){if(!this.enabled){return}if(j(J.target).closest(".select2-search-choice").length>0){return}this.clearPlaceholder();this.open();this.focusSearch();J.preventDefault()}));this.container.delegate(H,"focus",this.bind(function(){if(!this.enabled){return}this.container.addClass("select2-container-active");this.dropdown.addClass("select2-drop-active");this.clearPlaceholder()}));this.initContainerWidth();this.clearSearch()},enable:function(){if(this.enabled){return}this.parent.enable.apply(this,arguments);this.search.removeAttr("disabled")},disable:function(){if(!this.enabled){return}this.parent.disable.apply(this,arguments);this.search.attr("disabled",true)},initSelection:function(){var I;if(this.opts.element.val()===""&&this.opts.element.text()===""){this.updateSelection([]);this.close();this.clearSearch()}if(this.select||this.opts.element.val()!==""){var H=this;this.opts.initSelection.call(null,this.opts.element,function(J){if(J!==l&&J!==null){H.updateSelection(J);H.close();H.clearSearch()}})}},clearSearch:function(){var H=this.getPlaceholder();if(H!==l&&this.getVal().length===0&&this.search.hasClass("select2-focused")===false){this.search.val(H).addClass("select2-default");this.resizeSearch()}else{this.search.val("").width(10)}},clearPlaceholder:function(){if(this.search.hasClass("select2-default")){this.search.val("").removeClass("select2-default")}},opening:function(){this.parent.opening.apply(this,arguments);this.clearPlaceholder();this.resizeSearch();this.focusSearch();this.opts.element.trigger(j.Event("open"))},close:function(){if(!this.opened()){return}this.parent.close.apply(this,arguments)},focus:function(){this.close();this.search.focus();this.opts.element.triggerHandler("focus")},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(K){var J=[],I=[],H=this;j(K).each(function(){if(b(H.id(this),J)<0){J.push(H.id(this));I.push(this)}});K=I;this.selection.find(".select2-search-choice").remove();j(K).each(function(){H.addSelectedChoice(this)});H.postprocessResults()},tokenize:function(){var H=this.search.val();H=this.opts.tokenizer(H,this.data(),this.bind(this.onSelect),this.opts);if(H!=null&&H!=l){this.search.val(H);if(H.length>0){this.open()}}},onSelect:function(I,H){this.addSelectedChoice(I);this.opts.element.trigger({type:"selected",val:this.id(I),choice:I});if(this.select||!this.opts.closeOnSelect){this.postprocessResults()}if(this.opts.closeOnSelect){this.close();this.search.width(10)}else{if(this.countSelectableResults()>0){this.search.width(10);this.resizeSearch();if(this.val().length>=this.getMaximumSelectionSize()){this.updateResults(true)}this.positionDropdown()}else{this.close();this.search.width(10)}}this.triggerChange({added:I});if(!H||!H.noFocus){this.focusSearch()}},cancel:function(){this.close();this.focusSearch()},addSelectedChoice:function(K){var I=!K.locked,O=j("
  • "),N=j("
  • ");var H=I?O:N,M=this.id(K),L=this.getVal(),J;J=this.opts.formatSelection(K,H.find("div"));if(J!=l){H.find("div").replaceWith("
    "+this.opts.escapeMarkup(J)+"
    ")}if(I){H.find(".select2-search-choice-close").bind("mousedown",d).bind("click dblclick",this.bind(function(P){if(!this.enabled){return}j(P.target).closest(".select2-search-choice").fadeOut("fast",this.bind(function(){this.unselect(j(P.target));this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");this.close();this.focusSearch()})).dequeue();d(P)})).bind("focus",this.bind(function(){if(!this.enabled){return}this.container.addClass("select2-container-active");this.dropdown.addClass("select2-drop-active")}))}H.data("select2-data",K);H.insertBefore(this.searchContainer);L.push(M);this.setVal(L)},unselect:function(I){var K=this.getVal(),J,H;I=I.closest(".select2-search-choice");if(I.length===0){throw"Invalid argument: "+I+". Must be .select2-search-choice"}J=I.data("select2-data");if(!J){return}H=b(this.id(J),K);if(H>=0){K.splice(H,1);this.setVal(K);if(this.select){this.postprocessResults()}}I.remove();this.opts.element.trigger({type:"removed",val:this.id(J),choice:J});this.triggerChange({removed:J})},postprocessResults:function(){var J=this.getVal(),K=this.results.find(".select2-result"),I=this.results.find(".select2-result-with-children"),H=this;K.each2(function(M,L){var N=H.id(L.data("select2-data"));if(b(N,J)>=0){L.addClass("select2-selected");L.find(".select2-result-selectable").addClass("select2-selected")}});I.each2(function(M,L){if(!L.is(".select2-result-selectable")&&L.find(".select2-result-selectable:not(.select2-selected)").length===0){L.addClass("select2-selected")}});if(this.highlight()==-1){H.highlight(0)}},resizeSearch:function(){var M,K,J,H,I,L=n(this.search);M=z(this.search)+10;K=this.search.offset().left;J=this.selection.width();H=this.selection.offset().left;I=J-(K-H)-L;if(I1){I=arguments[1]}if(!K&&K!==0){this.opts.element.val("");this.updateSelection([]);this.clearSearch();if(I){this.triggerChange()}return}this.setVal(K);if(this.select){this.opts.initSelection(this.select,this.bind(this.updateSelection));if(I){this.triggerChange()}}else{if(this.opts.initSelection===l){throw new Error("val() cannot be called if initSelection() is not defined")}this.opts.initSelection(this.opts.element,function(M){var L=j(M).map(H.id);H.setVal(L);H.updateSelection(M);H.clearSearch();if(I){H.triggerChange()}})}this.clearSearch()},onSortStart:function(){if(this.select){throw new Error("Sorting of elements is not supported when attached to instead.")}this.search.width(0);this.searchContainer.hide()},onSortEnd:function(){var I=[],H=this;this.searchContainer.show();this.searchContainer.appendTo(this.searchContainer.parent());this.resizeSearch();this.selection.find(".select2-search-choice").each(function(){I.push(H.opts.id(j(this).data("select2-data")))});this.setVal(I);this.triggerChange()},data:function(I){var H=this,J;if(arguments.length===0){return this.selection.find(".select2-search-choice").map(function(){return j(this).data("select2-data")}).get()}else{if(!I){I=[]}J=j.map(I,function(K){return H.opts.id(K)});this.setVal(J);this.updateSelection(I);this.clearSearch()}}});j.fn.select2=function(){var K=Array.prototype.slice.call(arguments,0),L,J,M,I,H=["val","destroy","opened","open","close","focus","isFocused","container","onSortStart","onSortEnd","enable","disable","positionDropdown","data"];this.each(function(){if(K.length===0||typeof(K[0])==="object"){L=K.length===0?{}:j.extend({},K[0]);L.element=j(this);if(L.element.get(0).tagName.toLowerCase()==="select"){I=L.element.attr("multiple")}else{I=L.multiple||false;if("tags" in L){L.multiple=I=true}}J=I?new G():new w();J.init(L)}else{if(typeof(K[0])==="string"){if(b(K[0],H)<0){throw"Unknown method: "+K[0]}M=l;J=j(this).data("select2");if(J===l){return}if(K[0]==="container"){M=J.container}else{M=J[K[0]].apply(J,K.slice(1))}if(M!==l){return false}}else{throw"Invalid arguments to select2 plugin: "+K}}});return(M===l)?this:M};j.fn.select2.defaults={width:"copy",loadMorePadding:0,closeOnSelect:true,openOnEnter:true,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(I,J,L,H){var K=[];i(I.text,L.term,K,H);return K.join("")},formatSelection:function(I,H){return I?I.text:l},sortResults:function(I,H,J){return I},formatResultCssClass:function(H){return l},formatNoMatches:function(){return"No matches found"},formatInputTooShort:function(H,I){var J=I-H.length;return"Please enter "+J+" more character"+(J==1?"":"s")},formatInputTooLong:function(I,H){var J=I.length-H;return"Please enter "+J+" less character"+(J==1?"":"s")},formatSelectionTooBig:function(H){return"You can only select "+H+" item"+(H==1?"":"s")},formatLoadMore:function(H){return"Loading more results..."},formatSearching:function(){return"Searching..."},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(H){return H.id},matcher:function(H,I){return I.toUpperCase().indexOf(H.toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:A,escapeMarkup:function(H){var I={"\":"\","&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(H).replace(/[&<>"'/\]/g,function(J){return I[J[0]]})},blurOnChange:false,selectOnBlur:false,adaptContainerCssClass:function(H){return H},adaptDropdownCssClass:function(H){return null}};window.Select2={query:{ajax:p,local:s,tags:o},util:{debounce:g,markMatch:i},"class":{"abstract":e,single:w,multi:G}}}(jQuery)); \ No newline at end of file diff --git a/django_select2/util.py b/django_select2/util.py index bba7ddc..0d214b8 100644 --- a/django_select2/util.py +++ b/django_select2/util.py @@ -191,6 +191,9 @@ def convert_to_js_string_arr(lst): ### Auto view helper utils ### +from . import __ENABLE_MULTI_PROCESS_SUPPORT as ENABLE_MULTI_PROCESS_SUPPORT, \ + __MEMCACHE_HOST as MEMCACHE_HOST, __MEMCACHE_PORT as MEMCACHE_PORT, __MEMCACHE_TTL as MEMCACHE_TTL + def synchronized(f): "Decorator to synchronize multiple calls to a functions." f.__lock__ = threading.Lock() @@ -225,6 +228,9 @@ def is_valid_id(val): else: return True +if ENABLE_MULTI_PROCESS_SUPPORT: + from memcache_wrapped_db_client import Client + remote_server = Client(MEMCACHE_HOST, str(MEMCACHE_PORT), MEMCACHE_TTL) @synchronized def register_field(key, field): @@ -256,6 +262,10 @@ def register_field(key, field): if logger.isEnabledFor(logging.INFO): logger.info("Registering new field: %s; With actual id: %s", key, id_) + + if ENABLE_MULTI_PROCESS_SUPPORT: + logger.info("Multi process support is enabled. Adding id-key mapping to remote server.") + remote_server.set(id_, key) else: id_ = __field_store[key] if logger.isEnabledFor(logging.INFO): @@ -272,7 +282,22 @@ def get_field(id_): :rtype: :py:class:`AutoViewFieldMixin` or None """ - return __id_store.get(id_, None) + field = __id_store.get(id_, None) + if field is None and ENABLE_MULTI_PROCESS_SUPPORT: + if logger.isEnabledFor(logging.DEBUG): + logger.debug('Id "%s" not found in this process. Looking up in remote server.', id_) + key = remote_server.get(id_) + if key is not None: + id_in_current_instance = __field_store[key] + if id_in_current_instance: + field = __id_store.get(id_in_current_instance, None) + if field: + __id_store[id_] = field + else: + logger.error('Unknown id "%s".', id_in_current_instance) + else: + logger.error('Unknown id "%s".', id_) + return field def timer_start(name): import sys, time diff --git a/docs/get_started.rst b/docs/get_started.rst index 11a72b7..182a17d 100644 --- a/docs/get_started.rst +++ b/docs/get_started.rst @@ -21,26 +21,52 @@ Installation python manage.py collectstatic +4. (Optionally) If you need multiple processes support, then:: + + python manage.py syncdb + Available Setting ----------------- ``AUTO_RENDER_SELECT2_STATICS`` [Default ``True``] +.................................................. This, when specified and set to ``False`` in ``settings.py`` then Django_Select2 widgets won't automatically include the required scripts and stylesheets. When this setting is ``True`` then every Select2 field on the page will output ``