Browse Source

Admin settings list works with floppy forms. #114

Rafał Pitoń 12 years ago
parent
commit
1a60200d52

+ 6 - 6
misago/apps/admin/settings/views.py

@@ -4,7 +4,7 @@ from django.shortcuts import redirect
 from django.template import RequestContext
 from django.utils.translation import ungettext, ugettext as _
 from misago.conf import settings as misago_settings
-from misago.forms import Form
+from misago.forms import Form, FormIterator
 from misago.messages import Message
 from misago.search import SearchQuery, SearchException
 from misago.models import SettingsGroup, Setting
@@ -30,16 +30,16 @@ def settings(request, group_id=None, group_slug=None):
     # Load selected group settings and turn them into form
     group_settings = Setting.objects.filter(group=active_group).order_by('position')
     last_fieldset = (None, [])
-    group_form = {'layout': []}
+    group_form = {'fieldsets': []}
     for setting in group_settings:
         # New field subgroup?
         if setting.separator and last_fieldset[0] != setting.separator:
             if last_fieldset[0]:
-                group_form['layout'].append(last_fieldset)
+                group_form['fieldsets'].append(last_fieldset)
             last_fieldset = (_(setting.separator), [])
         last_fieldset[1].append(setting.pk)
         group_form[setting.pk] = setting.get_field()
-    group_form['layout'].append(last_fieldset)
+    group_form['fieldsets'].append(last_fieldset)
     SettingsGroupForm = type('SettingsGroupForm', (Form,), group_form)
 
     #Submit form
@@ -67,7 +67,7 @@ def settings(request, group_id=None, group_slug=None):
                               'groups': settings_groups,
                               'active_group': active_group,
                               'search_form': SearchForm(request=request),
-                              'form': form,
+                              'form': FormIterator(form),
                               'raw_form': form,
                               },
                               context_instance=RequestContext(request));
@@ -113,6 +113,6 @@ def settings_search(request):
                               'groups': settings_groups,
                               'active_group': None,
                               'found_settings': found_settings,
-                              'search_form': FormFields(form),
+                              'search_form': form,
                               },
                               context_instance=RequestContext(request));

+ 1 - 1
misago/forms/__init__.py

@@ -1,4 +1,4 @@
 from misago.forms.fields import ForumChoiceField, ReCaptchaField, QACaptchaField
 from misago.forms.forms import Form
-from misago.forms.layouts import FormLayout
+from misago.forms.iterators import FormIterator
 from misago.forms.widgets import ReCaptchaWidget, YesNoSwitch, ForumTOS

+ 47 - 0
misago/forms/iterators.py

@@ -0,0 +1,47 @@
+class FormIterator(object):
+    def __init__(self, form, fieldsets=None):
+        self._index = -1
+        self.form = form
+        try:
+            self.fieldsets = fieldsets or form.fieldsets
+        except AttributeError:
+            raise AttributeError('Form fieldset could not be found. Either pass explicit "fieldsets" argument to FormIterator or define "fieldsets" attribute on form.')
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        self._index += 1
+        try:
+            return FieldsetIterator(self.form,
+                                    self.fieldsets[self._index][0],
+                                    self.fieldsets[self._index][1])
+        except IndexError:
+            raise StopIteration()
+
+
+class FieldsetIterator(object):
+    def __init__(self, form, name, fields):
+        self._index = -1
+        self.form = form
+        self.name = name
+        self.fields = fields
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        self._index += 1
+        try:
+            row =  self.fields[self._index]
+            if isinstance(row, basestring):
+                field_name = row
+                return self.form[field_name]
+            field_name = row[0]
+            field = self.form[field_name]
+            field.extra =  row[1]
+            return field
+        except IndexError:
+            raise StopIteration()
+        except KeyError:
+            raise KeyError('Field "%s" could not be found in iterated form.' % field_name)

+ 0 - 11
misago/forms/layouts.py

@@ -1,11 +0,0 @@
-from UserDict import IterableUserDict
-from recaptcha.client.captcha import displayhtml
-from django.utils import formats
-from misago.conf import settings
-
-class FormLayout(object):
-    """
-    Simple scaffold for dynamically generated forms that allows for better rendering.
-    """
-    def __init__(self, layout, form):
-        raise NotImplementedError("Forms layouts are not yet implemented")

+ 16 - 7
misago/models/settingmodel.py

@@ -122,18 +122,27 @@ class Setting(models.Model):
                                    widget=forms.Textarea
                                    )
 
+        kwargs = {
+                  'initial': self.value,
+                  'label': _(self.name),
+                  'help_text': _(self.description) if self.description else None,
+                  'validators': field_validators,
+                  'required': False,
+                 }
+
         # Default input
         default_input = forms.CharField
         if self.normalize_to == 'integer':
             default_input = forms.IntegerField
+
         if self.normalize_to == 'float':
             default_input = forms.FloatField
 
+        if self.normalize_to in ('integer', 'float'):
+            if 'max' in extra:
+                kwargs['max_value'] = extra['max']
+            if 'min' in extra:
+                kwargs['min_value'] = extra['min']
+
         # Make text-input
-        return default_input(
-                             initial=self.value,
-                             label=_(self.name),
-                             help_text=_(self.description) if self.description else None,
-                             validators=field_validators,
-                             required=False,
-                             )
+        return default_input(**kwargs)

+ 12 - 3
templates/admin/settings/settings.html

@@ -28,11 +28,20 @@
   	{{ draw_message(message, 'alert-form') }}
   	{% endif %}
     {% if active_group.description %}
-  	<p>{{ _(active_group.description) }}</p>{% endif %}
+    <p>{{ _(active_group.description) }}</p>{% endif %}
     <form class="form-vertical" action="{{ url('admin_settings', group_id=active_group.id, group_slug=active_group.key) }}" method="post">
       <div class="form-container">
-        {% for field in form %}
-        {{ form_theme.row(field, attrs={'class': 'span9'}) }}
+        {% for fieldset in form %}
+        <fieldset>
+          {% if fieldset.name %}<legend>{{ fieldset.name }}</legend>{% endif %}
+          {% for field in fieldset %}
+          {% if field.field.widget.__class__.__name__ in ('CheckboxInput', 'YesNoSwitch') %}
+          {{ form_theme.row(field) }}
+          {% else %}
+          {{ form_theme.row(field, attrs={'class': 'span9'}) }}
+          {% endif %}
+          {% endfor %}
+        </fieldset>
         {% endfor %}
       </div>
       <div class="form-actions">

+ 29 - 6
templates/forms.html

@@ -95,10 +95,14 @@
 {% if 'inline' in context.attrs %}{% do context.attrs.pop('inline') %}{% endif %}
 {% if widget == 'Textarea' %}
 {{ _textarea(_field, context) }}
+{% elif widget == 'YesNoSwitch' %}
+{{ _yesno(_field, context) }}
 {% elif widget == 'Select' %}
 {{ _select(_field, context) }}
 {% elif widget == 'RadioSelect' %}
 {{ _radio_select(_field, context) }}
+{% elif widget == 'CheckboxSelectMultiple' %}
+{{ _checkbox_select(_field, context) }}
 {% elif widget == 'ReCaptchaWidget' %}
 {{ _field.field.widget.render()|safe }}
 {% else %}
@@ -118,6 +122,12 @@
 <textarea id="id_{{ context.name }}" name="{{ context.name }}" {{ attributes(context.attrs)|trim }}>{% if 'value' in context and context.value|length > 0 %}{{ context.value }}{% endif %}</textarea>
 {%- endmacro %}
 
+{% macro _yesno(_field, context) -%}
+<div id="id_{{ context.name }}_div" class="yes-no-switch{% if 'class' in context.attrs %} {{ context.attrs.class }}{% endif %}">
+  {{ _input(_field, context) }}
+</div>
+{%- endmacro %}
+
 {% macro _select(_field, context) -%}
 <select id="id_{{ context.name }}" name="{{ context.name }}" {{ attributes(context.attrs)|trim }}>
   {% if context['optgroups']|length > 1 %}
@@ -137,10 +147,23 @@
 {%- endmacro %}
 
 {% macro _radio_select(_field, context) -%}
-{% for option in context['optgroups'][0][1] %}
-<label class="radio">
-  <input type="radio" name="{{ context.name }}" id="id_{{ context.name }}_{{ option[0] }}" value="{{ option[0] }}"{% if 'value' in context and option[0] in context.value %} checked="checked"{% endif %}>
-  {{ option[1] }}
-</label>
-{% endfor %}
+<div class="radio-group">
+  {% for option in context['optgroups'][0][1] %}
+  <label class="radio">
+    <input type="radio" name="{{ context.name }}" id="id_{{ context.name }}_{{ option[0] }}" value="{{ option[0] }}"{% if 'value' in context and option[0] in context.value %} checked="checked"{% endif %}>
+    {{ option[1] }}
+  </label>
+  {% endfor %}
+</div>
 {%- endmacro %}
+
+{% macro _checkbox_select(_field, context) %}
+<div class="select-multiple">
+{% for option in context['optgroups'][0][1] %}
+  <label class="checkbox">
+    <input type="checkbox" name="{{ context.name }}" id="id_{{ context.name }}_{{ option[0] }}" value="{{ option[0] }}"{% if 'value' in context and option[0] in context.value %} checked="checked"{% endif %}>
+    {{ option[1] }}
+  </label>
+  {% endfor %}
+</div>
+{% endmacro %}