Source code for superdjango.forms.widgets

# Imports

from datetime import timedelta
from django import forms
from django.utils.translation import ugettext_lazy as _
from json import dumps as json_dumps
import os
from superdjango.assets import JavaScript, StyleSheet

# Exports

__all__ = (
    "AjaxUploadWidget",
    "ChooserWidget",
    "CodeEditorWidget",
    "ColorPickerWidget",
    "MarkdownWidget",
    "ReadOnlyWidget",
    "SlugFromWidget",
)

# Widgets


[docs]class AjaxUploadWidget(forms.ClearableFileInput): """A file widget that provides support for AJAX uploads."""
[docs] def render(self, name, value, attrs=None, renderer=None): """Get the HTML that supports AJAX upload.""" if attrs is None: attrs = dict() # attrs['style'] = 'display: none;' html = super().render(name, value, attrs=attrs, renderer=renderer) context = { 'message': _("Please enable JavaScript to use the file uploader."), 'name': name, } html += '<div id="file-uploader-%(name)s"><noscript><p>%(message)s</p></noscript></div>' % context # html += '<input type="hidden" name="%s" value="%s" id="file-uploader-%s-field">' % ( # name, # value or "", # name # ) return html
[docs]class ChooserWidget(forms.Select): """A widget that may be used to transform a select into a chooser.""" pass
[docs]class CodeEditorWidget(forms.widgets.Textarea): """A widget for producing a code editor.""" template_name = "html/forms/widgets/code_editor.html"
[docs] def render(self, name, value, attrs=None, renderer=None): """Get the HTML for the code editor.""" context = self.get_context(name, value, attrs) template = os.path.join("html", "forms", "widgets", "code_editor.html") return self._render(template, context, renderer)
[docs]class ColorPickerWidget(forms.TextInput): """A widget that supports a color picker.""" @property def media(self): """Return the form media for the color picker resource.""" return forms.Media( css={ 'all': [ "bundled/wcp/css/wheelcolorpicker.css", ] }, js=[ "bundled/wcp/jquery.wheelcolorpicker.js", "superdjango/ui/js/color_picker.js", ] )
class HumanFriendlyDurationWidget(forms.TextInput): """Allows human-friendly durations.""" def format_value(self, value): """Format the value.""" tokens = list() if value.days: tokens.append("%sd" % value.days) if value.hours: tokens.append("%sh" % value.hours) if value.minutes: tokens.append("%sm" % value.minutes) if value.seconds: tokens.append("%ss" % value.seconds) return " ".join(tokens) @staticmethod def to_python(value): """Convert the duration to Python timedelta.""" days = None hours = None minutes = None seconds = None tokens = value.split(" ") for t in tokens: t = t.strip() if t.endswith("d"): days = int(t.replace("d", "").strip()) elif t.endswith("h"): hours = int(t.replace("h", "").strip()) elif t.endswith("m"): minutes = int(t.replace("m", "").strip()) elif t.endswith("s"): seconds = int(t.replace("s", "").strip()) else: pass return timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
[docs]class MarkdownWidget(forms.widgets.Textarea): """A widget for creating a Markdown editor. Base on `SimpleMDE`_. .. _SimpleMDE: https://github.com/sparksuite/simplemde-markdown-editor """ template_name = "html/forms/widgets/markdown.html"
[docs] def __init__(self, attrs=None, options=None): """Initialize the widget. The ``options`` parameter is for SimpleMDE options.""" super().__init__(attrs=attrs) self._widget_options = options or dict()
# noinspection PyUnusedLocal # @classmethod # def get_css(cls, field_name=None): # """Get the CSS for the editor. Works with SuperDjango UI. # # :param field_name: The name of the field. NOT USED, but included to maintain the standard signature. # :type field_name: str # # :rtype: StyleSheet # # """ # css = StyleSheet() # # css.append("simplemde", url="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css") # # return css # # # noinspection PyUnusedLocal # @classmethod # def get_js(cls, field_name=None): # """Get the JavaScript for the editor. Works with SuperDjango UI. # # :param field_name: The name of the field. # :type field_name: str # # :rtype: JavaScript # # """ # js = JavaScript() # # js.append("simplemde", url="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js") # js.append("simplemde-fields", url="superdjango/forms/js/simplemde.js") # # return js @property def media(self): """Support for standard Django implementation.""" return forms.Media( css={ 'all': [ "https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css", ] }, js=[ "https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js", "superdjango/forms/js/simplemde.js", ] )
[docs] def render(self, name, value, attrs=None, renderer=None): """Add class and options to output.""" # markdown class now exists in the template. # if "class" not in attrs: # attrs['class'] = "" # # attrs['class'] += " markdown" attrs['data-simplemde-options'] = json_dumps(self._widget_options) # insert this style tag to fix the label from breaking into the toolbar # html = super().render(name, value, attrs, renderer=renderer) # html += "<style>.field-%s label { float: none; }</style>" % name # return mark_safe(html) context = self.get_context(name, value, attrs) # template = os.path.join("html", "forms", "widgets", "markdown.html") return self._render(self.template_name, context, renderer)
[docs]class ReadOnlyWidget(forms.widgets.Input): """Display only the value of the field.""" template_name = "html/forms/widgets/readonly.html"
[docs] def __init__(self, attrs=None): """Initialize with ``disabled`` as ``True``.""" if attrs is None: attrs = {'disabled': True} super().__init__(attrs=attrs)
[docs] def render(self, name, value, attrs=None, renderer=None): """Set the initial value.""" if hasattr(self, "initial"): value = self.initial return value
[docs]class SlugFromWidget(forms.widgets.TextInput): """Supports real-time slug generation from another field.""" template_name = "html/forms/widgets/slug.html"
[docs] def __init__(self, attrs=None, from_field="title"): """Initialize with ``data-from-field`` in attributes.""" self.from_field = from_field _attrs = attrs or dict() _attrs['data-from-field'] = from_field super().__init__(attrs=_attrs)
@property def media(self): """Get the form media for creating the slug in real-time.""" return forms.Media( js=[ "superdjango/ui/js/slugify.js", ] )