diff --git a/django_select2/conf.py b/django_select2/conf.py index 4d686005..8862932a 100644 --- a/django_select2/conf.py +++ b/django_select2/conf.py @@ -87,6 +87,14 @@ class Select2Conf(AppConf): SELECT2_CSS = 'assets/css/select2.css' + If you want to add more css (usually used in select2 themes), add a line + in settings.py like this:: + + SELECT2_CSS = [ + 'assets/css/select2.css', + 'assets/css/select2-theme.css', + ] + If you provide your own CSS and would not like Django-Select2 to load any, change this setting to a blank string like so:: @@ -96,6 +104,14 @@ class Select2Conf(AppConf): develop without an Internet connection. """ + THEME = "default" + """ + Select2 supports custom themes using the theme option so you can style Select2 + to match the rest of your application. + + .. tip:: When using other themes, you may need use select2 css and theme css. + """ + I18N_PATH = ( "https://cdnjs.cloudflare.com/ajax/libs/select2/{version}/js/i18n".format( version=LIB_VERSION diff --git a/django_select2/forms.py b/django_select2/forms.py index 86ca0390..b40b6207 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -90,6 +90,7 @@ def build_attrs(self, base_attrs, extra_attrs=None): default_attrs = { "lang": self.i18n_name, "data-minimum-input-length": 0, + "data-theme": settings.SELECT2_THEME, } if self.is_required: default_attrs["data-allow-clear"] = "false" @@ -120,18 +121,19 @@ def media(self): .. Note:: For more information visit https://docs.djangoproject.com/en/stable/topics/forms/media/#media-as-a-dynamic-property """ - select2_js = (settings.SELECT2_JS,) if settings.SELECT2_JS else () - select2_css = (settings.SELECT2_CSS,) if settings.SELECT2_CSS else () + select2_js = [settings.SELECT2_JS] if settings.SELECT2_JS else [] + select2_css = settings.SELECT2_CSS if settings.SELECT2_CSS else [] - i18n_file = () + if isinstance(select2_css, str): + select2_css = [select2_css] + + i18n_file = [] if self.i18n_name in settings.SELECT2_I18N_AVAILABLE_LANGUAGES: - i18n_file = ( - ("%s/%s.js" % (settings.SELECT2_I18N_PATH, self.i18n_name),) - ) + i18n_file = [f"{settings.SELECT2_I18N_PATH}/{self.i18n_name}.js"] return forms.Media( - js=select2_js + i18n_file + ("django_select2/django_select2.js",), - css={"screen": select2_css + ("django_select2/django_select2.css",)}, + js=select2_js + i18n_file + ["django_select2/django_select2.js"], + css={"screen": select2_css + ["django_select2/django_select2.css"]}, ) diff --git a/tests/test_forms.py b/tests/test_forms.py index af988845..5a89dfd1 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -169,6 +169,11 @@ def test_i18n(self): "django_select2/django_select2.js", ) + def test_theme_setting(self, settings): + settings.SELECT2_THEME = "classic" + widget = self.widget_cls() + assert 'data-theme="classic"' in widget.render("name", None) + class TestSelect2MixinSettings: def test_default_media(self): @@ -209,6 +214,13 @@ def test_empty_css_setting(self, settings): result = sut.media.render() assert "/select2.css" not in result + def test_multiple_css_setting(self, settings): + settings.SELECT2_CSS = ["select2.css", "select2-theme.css"] + sut = Select2Widget() + result = sut.media.render() + assert "select2.css" in result + assert "select2-theme.css" in result + class TestHeavySelect2Mixin(TestSelect2Mixin): url = reverse("heavy_select2_widget") @@ -321,6 +333,11 @@ class NoPickle: with pytest.raises(NotImplementedError): widget.set_to_cache() + def test_theme_setting(self, settings): + settings.SELECT2_THEME = "classic" + widget = self.widget_cls(data_view="heavy_data_1") + assert 'data-theme="classic"' in widget.render("name", None) + class TestModelSelect2Mixin(TestHeavySelect2Mixin): form = forms.AlbumModelSelect2WidgetForm(initial={"primary_genre": 1})