Marcos Dumay de Medeiros vor 4 Jahren
Ursprung
Commit
b1adc789ea

+ 2 - 1
TODO

@@ -1,7 +1,8 @@
-Many2many does not appear in list
 Export data to csv
 Go to page number
 Filter for all basic types
 Form fields for reverse relations
+    Fix appearance of deleted forms
 Union and disjunction of permissions
 Multiple registering of actions
+Type annotations. Lots of them.

+ 2 - 2
src/rapid/forms.py

@@ -10,7 +10,7 @@ from django import forms
 
 from rapid.models import Profile, Application, DocumentTemplate
 from rapid.wrappers import FieldData
-from rapid.widgets import RapidReadOnly, RapidRelationReadOnly, RapidSelector
+from rapid.widgets import RapidReadOnly, RapidSelector, getRapidReadonlyRelation
 
 
 class ManageUsers(forms.ModelForm):
@@ -18,7 +18,7 @@ class ManageUsers(forms.ModelForm):
         model = Profile
         fields = '__all__'
         widgets = {
-            'application': RapidRelationReadOnly(Application),
+            'application': getRapidReadonlyRelation(Application, None),
             'name': RapidReadOnly(),
             'description': RapidReadOnly,
             'users': RapidSelector(FieldData.from_model(Profile, 'users'))

+ 11 - 6
src/rapid/rapidforms.py

@@ -16,15 +16,14 @@ from django.db import transaction
 from django.utils.encoding import force_text
 from datetimewidget import widgets as dtwidgets
 
-from rapid.widgets import RapidSelector, RapidRelationReadOnly, rapid_alternatives_widget, rapid_dependent_widget
+from rapid.widgets import RapidSelector, rapid_alternatives_widget, rapid_dependent_widget, \
+    getRapidReadonlyRelation
 from rapid.wrappers import FieldData, ModelData
 
 import gettext
 _ = gettext.gettext
 
 
-
-
 class RapidAlternativesField(forms.Field):
     """
     Form field for AlternativeData.
@@ -131,12 +130,15 @@ def for_model(request, model, default_relations=()):
         default_relations_fields = [x for x, y in default_relations]
     for (x, y) in default_relations:
         f = FieldData(getattr(model, x).field, request)
-        widgets.append((x, RapidRelationReadOnly(f.related_model().model)))
+        widgets.append((x, getRapidReadonlyRelation(f.related_model().model, y)))
         default_relations_fields.append(x)
     for f in ModelData(model).local_fields():
-        if f.is_relation() and force_text(f.bare_name()) not in default_relations_fields:
-            if f.related_model().has_permission(request, 'select'):
+        if f.is_relation():
+            if force_text(f.bare_name()) not in default_relations_fields and \
+            f.related_model().has_permission(request, 'select'):
                 widgets.append((f.bare_name(), RapidSelector(f)))
+            elif force_text(f.bare_name()) in default_relations_fields:
+                pass
         if type(f.field) == models.DateField:
             widgets.append((f.bare_name(), dtwidgets.DateWidget(usel10n = True, bootstrap_version=3)))
         if type(f.field) == models.DateTimeField:
@@ -144,6 +146,8 @@ def for_model(request, model, default_relations=()):
         if type(f.field) == models.TimeField:
             widgets.append((f.bare_name(), dtwidgets.TimeWidget(usel10n = True, bootstrap_version=3)))
 
+    #if force_text(model._meta.db_table) == 'testproject_singledepontest1':
+    #    import pdb; pdb.set_trace()
     # ModelForm.Meta has attributes with the same names, thus I'll rename them
     form_model = model
     form_widgets = dict(widgets)
@@ -192,6 +196,7 @@ def for_model(request, model, default_relations=()):
 
         @transaction.atomic
         def save(self, commit=True):
+
             if not commit:
                 return super(CForm, self).save(commit)
             else:

+ 21 - 4
src/rapid/templates/rapid/widgets/multipleDependent.html

@@ -8,16 +8,20 @@
         border-style: solid;
         padding: 1em;
     }
-    .deleted{
+    .deleted *:not(.toggle-remove){
         text-decoration: line-through;
     }
+    .included-dependent-checkbox{
+        display: none;
+    }
 </style>
 <div id="forms-for-{{ formset.prefix }}">
     {% for form in formset %}
         <div class="rapid-singledependent {{ formset.prefix }} form">
-            <input type="checkbox" class="includes_{{ formset.prefix }}"
-                   name="includes_{{ form.prefix }}" checked="true">
+            <input type="checkbox" class="includes_{{ formset.prefix }} included-dependent-checkbox"
+                   name="includes_{{ form.prefix }}" checked>
             {{ form.as_p }}
+            <input type="button" value="Remover" class="toggle-remove">
         </div>
     {% endfor %}
 </div>
@@ -29,8 +33,21 @@
     $("#add-form-in-{{ formset.prefix }}").click(function(){
         var formcount = $("#forms-for-{{ formset.prefix }}").children("div").length;
         $("#id_{{ formset.prefix }}-TOTAL_FORMS").val(formcount + 1);
-        var empty = "<div class=\"rapid-singledependent {{ formset.prefix }} form\">\n<input type=\"checkbox\" class=\"includes_{{ formset.prefix }}\" name=\"includes_{{ formset.prefix }}-__prefix__\" checked=\"true\">\n{{ formset.empty_form.as_p|jsstr }}\n<\div>";
+        var empty = "<div class=\"rapid-singledependent {{ formset.prefix }} form\">\n<input type=\"checkbox\" class=\"includes_{{ formset.prefix }} included-dependent-checkbox\" name=\"includes_{{ formset.prefix }}-__prefix__\" checked=\"true\">\n{{ formset.empty_form.as_p|jsstr }}\n<input type=\"button\" value=\"Apagar\" id=\"toggle-remove\">\n<\div>";
         $("#forms-for-{{ formset.prefix }}").append(empty.replace(/__prefix__/g, formcount));
     });
+    $("#forms-for-{{ formset.prefix }} .included-dependent-checkbox").change(function(){
+        $(this).parent().toggleClass("deleted");
+    });
+    $("#forms-for-{{ formset.prefix }} .toggle-remove").click(function(){
+        var box = $(this).parent().children(".included-dependent-checkbox")
+        var vis = box.prop("checked");
+        box.prop("checked", !vis);
+        box.parent().toggleClass("deleted");
+        if(vis)
+            $(this).prop("value", "Incluir");
+        else
+            $(this).prop("value", "Remover");
+    });
 </script>
 </div>

+ 24 - 2
src/rapid/templates/rapid/widgets/singleDependent.html

@@ -1,4 +1,4 @@
-<div>
+<div id="form-for-{{ name }}">
 <style scoped>
     .rapid-dependent{
         border-width: 1px;
@@ -9,14 +9,36 @@
     .hidden{
         display: none;
     }
+    .deleted{
+        text-decoration: line-through;
+    }
+    .included-dependent-checkbox{
+        display: none;
+    }
 </style>
-<input type="checkbox" id="includes_{{ name }}" name="includes_{{ name }}"{% if present %} checked{% endif %}>
+<input type="checkbox" class="included-dependent-checkbox" id="includes_{{ name }}"
+       name="includes_{{ name }}"{% if present %} checked{% endif %}>
 <div class="rapid-dependent {{ name }} form{% if not present %} hidden{% endif %}">
     {{ form.as_p }}
 </div>
+<input type="button" value="{% if present %}Remover{% else %}Incluir{% endif %}" class="toggle-remove">
 <script>
     $("#includes_{{ name }}").change(function(){
         $("div.{{ name }}.form").toggleClass("hidden");
     });
+    $("#form-for-{{ name }} .included-dependent-checkbox").change(function(){
+        $(this).parent().toggleClass("deleted");
+    });
+    $("#form-for-{{ name }} .toggle-remove").click(function(){
+        var box = $(this).parent().children(".included-dependent-checkbox");
+        var vis = box.prop("checked");
+        box.prop("checked", !vis);
+        if (vis) {
+            $(this).prop("value", "Incluir");
+        } else {
+            $(this).prop("value", "Remover");
+        }
+        $("div.{{ name }}.form").toggleClass("hidden");
+    });
 </script>
 </div>

+ 25 - 26
src/rapid/widgets.py

@@ -17,40 +17,40 @@ _templates_root = 'rapid/widgets/'
 
 class RapidReadOnly(widgets.Widget):
     def render(self, name, value, attrs=None):
-        hidden = '<input type="hidden" name="%s" value="%s" ' % (name, value)
+        hidden = '<input type="hidden" name="%s" value="%s" ' % (name, value if value else "")
         for a in attrs.keys():
             hidden += '%s="%s" ' % (a, attrs[a])
         hidden += '>'
         return '<span class="data-value">%s</span>%s\n' % (force_text(value), hidden)
 
     def value_from_datadict(self, data, files, name):
-        return data[name]
-
-
-class RapidRelationReadOnly(widgets.Widget):
-    def __init__(self, model, *args, **kwargs):
-        super(RapidRelationReadOnly, self).__init__(*args, **kwargs)
-        self.model = ModelData(model)
+        return data.get(name)
 
-    def render(self, name, value, attrs=None):
-        hidden = '<input type="hidden" name="%s" value="%s" ' % (name, value)
-        for a in attrs.keys():
-            hidden += '%s="%s" ' % (a, attrs[a])
-        hidden += '>'
-        if hasattr(value, '__iter__'):
-            obj = self.model.default_manager().filter(pk__in=value)
-            ret = ''
-            for o in obj:
-                ret += '<span class="data-value multiple">%s</span>\n' % force_text(o)
-            ret += hidden
-            return ret
-        else:
-            obj = self.model.default_manager().get(pk=value)
-            return '<span class="data-value">%s</span>%s\n' % (force_text(obj), hidden)
 
-    def value_from_datadict(self, data, files, name):
-        return data.get(name)
+def getRapidReadonlyRelation(model, originator):
+    class RapidRelationReadOnly(widgets.Widget):
+        def render(self, name, value, attrs=None):
+            hidden = '<input type="hidden" name="%s" value="%s" ' % (name, value if value else "")
+            for a in attrs.keys():
+                hidden += '%s="%s" ' % (a, attrs[a])
+            hidden += '>'
+            if hasattr(value, '__iter__'):
+                obj = model.default_manager().filter(pk__in=value)
+                ret = ''
+                for o in obj:
+                    ret += '<span class="data-value multiple">%s</span>\n' % force_text(o)
+                ret += hidden
+                return ret
+            else:
+                if value:
+                    obj = model.default_manager().get(pk=value)
+                else:
+                    obj = ""
+                return '<span class="data-value">%s</span>%s\n' % (force_text(obj), hidden)
 
+        def value_from_datadict(self, data, files, name):
+            return originator
+    return RapidRelationReadOnly
 
 class RapidSelector(widgets.Select):
     """
@@ -152,7 +152,6 @@ def rapid_dependent_widget(model_data, form, has_instance, is_mutiple):
                  'form': form,
                  'present': has_instance,
                  })
-            # import pdb; pdb.set_trace()
             t = loader.get_template(_templates_root + ('multipleDependent.html' if
                                     is_mutiple else 'singleDependent.html'))
             return t.render(c)