| 1 | #coding: utf-8 |
|---|
| 2 | |
|---|
| 3 | from django import forms |
|---|
| 4 | from django.shortcuts import render_to_response, get_object_or_404 |
|---|
| 5 | from django.http import HttpResponseRedirect |
|---|
| 6 | from django.forms.models import inlineformset_factory |
|---|
| 7 | from django.utils.translation import ugettext_lazy as _ |
|---|
| 8 | |
|---|
| 9 | # imports used by ReviewModelForm._html_output |
|---|
| 10 | from django.utils.encoding import force_unicode |
|---|
| 11 | from django.utils.safestring import mark_safe |
|---|
| 12 | from django.forms.forms import BoundField, conditional_escape |
|---|
| 13 | |
|---|
| 14 | from clinicaltrials.registry.models import ClinicalTrial, TrialNumber |
|---|
| 15 | |
|---|
| 16 | TRIAL_FORMS = ['TrialIdentificationForm', 'SponsorsForm', |
|---|
| 17 | 'HealthConditionsForm', 'InterventionsForm', |
|---|
| 18 | 'RecruitmentForm', 'StudyTypeForm','OutcomesForm', |
|---|
| 19 | 'DescriptorForm',] |
|---|
| 20 | |
|---|
| 21 | EXTRA_SECONDARY_IDS = 2 |
|---|
| 22 | |
|---|
| 23 | def edit_trial_index(request, trial_pk): |
|---|
| 24 | ''' start view ''' |
|---|
| 25 | links = [] |
|---|
| 26 | for i, name in enumerate(TRIAL_FORMS): |
|---|
| 27 | data = dict(label='form.title', form_name=name) |
|---|
| 28 | data['step'] = 'step_' + str(i + 1) |
|---|
| 29 | data['icon'] = '/media/img/admin/icon_alert.gif' |
|---|
| 30 | data['msg'] = 'Blank fields' |
|---|
| 31 | links.append(data) |
|---|
| 32 | return render_to_response('registry/trial_index.html', |
|---|
| 33 | {'trial_pk':trial_pk,'links':links}) |
|---|
| 34 | |
|---|
| 35 | class ReviewModelForm(forms.ModelForm): |
|---|
| 36 | def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row): |
|---|
| 37 | "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." |
|---|
| 38 | |
|---|
| 39 | top_errors = self.non_field_errors() # Errors that should be displayed above all fields. |
|---|
| 40 | output, hidden_fields = [], [] |
|---|
| 41 | for name, field in self.fields.items(): |
|---|
| 42 | bf = BoundField(self, field, name) |
|---|
| 43 | bf_errors = self.error_class([conditional_escape(error) for error in bf.errors]) # Escape and cache in local variable. |
|---|
| 44 | if bf.is_hidden: |
|---|
| 45 | if bf_errors: |
|---|
| 46 | top_errors.extend([u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors]) |
|---|
| 47 | hidden_fields.append(unicode(bf)) |
|---|
| 48 | else: |
|---|
| 49 | if errors_on_separate_row and bf_errors: |
|---|
| 50 | output.append(error_row % force_unicode(bf_errors)) |
|---|
| 51 | if bf.label: |
|---|
| 52 | label = conditional_escape(force_unicode(bf.label)) |
|---|
| 53 | # Only add the suffix if the label does not end in |
|---|
| 54 | # punctuation. |
|---|
| 55 | if self.label_suffix: |
|---|
| 56 | if label[-1] not in ':?.!': |
|---|
| 57 | label += self.label_suffix |
|---|
| 58 | label = bf.label_tag(label) or '' |
|---|
| 59 | else: |
|---|
| 60 | label = '' |
|---|
| 61 | if field.help_text: |
|---|
| 62 | help_text = help_text_html % force_unicode(field.help_text) |
|---|
| 63 | else: |
|---|
| 64 | help_text = u'' |
|---|
| 65 | field_path = '%s.%s.%s' % (self.__module__, self.__class__.__name__, name) |
|---|
| 66 | issue_text = '%s #%s' % (field_path, self.instance.pk) |
|---|
| 67 | output.append(normal_row % {'errors': force_unicode(bf_errors), |
|---|
| 68 | 'label': force_unicode(label), |
|---|
| 69 | 'field': unicode(bf), |
|---|
| 70 | 'help_text': help_text, |
|---|
| 71 | 'issue': issue_text,}) |
|---|
| 72 | if top_errors: |
|---|
| 73 | output.insert(0, error_row % force_unicode(top_errors)) |
|---|
| 74 | if hidden_fields: # Insert any hidden fields in the last row. |
|---|
| 75 | str_hidden = u''.join(hidden_fields) |
|---|
| 76 | if output: |
|---|
| 77 | last_row = output[-1] |
|---|
| 78 | # Chop off the trailing row_ender (e.g. '</td></tr>') and |
|---|
| 79 | # insert the hidden fields. |
|---|
| 80 | if not last_row.endswith(row_ender): |
|---|
| 81 | # This can happen in the as_p() case (and possibly others |
|---|
| 82 | # that users write): if there are only top errors, we may |
|---|
| 83 | # not be able to conscript the last row for our purposes, |
|---|
| 84 | # so insert a new, empty row. |
|---|
| 85 | last_row = normal_row % {'errors': '', |
|---|
| 86 | 'label': '', |
|---|
| 87 | 'field': '', |
|---|
| 88 | 'help_text': '', |
|---|
| 89 | 'issue': '',} |
|---|
| 90 | output.append(last_row) |
|---|
| 91 | output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender |
|---|
| 92 | else: |
|---|
| 93 | # If there aren't any rows in the output, just append the |
|---|
| 94 | # hidden fields. |
|---|
| 95 | output.append(str_hidden) |
|---|
| 96 | return mark_safe(u'\n'.join(output)) |
|---|
| 97 | |
|---|
| 98 | def as_table(self): |
|---|
| 99 | "Returns this form rendered as HTML <tr>s -- excluding the <table></table>." |
|---|
| 100 | normal_row = u''' |
|---|
| 101 | <tr><th>%(label)s</th> |
|---|
| 102 | <td>%(errors)s%(field)s</td> |
|---|
| 103 | <td>%(help_text)s |
|---|
| 104 | <div class="issue">%(issue)s</div> |
|---|
| 105 | </td></tr> |
|---|
| 106 | ''' |
|---|
| 107 | return self._html_output(normal_row=normal_row, |
|---|
| 108 | error_row=u'<tr><td colspan="3">%s</td></tr>', |
|---|
| 109 | row_ender='</td></tr>', |
|---|
| 110 | help_text_html=u'<br />%s', |
|---|
| 111 | errors_on_separate_row=False) |
|---|
| 112 | |
|---|
| 113 | |
|---|
| 114 | |
|---|
| 115 | class TrialIdentificationForm(ReviewModelForm): |
|---|
| 116 | class Meta: |
|---|
| 117 | model = ClinicalTrial |
|---|
| 118 | fields = ['scientific_title','scientific_acronym', |
|---|
| 119 | 'public_title','acronym'] |
|---|
| 120 | title = _('Trial Identification') |
|---|
| 121 | # TRDS 10a |
|---|
| 122 | scientific_title = forms.CharField(label=_('Scientific Title'), |
|---|
| 123 | max_length=2000, |
|---|
| 124 | widget=forms.Textarea, |
|---|
| 125 | help_text=_('The scientific title')) |
|---|
| 126 | # TRDS 10b |
|---|
| 127 | scientific_acronym = forms.CharField(required=False, |
|---|
| 128 | label=_('Scientific Acronym'), |
|---|
| 129 | max_length=255) |
|---|
| 130 | # TRDS 10c |
|---|
| 131 | scientific_acronym_expansion = forms.CharField(required=False, |
|---|
| 132 | label=_('Scientific Acronym Expansion'), |
|---|
| 133 | max_length=255) |
|---|
| 134 | # TRDS 9a |
|---|
| 135 | public_title = forms.CharField(required=False, |
|---|
| 136 | label=_('Public Title'), |
|---|
| 137 | max_length=2000, |
|---|
| 138 | widget=forms.Textarea) |
|---|
| 139 | # TRDS 9b |
|---|
| 140 | acronym = forms.CharField(required=False, label=_('Acronym'), |
|---|
| 141 | max_length=255) |
|---|
| 142 | |
|---|
| 143 | class SecondaryIdForm(ReviewModelForm): |
|---|
| 144 | ''' this is just to inherit the custom _html_output and as_table methods ''' |
|---|
| 145 | |
|---|
| 146 | def step_1(request, trial_pk): |
|---|
| 147 | ct = get_object_or_404(ClinicalTrial, id=int(trial_pk)) |
|---|
| 148 | |
|---|
| 149 | if request.POST: |
|---|
| 150 | form = TrialIdentificationForm(request.POST, instance=ct) |
|---|
| 151 | SecondaryIdSet = inlineformset_factory(ClinicalTrial, TrialNumber, |
|---|
| 152 | form=SecondaryIdForm, |
|---|
| 153 | extra=EXTRA_SECONDARY_IDS) |
|---|
| 154 | secondary_forms = SecondaryIdSet(request.POST, instance=ct) |
|---|
| 155 | |
|---|
| 156 | if form.is_valid() and secondary_forms.is_valid(): |
|---|
| 157 | form.save() |
|---|
| 158 | secondary_forms.save() |
|---|
| 159 | |
|---|
| 160 | if request.POST.has_key('submit_next'): |
|---|
| 161 | return HttpResponseRedirect("/rg/step_2/%s/" % trial_pk) |
|---|
| 162 | # FIXME: use dynamic url |
|---|
| 163 | return HttpResponseRedirect("/rg/edit/%s/" % trial_pk) |
|---|
| 164 | else: |
|---|
| 165 | form = TrialIdentificationForm(instance=ct) |
|---|
| 166 | SecondaryIdSet = inlineformset_factory(ClinicalTrial, TrialNumber, |
|---|
| 167 | form=SecondaryIdForm, |
|---|
| 168 | extra=EXTRA_SECONDARY_IDS, can_delete=True) |
|---|
| 169 | secondary_forms = SecondaryIdSet(instance=ct) |
|---|
| 170 | |
|---|
| 171 | forms = {'main':form, 'secondary':secondary_forms} |
|---|
| 172 | return render_to_response('registry/trial_form_step_1.html', |
|---|
| 173 | {'forms':forms, |
|---|
| 174 | 'next_form_title':_('Sponsors and Sources of Support')}) |
|---|