Skip to content

Instantly share code, notes, and snippets.

@BertrandBordage
Last active January 2, 2016 10:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save BertrandBordage/8288704 to your computer and use it in GitHub Desktop.
Save BertrandBordage/8288704 to your computer and use it in GitHub Desktop.
# WARNING: This is just a workaround. Consider it as a very
# temporary solution if you really need this feature.
from django.utils.safestring import mark_safe
from django_select2.util import convert_to_js_arr
TEMPORARY_ID = 0
def selector():
return """
$input = $('.select2-%s').nextAll('input:not([id*="__prefix__"])');
""" % TEMPORARY_ID
def render_js_script(inner_code):
code = """
%s
if ($input.length != 0) {
%s
}""" % (selector(), inner_code)
return u"""
<script type="text/javascript">
jQuery(function ($) {
%s else {
$('.add-row a').click(function () {
%s
})
}
});
</script>""" % (code, code)
class FixedSelect2WidgetMixin(object):
def render_js_code(self, id_, *args):
if id_:
return render_js_script(self.render_inner_js_code(id_, *args))
return u''
def render(self, name, value, attrs=None, choices=()):
global TEMPORARY_ID
s = """
<span class="select2-%s"></span>
<script>
jQuery(function ($) {
%s
});
</script>
""" % (TEMPORARY_ID, selector())
s += super(FixedSelect2WidgetMixin, self).render(
name, value, attrs=attrs, choices=choices)
id_ = attrs.get('id', None)
s = s.replace("$('#%s')" % id_, '$input')
s = s.replace('$("#%s")' % id_, '$input')
s = s.replace("'%s'" % id_, '$input[0].id')
TEMPORARY_ID += 1
return mark_safe(s)
# Now, redefine each widget class you need by adding the mixin
# as the first inherited class.
from django_select2 import AutoHeavySelect2Widget, AutoHeavySelect2MultipleWidget
class AutoHeavySelect2Widget(FixedSelect2WidgetMixin, AutoHeavySelect2Widget):
pass
class AutoHeavySelect2MultipleWidget(FixedSelect2WidgetMixin, AutoHeavySelect2MultipleWidget):
def render_inner_js_code(self, id_, name, value, *args):
js = ''
if value:
js += u"$('#%s').val(django_select2.convertArrToStr(%s));" \
% (id_, convert_to_js_arr(value, id_))
js += u"django_select2.initMultipleHidden($('#%s'));" % id_
js += super(AutocompleteMultiple, self).render_inner_js_code(
id_, name, value, *args)
return js
@nicboul
Copy link

nicboul commented Feb 6, 2014

Could you make a small tutorial on how to use your workaround please, I totally have no clue where to put that code :)

thank you!

@andergmartins
Copy link

Hi nickboul,

I have wrote a small change to make it work for my project, adding a fast delay before apply the event listeners, to make sure all links were rendered.
You can find it here: https://gist.github.com/andergmartins/9452777

You can use this gist or mine, adding it to a file name "select2_fixed_widgets.py", to a lib folder or insider your app folder. So on the forms you are creating, instead of import the "AutoHeavySelect2MultipleWidget" and "AutoHeavySelect2Widget" classes from "django_select2.util", import it from your utlis file (this gist content), like: mydjangoproject.libs.select2_fixed_widgets".

I hope this can help you.

Cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment