96 # Check if the Model property added help_text, and copy that verbatim |
96 # Check if the Model property added help_text, and copy that verbatim |
97 # to the corresponding field help_text. |
97 # to the corresponding field help_text. |
98 if hasattr(model_prop, 'help_text'): |
98 if hasattr(model_prop, 'help_text'): |
99 self.fields[field_name].help_text = model_prop.help_text |
99 self.fields[field_name].help_text = model_prop.help_text |
100 |
100 |
|
101 # Check if the Model property added example_text, and copy that verbatim |
|
102 # to the corresponding field help_text. |
|
103 if hasattr(model_prop, 'example_text'): |
|
104 self.fields[field_name].example_text = model_prop.example_text |
101 |
105 |
102 class BaseForm(DbModelForm): |
106 class BaseForm(DbModelForm): |
103 """Subclass of DbModelForm that extends as_table HTML output. |
107 """Subclass of DbModelForm that extends as_table HTML output. |
104 |
108 |
105 BaseForm has additional class names in HTML tags for label and help text |
109 BaseForm has additional class names in HTML tags for label and help text |
108 label and input. |
112 label and input. |
109 """ |
113 """ |
110 |
114 |
111 DEF_NORMAL_ROW = u'<tr title="%(help_text)s"><td class=' \ |
115 DEF_NORMAL_ROW = u'<tr title="%(help_text)s"><td class=' \ |
112 '"%(field_class_type)s">%(label)s</td><td>' \ |
116 '"%(field_class_type)s">%(label)s</td><td>' \ |
113 '%(errors)s%(field)s%(required)s</td></tr>' |
117 '%(errors)s%(field)s%(required)s%(example_text)s</td></tr>' |
114 DEF_ERROR_ROW = u'<tr><td> </td><td class="formfielderror">%s</td></tr>' |
118 DEF_ERROR_ROW = u'<tr><td> </td><td class="formfielderror">%s</td></tr>' |
115 DEF_ROW_ENDER = '</td></tr>' |
119 DEF_ROW_ENDER = '</td></tr>' |
116 DEF_REQUIRED_HTML = u'<td class="formfieldrequired">(required)</td>' |
120 DEF_REQUIRED_HTML = u'<td class="formfieldrequired">(required)</td>' |
117 DEF_HELP_TEXT_HTML = u'%s' |
121 DEF_HELP_TEXT_HTML = u'%s' |
|
122 DEF_EXAMPLE_TEXT_HTML = u'<td class="formfieldexample">e.g. %s</td>' |
|
123 |
118 |
124 |
119 def __init__(self, *args, **kwargs): |
125 def __init__(self, *args, **kwargs): |
120 """Parent class initialization. |
126 """Parent class initialization. |
121 |
127 |
122 Args: |
128 Args: |
123 *args, **kwargs: passed through to parent __init__() constructor |
129 *args, **kwargs: passed through to parent __init__() constructor |
124 """ |
130 """ |
125 super(BaseForm, self).__init__(error_class=CustomErrorList, *args, **kwargs) |
131 super(BaseForm, self).__init__(error_class=CustomErrorList, *args, **kwargs) |
126 |
132 |
127 def _html_output_with_required(self, normal_row, error_row, row_ender, |
133 def _html_output_with_required(self, normal_row, error_row, row_ender, |
128 help_text_html, required_html, errors_on_separate_row): |
134 help_text_html, required_html, example_text_html, errors_on_separate_row): |
129 """Helper function for outputting HTML. |
135 """Helper function for outputting HTML. |
130 |
136 |
131 Used by as_table(), as_ul(), as_p(). Displays information |
137 Used by as_table(), as_ul(), as_p(). Displays information |
132 about required fields. |
138 about required fields. |
133 """ |
139 """ |
134 # Errors that should be displayed above all fields. |
140 # Errors that should be displayed above all fields. |
135 top_errors = self.non_field_errors() |
141 top_errors = self.non_field_errors() |
168 field_class_type = u'formfieldlabel' |
174 field_class_type = u'formfieldlabel' |
169 |
175 |
170 if field.required: |
176 if field.required: |
171 required = required_html |
177 required = required_html |
172 else: |
178 else: |
173 required = u'' |
179 required = u'<td></td>' |
174 |
180 |
|
181 if hasattr(field, 'example_text'): |
|
182 example_text = example_text_html % force_unicode(field.example_text) |
|
183 else: |
|
184 example_text = u'<td></td>' |
|
185 |
175 if errors_on_separate_row and bf_errors: |
186 if errors_on_separate_row and bf_errors: |
176 errors = u'' |
187 errors = u'' |
177 else: |
188 else: |
178 errors = force_unicode(bf_errors) |
189 errors = force_unicode(bf_errors) |
179 |
190 |
180 output.append(normal_row % {'field_class_type': field_class_type, |
191 output.append(normal_row % {'field_class_type': field_class_type, |
181 'errors': errors, |
192 'errors': errors, |
182 'label': force_unicode(label), |
193 'label': force_unicode(label), |
183 'field': unicode(bf), |
194 'field': unicode(bf), |
184 'required': required, |
195 'required': required, |
185 'help_text': help_text}) |
196 'help_text': help_text, |
|
197 'example_text': example_text}) |
186 if top_errors: |
198 if top_errors: |
187 output.insert(0, error_row % force_unicode(top_errors)) |
199 output.insert(0, error_row % force_unicode(top_errors)) |
188 if hidden_fields: # Insert any hidden fields in the last row. |
200 if hidden_fields: # Insert any hidden fields in the last row. |
189 str_hidden = u''.join(hidden_fields) |
201 str_hidden = u''.join(hidden_fields) |
190 if output: |
202 if output: |
195 # This can happen in the as_p() case (and possibly others |
207 # This can happen in the as_p() case (and possibly others |
196 # that users write): if there are only top errors, we may |
208 # that users write): if there are only top errors, we may |
197 # not be able to conscript the last row for our purposes, |
209 # not be able to conscript the last row for our purposes, |
198 # so insert a new, empty row. |
210 # so insert a new, empty row. |
199 last_row = normal_row % {'errors': '', 'label': '', |
211 last_row = normal_row % {'errors': '', 'label': '', |
200 'field': '', 'help_text': ''} |
212 'field': '', 'help_text': '', 'example_text': ''} |
201 output.append(last_row) |
213 output.append(last_row) |
202 output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender |
214 output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender |
203 else: |
215 else: |
204 # If there aren't any rows in the output, just append the |
216 # If there aren't any rows in the output, just append the |
205 # hidden fields. |
217 # hidden fields. |
206 output.append(str_hidden) |
218 output.append(str_hidden) |
|
219 |
207 return mark_safe(u'\n'.join(output)) |
220 return mark_safe(u'\n'.join(output)) |
208 |
221 |
209 def as_table(self): |
222 def as_table(self): |
210 """Returns form rendered as HTML <tr> rows -- with no <table></table>.""" |
223 """Returns form rendered as HTML <tr> rows -- with no <table></table>.""" |
211 |
224 |
212 return self._html_output_with_required(self.DEF_NORMAL_ROW, |
225 return self._html_output_with_required(self.DEF_NORMAL_ROW, |
213 self.DEF_ERROR_ROW, |
226 self.DEF_ERROR_ROW, |
214 self.DEF_ROW_ENDER, |
227 self.DEF_ROW_ENDER, |
215 self.DEF_HELP_TEXT_HTML, |
228 self.DEF_HELP_TEXT_HTML, |
216 self.DEF_REQUIRED_HTML, True) |
229 self.DEF_REQUIRED_HTML, |
|
230 self.DEF_EXAMPLE_TEXT_HTML, True) |
217 |
231 |
218 |
232 |
219 class SelectQueryArgForm(forms.Form): |
233 class SelectQueryArgForm(forms.Form): |
220 """URL query argument change control implemented as a Django form. |
234 """URL query argument change control implemented as a Django form. |
221 """ |
235 """ |