def field_(self, name): """ From https://github.com/halfnibble/django-underscore-filters Get a form field starting with _. Taken near directly from Django > forms. Returns a BoundField with the given name. """ try: field = self.fields[name] except KeyError as e: raise KeyError("Key %r not found in '%s'" % (name, self.__class__.__name__)) from e return BoundField(self, field, name)
def __init__(self, *args, **kwargs): super(FindingForm, self).__init__(*args, **kwargs) # Dynamically add the fields for IM providers / external services self.service_fields = [] for shortname, name, icon in SERVICES: field = forms.URLField(max_length=255, required=False, label=name) self.fields['service_' + shortname] = field self.service_fields.append({ 'label': name, 'shortname': shortname, 'id': 'service_' + shortname, 'icon': icon, 'field': BoundField(self, field, 'service_' + shortname), }) self.improvider_fields = [] for shortname, name, icon in IMPROVIDERS: field = forms.CharField(max_length=50, required=False, label=name) self.fields['im_' + shortname] = field self.improvider_fields.append({ 'label': name, 'shortname': shortname, 'id': 'im_' + shortname, 'icon': icon, 'field': BoundField(self, field, 'im_' + shortname), })
def fieldsets(self): for fieldset_name, fieldset_attrs in self.get_fieldsets(): fields = [] for field_name in fieldset_attrs.get('fields', None) or []: if field_name in self.fields: fields.append( BoundField(self, self.fields[field_name], field_name)) yield Fieldset( fieldset_name, fields=fields, legend=fieldset_attrs.get('legend', ''), classes=fieldset_attrs.get('classes', ''), )
def set_fieldsets(self, fieldsets): result = [] for name, lines in fieldsets: field_lines = [] for line in lines: if isinstance(line, str): line = (line,) field_line = [] for field_name in line: field = self.fields[field_name] bf = BoundField(self, field, field_name) field_line.append(bf) field_lines.append(field_line) result.append({'name': name, 'lines': field_lines},) self.fieldsets = result
def render_field(field, form, template="uni_form/field.html", labelclass=None): if not isinstance(field, str): return field.render(form) try: field_instance = form.fields[field] except KeyError: raise Exception("Could not resolve form field '%s'." % field) bound_field = BoundField(form, field_instance, field) html = render_to_string(template, {'field': bound_field, 'labelclass': labelclass}) if not hasattr(form, 'rendered_fields'): form.rendered_fields = [] if not field in form.rendered_fields: form.rendered_fields.append(field) else: raise Exception("A field should only be rendered once: %s" % field) return html
def as_input_field(self): bound_fields = [ BoundField(self, field, name) for name, field in self.fields.items() ] c = Context(dict(form=self, bound_fields=bound_fields)) t = Template(''' <li id="bar_{{ form.question.id }}"> <div class="section"> <span class="title" >{{ form.answer.label_tag }}</span><br /> <span class="sub-title">{{ form.question.hint }}</span> {{ form.errors }} {% if form.answer.required %}is required{% endif %} </div> </li> ''') return t.render(c)
def render(self, form, request, step, context=None): "Renders the given Form object, returning an HttpResponse." old_data = request.POST prev_fields = [] if old_data: for i in range(step): old_form = self.get_form(i, old_data) hash_name = 'hash_%s' % i if isinstance(old_form, BaseFormSet): for _form in old_form.forms + [old_form.management_form]: prev_fields.extend([bf for bf in _form]) else: prev_fields.extend([bf for bf in old_form]) hash_field = forms.Field(initial=old_data.get( hash_name, self.security_hash(request, old_form))) bf = BoundField(forms.Form(), hash_field, hash_name) prev_fields.append(bf) return self.render_template(request, form, prev_fields, step, context)
def inner(self): if not hasattr(self, cache_attr): from django.forms.forms import BoundField fieldsets = [] for item in sets: fieldset = {} fieldset['title'] = item['title'] fieldset['description'] = item['description'] if 'description' in item else '' fieldset['fields'] = [] fieldset['span'] = item.get('span', None) for fieldname in item['fields']: fieldset['fields'].append(BoundField(self, self.fields[fieldname], fieldname)) fieldsets.append(fieldset) self.cache_attr = fieldsets return self.cache_attr
def field_template(name, field, form_or_model, attrs={}, suffix=""): label = "" value = "" output = "" td_attrs = {} if isinstance(field, models.Field): label = u'%s' % field.verbose_name value = field_to_string(field, form_or_model) elif isinstance(field, forms.Field): bf = BoundField(form_or_model, field, name) label = u'%s' % bf.label_tag() value = u'%s' % bf if bf.help_text: value += '<br/>\n<span class="help_text">%s</span>' % ( u'%s' % bf.help_text) if bf._errors(): value += '<br/>\n<ul class="errorlist">\n' for error in bf._errors(): value += '\t<li>%s</li>\n' % error value += '</ul>\n' css_classes = bf.css_classes() if css_classes: td_attrs['class'] = css_classes else: name = _(pretty_name(name).lower()) label = u'%s' % name.capitalize() if callable(field): value = value_to_string(field()) else: value = value_to_string(field) td_attrs.update(attrs) if label and value: output += ("\t\t<th>%s</th>\n" % (label[0].capitalize() + label[1:])) output += "\t\t<td%s>\n" % flatatt(td_attrs) output += "\t\t\t%s%s\n" % (value, suffix) output += "\t\t</td>\n" return output
def test_crispy_addon(settings): test_form = SampleForm() field_instance = test_form.fields['email'] bound_field = BoundField(test_form, field_instance, 'email') if settings.CRISPY_TEMPLATE_PACK == 'bootstrap': # prepend tests assert "input-prepend" in crispy_addon(bound_field, prepend="Work") assert "input-append" not in crispy_addon(bound_field, prepend="Work") # append tests assert "input-prepend" not in crispy_addon(bound_field, append="Primary") assert "input-append" in crispy_addon(bound_field, append="Secondary") # prepend and append tests assert "input-append" in crispy_addon(bound_field, prepend="Work", append="Primary") assert "input-prepend" in crispy_addon(bound_field, prepend="Work", append="Secondary") elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap3': assert "input-group-addon" in crispy_addon(bound_field, prepend="Work", append="Primary") assert "input-group-addon" in crispy_addon(bound_field, prepend="Work", append="Secondary") elif settings.CRISPY_TEMPLATE_PACK == 'bootstrap4': assert "input-group-text" in crispy_addon(bound_field, prepend="Work", append="Primary") assert "input-group-text" in crispy_addon(bound_field, prepend="Work", append="Secondary") # errors with pytest.raises(TypeError): crispy_addon() with pytest.raises(TypeError): crispy_addon(bound_field)
def render(self, form): fieldoutput = u'' errors = u'' helptext = u'' count = 0 for field in self.fields: fieldoutput += render_field(field, form, 'uni_form/multifield.html', self.label_class) try: field_instance = form.fields[field] except KeyError: if not FAIL_SILENTLY: raise Exception("Could not resolve form field '%s'." % field) bound_field = BoundField(form, field_instance, field) auto_id = bound_field.auto_id for error in bound_field.errors: errors += u'<p id="error_%i_%s" class="errorField">%s</p>' % ( count, auto_id, error) count += 1 if bound_field.help_text: helptext += u'<p id="hint_%s" class="formHint">%s</p>' % ( auto_id, bound_field.help_text) if errors: self.css += u' error' output = u'<div class="%s">\n' % self.div_class output += errors output += self.label_html output += u'<div class="multiField">\n' output += fieldoutput output += u'</div>\n' output += helptext output += u'</div>\n' return output
def create_divs(self, fields): """Create a <div> for each field.""" output = "" for field in fields: try: # create a field instance for the bound field field_instance = self.fields[field] except KeyError: # could not create the instance so throw an exception # msg on a separate line since the line got too long # otherwise msg = "Could not resolve form field '%s'." % field raise FieldsetError(msg) # create a bound field containing all the necessary fields # from the form bound_field = BoundField(self, field_instance, field) output += '<div class="field %(class)s">%(label)s%(help_text)s%' \ '(errors)s%(field)s</div>\n' % \ {'class': bound_field.name, 'label': bound_field.label, 'help_text': bound_field.help_text, 'errors': bound_field.errors, 'field': unicode(bound_field)} return output
def as_template(self): "Helper function for rendering a form field as a template element. All inputs are disabled" self.fields['answer'].widget.attrs.update({ 'disabled': 'disabled', 'readonly': 'readonly' }) bound_fields = [ BoundField(self, field, name) for name, field in self.fields.items() ] ctxt_dict = dict(form=self, bound_fields=bound_fields) ctxt_dict.update(csrf(self.request)) c = Context(ctxt_dict) t = Template(''' <li class="sortable_item item" id="bar_{{ form.question.id }}"> <div class="item_header"> <span id="qn_attr" class="icon"> <a href="{% url update_field form_id=form.survey.id question_id=form.question.id %}" id="updlstItem{{ form.question.id }}" class="updField"> <img class="icon_button" src="/form_media/images/edit.png"/> </a> <form class="delete icon_button" method="POST" action="{% url delete_field form_id=form.survey.id %}" id="dellstItem{{ form.question.id }}" class="delField"> <input type="hidden" name="question_id" value="{{form.question.id}}" /> <input type="submit" name="delete" value="" style="border:none;background:url('/form_media/images/delete.gif') no-repeat scroll 3px 0 transparent"/> {% csrf_token %} </form> <img src="/form_media/images/arrow.png" alt="move" width="16" height="16" class="icon_button handle" /> </span> <span id="qLabel_{{ form_pair.q_id }}" class="qlabel">{{ form.answer.label_tag }}{% if form.question.required %}<span style="color:red;"> *</span>{% endif %}</span> </div> <div class="options">{{ form.answer }}</div> {% if form.question.hint %} <span class="helpText clear">Hint: {{ form.question.hint }}</span> {% endif %} </li> ''') return t.render(c)
def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row): "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." top_errors = self.non_field_errors( ) # Errors that should be displayed above all fields. output, hidden_fields = [], [] for section, fields in self.sections: if section: output.append( normal_row % { 'errors': '', 'label': ' ', 'field': self.section_template % section, 'help_text': '' }) for name, field in [ i for i in list(self.fields.items()) if i[0] in fields ]: bf = BoundField(self, field, name) bf_errors = self.error_class([ escape(error) for error in bf.errors ]) # Escape and cache in local variable. if bf.is_hidden: if bf_errors: top_errors.extend([ '(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors ]) hidden_fields.append(str(bf)) else: if errors_on_separate_row and bf_errors: output.append(error_row % force_unicode(bf_errors)) if bf.label: label = escape(force_unicode(bf.label)) # Only add the suffix if the label does not end in # punctuation. if self.label_suffix: if label[-1] not in ':?.!': label += self.label_suffix label = bf.label_tag(label) or '' else: label = '' if field.help_text: help_text = help_text_html % force_unicode( field.help_text) else: help_text = '' output.append( normal_row % { 'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': str(bf), 'help_text': help_text }) if top_errors: output.insert(0, error_row % force_unicode(top_errors)) if hidden_fields: # Insert any hidden fields in the last row. str_hidden = ''.join(hidden_fields) if output: last_row = output[-1] # Chop off the trailing row_ender (e.g. '</td></tr>') and # insert the hidden fields. output[ -1] = last_row[:-len(row_ender)] + str_hidden + row_ender else: # If there aren't any rows in the output, just append the # hidden fields. output.append(str_hidden) return mark_safe('\n'.join(output))
def _bound_value(self, field_name): field = self.fields[field_name] return BoundField(self, field, field_name).value()
def default(self, o, form=None, field_name=None): if issubclass(o.__class__, (forms.Form, forms.BaseForm)): flds = [] for name, field in o.fields.items(): if isinstance(field, dict): field['title'] = name else: field.name = name cfg = self.default(field, o, name) flds.append(cfg) return flds elif isinstance(o, dict): #Fieldset default_config = { 'autoHeight': True, 'collapsible': True, 'items': [], 'labelWidth': 200, 'title': o['title'], 'xtype': 'fieldset', } del o['title'] #Ensure fields are added sorted by position for name, field in sorted(o.items()): field.name = name default_config['items'].append(self.default(field)) return default_config elif issubclass(o.__class__, fields.Field): #bf = form and form.is_bound and BoundField(form, o, field_name) or None bf = BoundField(form, o, field_name) #print field_name , o.__class__ default_config = {} if o.__class__ in self.DJANGO_EXT_FIELD_TYPES: default_config.update( self.DJANGO_EXT_FIELD_TYPES[o.__class__][1]) else: default_config.update(self.EXT_DEFAULT_CONFIG['editor']) config = deepcopy(default_config) if bf: config['invalidText'] = "".join(form[field_name].errors) if form and form.is_bound: data = bf.data else: if field_name: data = form.initial.get(field_name, o.initial) if callable(data): data = data() else: data = None config['value'] = data for dj, ext in self.DJANGO_EXT_FIELD_ATTRS.items(): v = None if dj == 'size': v = o.widget.attrs.get(dj, None) if v is not None: if o.__class__ in (fields.DateField, fields.DateTimeField, fields.SplitDateTimeField, fields.TimeField): v += 8 #Django's size attribute is the number of characters, #so multiply by the pixel width of a character v = v * self.CHAR_PIXEL_WIDTH elif dj == 'hidden': v = o.widget.attrs.get( dj, default_config.get('fieldHidden', ext[1])) elif dj == 'name': v = bf and bf.html_name or field_name elif dj == 'label': v = bf and bf.label or getattr(o, dj, ext[1]) elif getattr(o, dj, ext[1]) is None: #print "dj:%s field name:%s"%(dj,field_name) pass #elif dj == 'input_formats': #alt_fmts = [] ##Strip out the '%' placeholders #for fmt in getattr(field, dj, ext[1]): #alt_fmts.append(fmt.replace('%', '')) #v = u'|'.join(alt_fmts) elif isinstance(ext[1], basestring): v = getattr(o, dj, getattr(field, ext[1])) elif ext[0] == 'store': v = { 'autoLoad': True, 'storeId': o.name, 'url': '/csds/ext/rdo/queryset/%s/' % (o.name.lower(), ), #'xtype': 'jsonstore', } elif dj == 'required': try: v = not getattr(o, dj) except AttributeError: v = ext[1] else: v = getattr(o, dj, ext[1]) if v is not None: if ext[0] == 'name': config[ext[0]] = v config['header'] = v elif ext[0] not in ('name', 'dataIndex', 'fieldLabel', 'header', 'defaultValue'): #elif ext[0] in ('allowBlank', 'listWidth', 'store', 'width'): #if isinstance(v, QuerySetIterator): # config['editor'][ext[0]] = list(v) config[ext[0]] = v if ext[0] == 'store': #config['url'] = v['url'] choices = [(c[0], c[1]) for c in o.choices] config['store'] = choices config['displayField'] = 'display' config['editable'] = False #config['editor']['forceSelection'] = True config['hiddenName'] = o.name #config['lastQuery'] = '' config['mode'] = 'local' config['triggerAction'] = 'all' #config['valueField'] = 'id' elif isinstance(v, unicode): config[ext[0]] = v.encode('utf8') else: config[ext[0]] = v return config else: return super(ExtJSONEncoder, self).default(o)
def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row, checkbox_row=''): """ Helper function for outputting HTML. Used by as_table(), as_ul(), as_p(). modified for Engineclub to wrap checkbox in label for Foundation markup with label to right. Hopefully a temporary hack until Django sorts out its form handling. """ top_errors = self.non_field_errors( ) # Errors that should be displayed above all fields. output, hidden_fields = [], [] for name, field in self.fields.items(): # MOD FOR ENGINECLUB checkbox = isinstance(field.widget, CheckboxInput) html_class_attr = '' bf = BoundField(self, field, name) bf_errors = self.error_class([ conditional_escape(error) for error in bf.errors ]) # Escape and cache in local variable. if bf.is_hidden: if bf_errors: top_errors.extend([ u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors ]) hidden_fields.append(unicode(bf)) else: # Create a 'class="..."' atribute if the row should have any # CSS classes applied. css_classes = bf.css_classes() if css_classes: html_class_attr = ' class="%s"' % css_classes if errors_on_separate_row and bf_errors: output.append(error_row % force_unicode(bf_errors)) if bf.label: label = conditional_escape(force_unicode(bf.label)) # Only add the suffix if the label does not end in # punctuation. if self.label_suffix: if label[-1] not in ':?.!': label += self.label_suffix # MOD FOR ENGINECLUB if not checkbox: label = bf.label_tag(label) or '' else: label = '' if field.help_text: help_text = help_text_html % force_unicode(field.help_text) else: help_text = u'' # MOD FOR ENGINECLUB output_row = checkbox_row if checkbox else normal_row output.append( output_row % { 'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text': help_text, 'html_class_attr': html_class_attr }) if top_errors: output.insert(0, error_row % force_unicode(top_errors)) if hidden_fields: # Insert any hidden fields in the last row. str_hidden = u''.join(hidden_fields) if output: last_row = output[-1] # Chop off the trailing row_ender (e.g. '</td></tr>') and # insert the hidden fields. if not last_row.endswith(row_ender): # This can happen in the as_p() case (and possibly others # that users write): if there are only top errors, we may # not be able to conscript the last row for our purposes, # so insert a new, empty row. last_row = (normal_row % { 'errors': '', 'label': '', 'field': '', 'help_text': '', 'html_class_attr': html_class_attr }) output.append(last_row) output[ -1] = last_row[:-len(row_ender)] + str_hidden + row_ender else: # If there aren't any rows in the output, just append the # hidden fields. output.append(str_hidden) return mark_safe(u'\n'.join(output))
def _html_output_as_dl(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row): "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." top_errors = self.non_field_errors( ) # Errors that should be displayed above all fields. mark_as_required_field = _('mark as required field') output, hidden_fields = [], [] for name, field in self.fields.items(): html_class_attr = '' bf = BoundField(self, field, name) bf_errors = self.error_class([ conditional_escape(error) for error in bf.errors ]) # Escape and cache in local variable. if bf.is_hidden: if bf_errors: top_errors.extend([ u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors ]) hidden_fields.append(unicode(bf)) else: # Create a 'class="..."' atribute if the row should have any # CSS classes applied. widget_type = type(field.widget) widget_base_type = widget_type.__bases__[0] extra_classes = None if widget_base_type == widgets.Input: if widget_type == widgets.FileInput: extra_classes = 'input_file' else: extra_classes = 'input_text' elif widget_base_type == widgets.Widget: if widget_type == widgets.Select: extra_classes = 'select' elif widget_type == widgets.Textarea: extra_classes = 'textarea' elif widget_type == widgets.CheckboxInput: extra_classes = 'input_checkbox' elif widget_base_type == widgets.Select: if widget_type == widgets.RadioSelect: extra_classes = 'input_radio' css_classes = bf.css_classes(extra_classes) if css_classes: html_class_attr = ' class="%s"' % css_classes if errors_on_separate_row and bf_errors: output.append(error_row % force_unicode(bf_errors)) if bf.label: label = conditional_escape(force_unicode(bf.label)) if bf.field.required and (widget_base_type == widgets.Input\ or widget_type == widgets.Textarea): label += mark_as_required_field # Only add the suffix if the label does not end in # punctuation. if self.label_suffix: if label[-1] not in ':?.!': label += self.label_suffix label = bf.label_tag(label) or '' else: label = '' if field.help_text: help_text = help_text_html % force_unicode(field.help_text) else: help_text = u'' output.append( normal_row % { 'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text': help_text, 'html_class_attr': html_class_attr }) if top_errors: output.insert(0, error_row % force_unicode(top_errors)) if hidden_fields: # Insert any hidden fields in the last row. str_hidden = u''.join(hidden_fields) if output: last_row = output[-1] # Chop off the trailing row_ender (e.g. '</td></tr>') and # insert the hidden fields. if not last_row.endswith(row_ender): # This can happen in the as_p() case (and possibly others # that users write): if there are only top errors, we may # not be able to conscript the last row for our purposes, # so insert a new, empty row. last_row = (normal_row % { 'errors': '', 'label': '', 'field': '', 'help_text': '', 'html_class_attr': html_class_attr }) output.append(last_row) output[ -1] = last_row[:-len(row_ender)] + str_hidden + row_ender else: # If there aren't any rows in the output, just append the # hidden fields. output.append(str_hidden) return mark_safe(u'\n'.join(output))
def __iter__(self): for name, field in self.fields.items(): bound_field = BoundField(self, field, name) bound_field.points = field.points yield bound_field
def _generate_bound_fields(self): self.bound_fields = SortedDict([(name, BoundField(self, field, name)) for name, field in self.fields.items() ])
def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row): "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." top_errors = self.non_field_errors() # Errors that should be displayed above all fields. output, hidden_fields = [], [] for name, field in self.fields.items(): bf = BoundField(self, field, name) bf_errors = self.error_class([conditional_escape(error) for error in bf.errors]) # Escape and cache in local variable. if bf.is_hidden: if bf_errors: top_errors.extend([u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors]) hidden_fields.append(unicode(bf)) else: if errors_on_separate_row and bf_errors: output.append(error_row % force_unicode(bf_errors)) if bf.label: label = conditional_escape(force_unicode(bf.label)) # Only add the suffix if the label does not end in # punctuation. if self.label_suffix: if label[-1] not in ':?.!': label += self.label_suffix # Sets label with an asterisk if this is a obligatory field according to to validation rules if hasattr(self.Meta,'min_required'): if not hasattr(self.Meta,'count'): self.Meta.count = 0 if self.Meta.min_required > 0 and self.Meta.count < self.Meta.min_required: if name != 'DELETE': label = label + ' <span class="required_field">(*)</span>' elif trial_validator.field_is_required(self, name): label = label + ' <span class="required_field">(*)</span>' label = bf.label_tag(label) or '' else: label = '' # Gets the field status for this field to use it as CSS class if self.instance: field_status = trial_validator.get_field_status(self, name, self.instance) else: field_status = '' if field.help_text: help_text = help_text_html % force_unicode(field.help_text) else: help_text = u'' form_name = self.__class__.__name__ help_record, new = FieldHelp.objects.get_or_create(form=form_name, field=name) # Trying to get the translation for help_record try: help_object = FieldHelpTranslation.objects.get_translation_for_object( lang=get_language(), model=FieldHelp, object_id=help_record.pk, ) help_text = "<div class='help_text'>%s</div>" % (help_object.text,) if help_object.example: help_text = "%s<div class='help_text_example'>%s:<br />%s</div>" % (help_text, _("Example"), help_object.example) if not help_text.strip(): help_text = unicode(help_record) except (FieldHelpTranslation.DoesNotExist, AttributeError): help_text = "<div class='help_text'>%s</div>" % (help_record.text,) if help_record.example: help_text = "%s<div class='help_text_example'>%s:<br />%s</div>" % (help_text, _("Example"), help_record.example) help_text = u'' + force_unicode(help_text) help_text = linebreaksbr(help_text_html % help_text) output.append(normal_row % {'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text': help_text, 'help_id': 'id_%s-help%s' % ((self.prefix or name),help_record.pk), 'field_class': field_status, 'field_name': name, }) # if necessary, updates the count of rendered repetitive forms if hasattr(self.Meta,'min_required'): if hasattr(self.Meta,'count'): self.Meta.count = self.Meta.count + 1 if top_errors: output.insert(0, error_row % force_unicode(top_errors)) if hidden_fields: # Insert any hidden fields in the last row. str_hidden = u''.join(hidden_fields) if output: last_row = output[-1] # Chop off the trailing row_ender (e.g. '</td></tr>') and # insert the hidden fields. if not last_row.endswith(row_ender): # This can happen in the as_p() case (and possibly others # that users write): if there are only top errors, we may # not be able to conscript the last row for our purposes, # so insert a new, empty row. last_row = normal_row % {'errors': '', 'label': '', 'field': '', 'help_text': '', 'help_id': 'id_%s-help%s' % (self.prefix,help_record.pk), 'issue': '',} output.append(last_row) output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender else: # If there aren't any rows in the output, just append the # hidden fields. output.append(str_hidden) return mark_safe(u'\n'.join(output))
def _boundfield(self, field, name): if isinstance(field, FormsetField): return BoundFormsetField(self, field, name) return BoundField(self, field, name)
def __iter__(self): for name in self.fields: field = self.form.fields[name] yield BoundField(self.form, field, name)
def render(self, context): form = context[self.arg] #TODO: cache #if adv_mode is None: adv_mode = Advanced.objects.order_by('-id')[0].adv_advancedmode #request.session['adv_mode'] = adv_mode form.advDefault = adv_mode if hasattr(form, "_meta") and hasattr(form._meta.model, '_admin'): model = form._meta.model else: model = None new_fields = form.fields.keys() output, hidden_fields, composed = [], [], {} top_errors = form.non_field_errors() if top_errors: output.append("<tr><td colspan=\"2\">%s</td></tr>" % ( force_unicode(top_errors), )) else: if form.prefix: prefix = form.prefix + "-__all__" else: prefix = "__all__" output.append("""<tr> <td colspan="2"> <input type="hidden" data-dojo-type="dijit.form.TextBox" name="%s" /> </td></tr>""" % (prefix,)) if model: for label, fields in model._admin.composed_fields: for field in fields[1:]: new_fields.remove(field) composed[fields[0]] = (label, fields) advanced_fields = getattr(form, 'advanced_fields', []) for field in new_fields: is_adv = field in advanced_fields _hide = ' style="display:none;"' if not adv_mode and is_adv else '' is_adv = ' class="advancedField"' if is_adv else '' if field in composed: label, fields = composed.get(field) html = u"""<tr><th><label%s>%s</label></th><td>""" % ( _hide, label) for field in fields: bf = BoundField(form, form.fields.get(field), field) bf_errors = form.error_class( [conditional_escape(error) for error in bf.errors] ) html += unicode(bf_errors) + unicode(bf) html += u"</td></tr>" output.append(html) else: bf = BoundField(form, form.fields.get(field), field) bf_errors = form.error_class( [conditional_escape(error) for error in bf.errors] ) if bf.is_hidden: hidden_fields.append(unicode(bf)) else: if bf.help_text: help_text = """<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId: '%shelp', showDelay: 200">%s</div><img id="%shelp" src="/static/images/ui/MoreInformation_16x16px.png" style="width:16px; height: 16px; cursor: help;" />""" % (bf.auto_id, bf.help_text, bf.auto_id) else: help_text = "" html = u"""<tr%s%s><th>%s</th><td>%s%s %s</td></tr>""" % ( is_adv, _hide, bf.label_tag(), bf_errors, bf, help_text, ) output.append(html) if hidden_fields: str_hidden = u''.join(hidden_fields) output.append(str_hidden) return ''.join(output)
def _get_fields(self, prefix_id): filtered_vals = filter(lambda x: x[0].startswith(prefix_id), self.fields.items()) for field in filtered_vals: yield BoundField(self, field[1], field[0])
def render_field(field, form, form_style, context, template=None, labelclass=None, layout_object=None): """ Renders a django-uni-form field :param field: Can be a string or a Layout object like `Row`. If it's a layout object, we call its render method, otherwise we instantiate a BoundField and render it using default template 'uni_form/field.html' The field is added to a list that the form holds called `rendered_fields` to avoid double rendering fields. :param form: The form/formset to which that field belongs to. :param form_style: We need this to render uni-form divs using helper's chosen style. :template: Template used for rendering the field. :layout_object: If passed, it points to the Layout object that is being rendered. We use it to store its bound fields in a list called `layout_object.bound_fields` """ FAIL_SILENTLY = getattr(settings, 'UNIFORM_FAIL_SILENTLY', True) if hasattr(field, 'render'): return field.render(form, form_style, context) else: # This allows fields to be unicode strings, always they don't use non ASCII try: if isinstance(field, unicode): field = str(field) # If `field` is not unicode then we turn it into a unicode string, otherwise doing # str(field) would give no error and the field would not be resolved, causing confusion else: field = str(unicode(field)) except (UnicodeEncodeError, UnicodeDecodeError): raise Exception( "Field '%s' is using forbidden unicode characters" % field) try: field_instance = form.fields[field] except KeyError: if not FAIL_SILENTLY: raise Exception("Could not resolve form field '%s'." % field) else: field_instance = None logging.warning("Could not resolve form field '%s'." % field, exc_info=sys.exc_info()) if not field in form.rendered_fields: form.rendered_fields.append(field) else: if not FAIL_SILENTLY: raise Exception("A field should only be rendered once: %s" % field) else: logging.warning("A field should only be rendered once: %s" % field, exc_info=sys.exc_info()) if field_instance is None: html = '' else: bound_field = BoundField(form, field_instance, field) if template is None: template = default_field_template else: template = get_template(template) # We save the Layout object's bound fields in the layout object's `bound_fields` list if layout_object is not None: layout_object.bound_fields.append(bound_field) html = template.render( Context({ 'field': bound_field, 'labelclass': labelclass })) return html
def outputhelper(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row, separator_html=SEPARATOR_HTML): "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." top_errors = self.non_field_errors( ) # Errors that should be displayed above all fields. output, hidden_fields = [], [] for name, field in self.fields.items(): html_class_attr = '' bf = BoundField(self, field, name) bf_errors = self.error_class([ conditional_escape(error) for error in bf.errors ]) # Escape and cache in local variable. # Check that we can get a unicode output of the field (in particular # if someone tries to pass bad data to the form try: unicode(bf) except TypeError: raise Http404 if bf.is_hidden: if bf_errors: top_errors.extend([ u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors ]) hidden_fields.append(unicode(bf)) elif bf.field.is_separator(): output.append(separator_html % { 'label': conditional_escape(force_unicode(bf.label)), }) else: # Create a 'class="..."' atribute if the row should have any # CSS classes applied. css_classes = bf.css_classes() if css_classes: html_class_attr = ' class="%s"' % css_classes if errors_on_separate_row and bf_errors: output.append(error_row % force_unicode(bf_errors)) if bf.label: label = conditional_escape(force_unicode(bf.label)) # Only add the suffix if the label does not end in # punctuation. if self.label_suffix: if label[-1] not in ':?.!': label += self.label_suffix label = bf.label_tag(label) or '' else: label = '' if field.help_text: help_text = help_text_html % force_unicode(field.help_text) else: help_text = u'' output.append( normal_row % { 'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text': help_text, 'html_class_attr': html_class_attr }) if top_errors: output.insert(0, error_row % force_unicode(top_errors)) if hidden_fields: # Insert any hidden fields in the last row. str_hidden = u''.join(hidden_fields) if output: last_row = output[-1] # Chop off the trailing row_ender (e.g. '</td></tr>') and # insert the hidden fields. if not last_row.endswith(row_ender): # This can happen in the as_p() case (and possibly others # that users write): if there are only top errors, we may # not be able to conscript the last row for our purposes, # so insert a new, empty row. last_row = (normal_row % { 'errors': '', 'label': '', 'field': '', 'help_text': '', 'html_class_attr': html_class_attr }) output.append(last_row) output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender else: # If there aren't any rows in the output, just append the # hidden fields. output.append(str_hidden) return mark_safe(u'\n'.join(output))
def render_field(field, form, form_style, context, template=None, labelclass=None, layout_object=None, attrs=None, template_pack=TEMPLATE_PACK): """ Renders a django-crispy-forms field :param field: Can be a string or a Layout object like `Row`. If it's a layout object, we call its render method, otherwise we instantiate a BoundField and render it using default template 'CRISPY_TEMPLATE_PACK/field.html' The field is added to a list that the form holds called `rendered_fields` to avoid double rendering fields. :param form: The form/formset to which that field belongs to. :param form_style: A way to pass style name to the CSS framework used. :template: Template used for rendering the field. :layout_object: If passed, it points to the Layout object that is being rendered. We use it to store its bound fields in a list called `layout_object.bound_fields` :attrs: Attributes for the field's widget """ with KeepContext(context): FAIL_SILENTLY = getattr(settings, 'CRISPY_FAIL_SILENTLY', True) if hasattr(field, 'render'): if 'template_pack' in inspect.getargspec(field.render)[0]: return field.render(form, form_style, context, template_pack=template_pack) else: return field.render(form, form_style, context) else: # This allows fields to be unicode strings, always they don't use non ASCII try: if isinstance(field, text_type): field = field.encode('ascii').decode() # If `field` is not unicode then we turn it into a unicode string, otherwise doing # str(field) would give no error and the field would not be resolved, causing confusion else: field = text_type(field) except (UnicodeEncodeError, UnicodeDecodeError): raise Exception( "Field '%s' is using forbidden unicode characters" % field) try: # Injecting HTML attributes into field's widget, Django handles rendering these field_instance = form.fields[field] if attrs is not None: widgets = getattr(field_instance.widget, 'widgets', [field_instance.widget]) # We use attrs as a dictionary later, so here we make a copy list_attrs = attrs if isinstance(attrs, dict): list_attrs = [attrs] * len(widgets) for index, (widget, attr) in enumerate(zip(widgets, list_attrs)): if hasattr(field_instance.widget, 'widgets'): if 'type' in attr and attr['type'] == "hidden": field_instance.widget.widgets[ index].is_hidden = True field_instance.widget.widgets[ index] = field_instance.hidden_widget() field_instance.widget.widgets[index].attrs.update(attr) else: if 'type' in attr and attr['type'] == "hidden": field_instance.widget.is_hidden = True field_instance.widget = field_instance.hidden_widget( ) field_instance.widget.attrs.update(attr) except KeyError: if not FAIL_SILENTLY: raise Exception("Could not resolve form field '%s'." % field) else: field_instance = None logging.warning("Could not resolve form field '%s'." % field, exc_info=sys.exc_info()) if hasattr(form, 'rendered_fields'): if not field in form.rendered_fields: form.rendered_fields.add(field) else: if not FAIL_SILENTLY: raise Exception( "A field should only be rendered once: %s" % field) else: logging.warning( "A field should only be rendered once: %s" % field, exc_info=sys.exc_info()) if field_instance is None: html = '' else: bound_field = BoundField(form, field_instance, field) if template is None: if form.crispy_field_template is None: template = default_field_template(template_pack) else: # FormHelper.field_template set template = get_template(form.crispy_field_template) else: template = get_template(template) # We save the Layout object's bound fields in the layout object's `bound_fields` list if layout_object is not None: if hasattr(layout_object, 'bound_fields') and isinstance( layout_object.bound_fields, list): layout_object.bound_fields.append(bound_field) else: layout_object.bound_fields = [bound_field] context.update({ 'field': bound_field, 'labelclass': labelclass, 'flat_attrs': flatatt(attrs if isinstance(attrs, dict) else {}), }) html = template.render(context) return html
def configure(self): from djangoplus.ui.components.forms import factory hidden_fields = [] one_to_one_fields = dict() one_to_many_fields = dict() for name in list(self.fields.keys()): field = self.fields[name] if type(field) == OneToOneField: one_to_one_fields[name] = field del (self.fields[name]) elif type(field) == OneToManyField: one_to_many_fields[name] = field del (self.fields[name]) if not self.fieldsets: fields = list(self.fields.keys()) + list( one_to_one_fields.keys()) + list(one_to_many_fields.keys()) if self.inline: self.fieldsets = (('', {'fields': (fields, )}), ) else: self.fieldsets = (('', {'fields': fields}), ) fieldset_field_names = [] extra_fieldset_field_names = [] for title, fieldset in self.fieldsets: field_names = fieldset.get('fields', ()) relation_names = fieldset.get('relations', ()) for name_or_tuple in tuple(field_names) + tuple(relation_names): for name in iterable(name_or_tuple): fieldset_field_names.append(name) for field_name in list(self.fields.keys()): if field_name not in fieldset_field_names: extra_fieldset_field_names.append(field_name) if extra_fieldset_field_names: self.fieldsets += ('Outros', { 'fields': extra_fieldset_field_names, }), for title, fieldset in self.fieldsets: title = '::' in title and title.split('::')[1] or title.split( '::')[0] field_names = fieldset.get('fields', ()) relation_names = fieldset.get('relations', ()) configured_fieldset = dict(title=title, tuples=[], one_to_one=[], one_to_many=[]) for name_or_tuple in tuple(field_names) + tuple(relation_names): fields = [] for name in iterable(name_or_tuple): if name in self.fields: field = self.fields[name] bf = BoundField(self, field, name) if bf.is_hidden: hidden_fields.append(bf) else: if bf.label: label = conditional_escape(str(bf.label)) if self.label_suffix: if label[-1] not in ':?.!': label += self.label_suffix label = label or '' else: label = '' help_text = field.help_text or '' label = str(label)[0:-1] label = field.required and '{}<span class="text-danger">*</span>'.format( label) or label d = dict(name=name, request=self.request, label=label, widget=bf, help_text=help_text) fields.append(d) elif name in one_to_one_fields: field = one_to_one_fields[name] one_to_one_id = getattr(self.instance, '{}_id'.format(name)) form = factory.get_one_to_one_form(self.request, self.instance, name, one_to_one_id, partial=True, prefix=name) required = field.required or form.data.get( form.prefix, None) save = form.data.get(form.prefix, None) if not required: for field_name in form.fields: form.fields[field_name].required = False configured_fieldset['one_to_one'].append( (field, form, required, save)) self.inner_forms.append(form) elif name in one_to_many_fields: field = one_to_many_fields[name] one_to_many_forms = [] if self.instance.pk: qs = getattr(self.instance, name).all() else: qs = field.queryset.filter(pk=0) count = qs.count() for i in range(0, field.one_to_many_max): instance = i < count and qs[i] or None form = factory.get_one_to_many_form( self.request, self.instance, name, partial=True, inline=True, prefix='{}{}'.format(name, i), instance=instance) form.id = '{}-{}'.format(name, i) form.hidden = i > count or field.one_to_many_count required = form.data.get(form.prefix, None) if not required: for field_name in form.fields: form.fields[field_name].required = False one_to_many_forms.append(form) self.inner_forms.append(form) one_to_many_count = None if field.one_to_many_count: if type(field.one_to_many_count) is int: one_to_many_count = field.one_to_many_count else: app_label = get_metadata(qs.model, 'app_label') if '__' in field.one_to_many_count: tokens = field.one_to_many_count.split( '__') model_name = self.fields[tokens[ 0]].queryset.model.__name__.lower() model_lookup = '__'.join(tokens[1:]) one_to_many_count = '{}:/view/{}/{}/PK/?one_to_many_count={}'.format( tokens[0], app_label, model_name, model_lookup) else: one_to_many_count = field.one_to_many_count configured_fieldset['one_to_many'].append( (name, field, one_to_many_forms, one_to_many_count)) if len(fields) > 2 or mobile(self.request): self.horizontal = False configured_fieldset['tuples'].append(fields) self.configured_fieldsets.append(configured_fieldset) self.str_hidden = ''.join([str(x) for x in hidden_fields])
def get_address_fields(self): """ Iterates through all address field_dict in form. """ for name in self.__address_fields: yield BoundField(self, self.__address_fields[name], name)