Render dependency checklist within submit form template

Previously I had added a custom widget to handle this, but it turns out
it's not flexible enough - we want to style items individually (not done
yet) and reorder checked items to the top on refresh (done).

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2013-02-26 17:21:40 +00:00
parent 1ca1674042
commit 8e49392398
4 changed files with 24 additions and 72 deletions

View File

@ -8,7 +8,6 @@ from layerindex.models import LayerItem, LayerMaintainer
from django import forms from django import forms
from django.core.validators import URLValidator, RegexValidator, email_re from django.core.validators import URLValidator, RegexValidator, email_re
from django.forms.models import inlineformset_factory from django.forms.models import inlineformset_factory
from widgets import TableCheckboxSelectMultiple
import re import re
@ -41,12 +40,16 @@ LayerMaintainerFormSet = inlineformset_factory(LayerItem, LayerMaintainer, form=
class SubmitLayerForm(forms.ModelForm): class SubmitLayerForm(forms.ModelForm):
# Additional form fields # Additional form fields
deps = forms.ModelMultipleChoiceField(label='Other layers this layer depends upon', queryset=LayerItem.objects.all(), required=False, widget=TableCheckboxSelectMultiple, initial=[l.pk for l in LayerItem.objects.filter(name='openembedded-core')]) deps = forms.ModelMultipleChoiceField(label='Other layers this layer depends upon', queryset=LayerItem.objects.all(), required=False, initial=[l.pk for l in LayerItem.objects.filter(name='openembedded-core')])
class Meta: class Meta:
model = LayerItem model = LayerItem
fields = ('name', 'layer_type', 'summary', 'description', 'vcs_url', 'vcs_subdir', 'vcs_web_url', 'vcs_web_tree_base_url', 'vcs_web_file_base_url', 'usage_url', 'mailing_list_url') fields = ('name', 'layer_type', 'summary', 'description', 'vcs_url', 'vcs_subdir', 'vcs_web_url', 'vcs_web_tree_base_url', 'vcs_web_file_base_url', 'usage_url', 'mailing_list_url')
def checked_deps(self):
val = [int(v) for v in self['deps'].value()]
return val
def clean_name(self): def clean_name(self):
name = self.cleaned_data['name'].strip() name = self.cleaned_data['name'].strip()
if re.compile(r'[^a-z0-9-]').search(name): if re.compile(r'[^a-z0-9-]').search(name):

View File

@ -35,7 +35,24 @@
{{ field.label_tag }} {{ field.label_tag }}
{% if field.name = 'deps' %} {% if field.name = 'deps' %}
<div class="scrolling"> <div class="scrolling">
{{ field }} <table><tbody>
{% for deplayer in deplistlayers %}
{% if deplayer.id in form.checked_deps %}
<tr>
<td><input type="checkbox" name="deps" value="{{ deplayer.id }}" id="id_deps_{{forloop.counter}}" checked="checked" /></td>
<td><label for="id_deps_{{forloop.counter}}">{{ deplayer.name }}</label></td>
</tr>
{% endif %}
{% endfor %}
{% for deplayer in deplistlayers %}
{% if not deplayer.id in form.checked_deps %}
<tr>
<td><input type="checkbox" name="deps" value="{{ deplayer.id }}" id="id_deps_{{forloop.counter}}" /></td>
<td><label for="id_deps_{{forloop.counter}}">{{ deplayer.name }}</label></td>
</tr>
{% endif %}
{% endfor %}
</tbody></table>
</div> </div>
{% else %} {% else %}
{{ field }} {{ field }}

View File

@ -62,6 +62,7 @@ def submit_layer(request):
return render(request, 'layerindex/submitlayer.html', { return render(request, 'layerindex/submitlayer.html', {
'form': form, 'form': form,
'maintainerformset': maintainerformset, 'maintainerformset': maintainerformset,
'deplistlayers': LayerItem.objects.all().order_by('name')
}) })
def submit_layer_thanks(request): def submit_layer_thanks(request):

View File

@ -1,69 +0,0 @@
# Based on parts of forms/widgets.py from Django
#
# Copyright (c) Django Software Foundation and individual contributors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of Django nor the names of its contributors may be used
# to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import django.forms
from django.forms.widgets import CheckboxInput
from django.utils.encoding import force_unicode
from django.utils.html import escape, conditional_escape
from django.utils.safestring import mark_safe
from itertools import chain
# Reworked CheckboxSelectMultiple
class TableCheckboxSelectMultiple(django.forms.SelectMultiple):
def render(self, name, value, attrs=None, choices=()):
if value is None: value = []
has_id = attrs and 'id' in attrs
final_attrs = self.build_attrs(attrs, name=name)
output = [u'<table>']
# Normalize to strings
str_values = set([force_unicode(v) for v in value])
for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
# If an ID attribute was given, add a numeric index as a suffix,
# so that the checkboxes don't all have the same ID attribute.
if has_id:
final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
label_for = u' for="%s"' % final_attrs['id']
else:
label_for = ''
cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
option_value = force_unicode(option_value)
rendered_cb = cb.render(name, option_value)
option_label = conditional_escape(force_unicode(option_label))
output.append(u'<tr><td>%s</td><td><label%s>%s</label></td></tr>' % (rendered_cb, label_for, option_label))
output.append(u'</table>')
return mark_safe(u'\n'.join(output))
def id_for_label(self, id_):
# See the comment for RadioSelect.id_for_label()
if id_:
id_ += '_0'
return id_