Skip to content

Instantly share code, notes, and snippets.

@esseti
Created March 30, 2018 15:27
Show Gist options
  • Save esseti/441f9a4da1b69f1b6c6061432bcc640e to your computer and use it in GitHub Desktop.
Save esseti/441f9a4da1b69f1b6c6061432bcc640e to your computer and use it in GitHub Desktop.
Beautiful widget for django multiple select
{% with id=widget.attrs.id %}
{% for group, options, index in widget.optgroups %}
{% for option in options %}
{% with widget=option %}
{% include widget.template_name%}
{% endwith %}
{% endfor %}
{% endfor %}
{% endwith %}
class MultipleChoiceForm(ModelForm):
class Meta:
model = MyModel
fields = ('myChoices',)
widgets = {
'myChoices': MyWidget,
}
def __init__(self, qs, *args, **kwargs):
# this is set in get_form_kwargs of the view
super().__init__(*args, **kwargs)
#this is needed to display only the data that matches the query
self.fields['myChoices'].queryset = qs
#this is needed for the rendering
self.fields['myChoices'].widget.qs = qs
{% load consenta_utils %}
{% with item=qs|index:widget.index %}
<div class="col-md-3 ">
<div class="panel purpose panel-default {% if widget.attrs.checked %}panel-primary{% endif %}"
style="cursor: pointer;">
<div class="panel-heading ">
<!-- this is the standard for the checkbox from django . i suggest to hide this in the class-->
<!-- the click on the div .panel checks the checbox (see js) -->
<input type="checkbox"
name="{{ widget.name }}"
{% if widget.value != None %}
value="{{ widget.value|stringformat:'s' }}"
{% endif %}
{% for name, value in widget.attrs.items %}{% if value is not False %}
{{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}
{% endif %}{% endfor %}/>
</div>
<div class="panel-body">
{{ item.description }}
</div>
</div>
</div>
{% endwith %}
$(document).ready(function () {
//this makes all the panels of the same size
function resize_panel(selector, what) {
if (what == undefined)
what = '.panel-body';
var objs = $(selector).find(what);
var o_h = 0;
objs.each(function () {
if (o_h < $(this).height()) {
o_h = $(this).height();
}
});
objs.each(function () {
$(this).height(o_h);
});
};
resize_panel('.panel', '.panel-heading');
resize_panel('.panel', '.panel-body');
resize_panel('.panel', '.panel-footer');
//this adds panel-primary (green stuff) to the panel when checkbox is selected
$('.purpose').click(function () {
var checkbox = $(this).find('input[type=checkbox]');
console.log($(this));
checkbox.prop("checked", !checkbox.prop("checked"));
if (checkbox.prop("checked")) {
$(this).addClass('panel-primary');
} else {
$(this).removeClass('panel-primary');
}
});
});
from django import template
register = template.Library()
@register.filter
def index(List, i):
return List[int(i)]
class ConsentCreationPP(CreateView):
template_name = "web_admin/consent_creation_new.html"
form_class = MultipleChoiceForm
def get_form_kwargs(self):
ctx = super().get_form_kwargs()
ctx.update({'qs':THE_QUERYSET})
return ctx
class MyWidget(forms.widgets.CheckboxSelectMultiple):
template_name = 'web_admin/partial/checkbox.html'
option_template_name = 'web_admin/partial/panel_item_p.html'
def get_context(self, name, value, attrs):
ctx = super().get_context(name, value, attrs)
# update the context adding the qs
ctx.update(dict(qs=self.qs))
return ctx
@ZKingDRFN
Copy link

Thanks for showing your work on this. I thought adding additional object detail to a form would be a lot more straight forward!

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