from django import forms from django.forms.widgets import TextInput from django.core.files.uploadedfile import UploadedFile from django.utils.safestring import mark_safe from django.template import loader import base64 import datetime import json class HtmlDateInput(TextInput): def __init__(self, *args, **kwargs): kwargs.update({'attrs': {'type': 'date', 'required-pattern': '[0-9]{4}-[0-9]{2}-[0-9]{2}'}}) super(HtmlDateInput, self).__init__(*args, **kwargs) def format_value(self, val): if isinstance(val, datetime.datetime): val = val.date() return super(HtmlDateInput, self).format_value(val) class RequiredFileUploadWidget(forms.FileInput): def __init__(self, filename=None, attrs=None): self.filename = filename super(RequiredFileUploadWidget, self).__init__(attrs) def render(self, name, value, attrs=None): output = [] if value and hasattr(value, 'url'): output.append('Current file: '.format(value.url)) if self.filename: output.append(self.filename) else: output.append(value.name) output.append('
') output.append("Upload new file: ") output.append(super(RequiredFileUploadWidget, self).render(name, value, attrs)) return mark_safe(''.join(output)) class PrettyPrintJsonWidget(forms.Textarea): def render(self, name, value, attrs=None, renderer=None): # This is mighty ugly -- we parse the json and then turn it back into json. # Luckily this isn't called often :) try: if value is not None: if isinstance(value, dict): # Already a dict, so just turn it into json value = json.dumps(value, indent=2) else: value = json.dumps(json.loads(value), indent=2) except ValueError: # Don't try to do anything if it's not valid json pass t = super(PrettyPrintJsonWidget, self).render(name, value, attrs, renderer) return t class MonospaceTextarea(forms.Textarea): def render(self, name, value, attrs=None, renderer=None): attrs['class'] = "{0} text-monospace".format(attrs.get('class', '')) return super(MonospaceTextarea, self).render(name, value, attrs, renderer) class TagOptionsTextWidget(forms.Textarea): def __init__(self, taglist, *args, **kwargs): self.taglist = taglist super(TagOptionsTextWidget, self).__init__(*args, **kwargs) def render(self, name, value, attrs=None, renderer=None): t = super(TagOptionsTextWidget, self).render(name, value, attrs, renderer) return t + mark_safe('
Suggested tags: {}
'.format( attrs['id'], "".join(('{}'.format(t) for t in self.taglist)) )) class EmailTextWidget(forms.Textarea): def render(self, name, value, attrs=None, renderer=None): attrs.update({ "cols": "72", "class": "{0} textarea-mail".format(attrs.get('class', '')), }) t = super(EmailTextWidget, self).render(name, value, attrs, renderer) return mark_safe('
This text area is initially sized to the correct width of an email!
') + t class InlineImageUploadWidget(forms.ClearableFileInput): clear_checkbox_label = "Remove image" def render(self, name, value, attrs=None, renderer=None): context = self.get_context(name, value, attrs) if value and not isinstance(value, UploadedFile): context['widget']['value'] = base64.b64encode(value).decode('ascii') context['widget']['imagetype'] = 'image/png' if bytes(value[:8]) == b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A' else 'image/jpg' return mark_safe(loader.render_to_string('confreg/widgets/inline_photo_upload_widget.html', context)) class InlinePdfUploadWidget(forms.ClearableFileInput): clear_checkbox_label = "Remove PDF" def render(self, name, value, attrs=None, renderer=None): context = self.get_context(name, value, attrs) if value and not isinstance(value, UploadedFile) and type(value) != object: context['widget']['value'] = base64.b64encode(value).decode('ascii') return mark_safe(loader.render_to_string('confreg/widgets/inline_pdf_upload_widget.html', context)) class AdminJsonWidget(PrettyPrintJsonWidget): def render(self, name, value, attrs=None, renderer=None): attrs['cols'] = 100 return super(AdminJsonWidget, self).render(name, value, attrs, renderer) class StaticTextWidget(TextInput): def __init__(self, *args, **kwargs): self.monospace = kwargs.pop('monospace', False) super(StaticTextWidget, self).__init__(*args, **kwargs) def render(self, name, value, attrs=None, renderer=None): if self.monospace: return mark_safe('
{0}
'.format(value)) else: return mark_safe(value) class SimpleTreeviewWidget(TextInput): template_name = 'forms/widgets/treeview_widget.html' def __init__(self, *args, **kwargs): self.treedata = dict(kwargs.pop('treedata')) super().__init__(*args, **kwargs) def get_context(self, name, value, attrs): context = super().get_context(name, value, attrs) context['treedata'] = self.treedata return context class StaticHtmlPreviewWidget(TextInput): template_name = 'forms/widgets/static_html_preview_widget.html' def get_context(self, name, value, attrs): d = super().get_context(name, value, attrs) d['base64content'] = base64.b64encode(d['widget']['value'].encode()).decode('ascii') return d class TestButtonWidget(TextInput): template_name = 'forms/widgets/test_button_widget.html' class Bootstrap4CheckboxSelectMultiple(forms.CheckboxSelectMultiple): template_name = 'forms/widgets/bs4_checkbox_select.html' class Bootstrap4HtmlDateTimeInput(forms.DateTimeInput): template_name = 'forms/widgets/bs4_datetime_input.html' class LinkForCodeWidget(TextInput): template_name = 'forms/widgets/linkforcode_widget.html' def get_context(self, name, value, attrs): d = super().get_context(name, value, attrs) d['authurl'] = self.authurl return d class SubmitButtonWidget(forms.Widget): template_name = 'forms/widgets/submitbutton_widget.html' def get_context(self, name, value, attrs): d = super().get_context(name, value, attrs) d['label'] = self.label d['prefixparagraph'] = self.prefixparagraph return d class SelectSetValueWidget(forms.Select): option_template_name = 'forms/widgets/select_set_value_option.html' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def get_context(self, name, value, attrs): attrs['data-set-form-field'] = 'id_{}'.format(self.setvaluefield) context = super().get_context(name, value, attrs) context['setmap'] = self.setvalues return context class CallForPapersSpeakersWidget(forms.SelectMultiple): template_name = 'forms/widgets/speaker_select.html' def __init__(self, conference, *args, **kwargs): self.conference = conference super().__init__(*args, **kwargs) def get_context(self, name, value, attrs): context = super().get_context(name, value, attrs) context['widget']['options'] = list(self.options(name, context['widget']['value'], attrs)) context['confurlname'] = self.conference.urlname return context