Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# Imports 

2 

3from datetime import timedelta 

4from django import forms 

5from django.utils.translation import ugettext_lazy as _ 

6from json import dumps as json_dumps 

7import os 

8from superdjango.assets import JavaScript, StyleSheet 

9 

10# Exports 

11 

12__all__ = ( 

13 "AjaxUploadWidget", 

14 "ChooserWidget", 

15 "CodeEditorWidget", 

16 "ColorPickerWidget", 

17 "MarkdownWidget", 

18 "ReadOnlyWidget", 

19 "SlugFromWidget", 

20) 

21 

22# Widgets 

23 

24 

25class AjaxUploadWidget(forms.ClearableFileInput): 

26 

27 def render(self, name, value, attrs=None, renderer=None): 

28 if attrs is None: 

29 attrs = dict() 

30 

31 # attrs['style'] = 'display: none;' 

32 html = super().render(name, value, attrs=attrs, renderer=renderer) 

33 

34 context = { 

35 'message': _("Please enable JavaScript to use the file uploader."), 

36 'name': name, 

37 } 

38 html += '<div id="file-uploader-%(name)s"><noscript><p>%(message)s</p></noscript></div>' % context 

39 # html += '<input type="hidden" name="%s" value="%s" id="file-uploader-%s-field">' % ( 

40 # name, 

41 # value or "", 

42 # name 

43 # ) 

44 return html 

45 

46 

47class ChooserWidget(forms.Select): 

48 pass 

49 

50 

51class CodeEditorWidget(forms.widgets.Textarea): 

52 template_name = "html/forms/widgets/code_editor.html" 

53 

54 def render(self, name, value, attrs=None, renderer=None): 

55 context = self.get_context(name, value, attrs) 

56 template = os.path.join("html", "forms", "widgets", "code_editor.html") 

57 

58 return self._render(template, context, renderer) 

59 

60 

61class ColorPickerWidget(forms.TextInput): 

62 

63 @property 

64 def media(self): 

65 return forms.Media( 

66 css={ 

67 'all': [ 

68 "bundled/wcp/css/wheelcolorpicker.css", 

69 ] 

70 }, 

71 js=[ 

72 "bundled/wcp/jquery.wheelcolorpicker.js", 

73 "superdjango/ui/js/color_picker.js", 

74 ] 

75 ) 

76 

77 

78class HumanFriendlyDurationWidget(forms.TextInput): 

79 """Allows human-friendly durations.""" 

80 

81 def format_value(self, value): 

82 tokens = list() 

83 if value.days: 

84 tokens.append("%sd" % value.days) 

85 

86 if value.hours: 

87 tokens.append("%sh" % value.hours) 

88 

89 if value.minutes: 

90 tokens.append("%sm" % value.minutes) 

91 

92 if value.seconds: 

93 tokens.append("%ss" % value.seconds) 

94 

95 return " ".join(tokens) 

96 

97 @staticmethod 

98 def to_python(value): 

99 days = None 

100 hours = None 

101 minutes = None 

102 seconds = None 

103 

104 tokens = value.split(" ") 

105 for t in tokens: 

106 t = t.strip() 

107 if t.endswith("d"): 

108 days = int(t.replace("d", "").strip()) 

109 elif t.endswith("h"): 

110 hours = int(t.replace("h", "").strip()) 

111 elif t.endswith("m"): 

112 minutes = int(t.replace("m", "").strip()) 

113 elif t.endswith("s"): 

114 seconds = int(t.replace("s", "").strip()) 

115 else: 

116 pass 

117 

118 return timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds) 

119 

120 

121class MarkdownWidget(forms.widgets.Textarea): 

122 """A widget for creating a Markdown editor. 

123 

124 Base on `SimpleMDE`_. 

125 

126 .. _SimpleMDE: https://github.com/sparksuite/simplemde-markdown-editor 

127 

128 """ 

129 

130 template_name = "html/forms/widgets/markdown.html" 

131 

132 def __init__(self, attrs=None, options=None): 

133 """Initialize the widget. The ``options`` parameter is for SimpleMDE options.""" 

134 super().__init__(attrs=attrs) 

135 

136 self._widget_options = options or dict() 

137 

138 # noinspection PyUnusedLocal 

139 # @classmethod 

140 # def get_css(cls, field_name=None): 

141 # """Get the CSS for the editor. Works with SuperDjango UI. 

142 # 

143 # :param field_name: The name of the field. NOT USED, but included to maintain the standard signature. 

144 # :type field_name: str 

145 # 

146 # :rtype: StyleSheet 

147 # 

148 # """ 

149 # css = StyleSheet() 

150 # 

151 # css.append("simplemde", url="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css") 

152 # 

153 # return css 

154 # 

155 # # noinspection PyUnusedLocal 

156 # @classmethod 

157 # def get_js(cls, field_name=None): 

158 # """Get the JavaScript for the editor. Works with SuperDjango UI. 

159 # 

160 # :param field_name: The name of the field. 

161 # :type field_name: str 

162 # 

163 # :rtype: JavaScript 

164 # 

165 # """ 

166 # js = JavaScript() 

167 # 

168 # js.append("simplemde", url="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js") 

169 # js.append("simplemde-fields", url="superdjango/forms/js/simplemde.js") 

170 # 

171 # return js 

172 

173 @property 

174 def media(self): 

175 """Support for standard Django implementation.""" 

176 return forms.Media( 

177 css={ 

178 'all': [ 

179 "https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css", 

180 ] 

181 }, 

182 js=[ 

183 "https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js", 

184 "superdjango/forms/js/simplemde.js", 

185 ] 

186 ) 

187 

188 def render(self, name, value, attrs=None, renderer=None): 

189 """Add class and options to output.""" 

190 # markdown class now exists in the template. 

191 # if "class" not in attrs: 

192 # attrs['class'] = "" 

193 # 

194 # attrs['class'] += " markdown" 

195 

196 attrs['data-simplemde-options'] = json_dumps(self._widget_options) 

197 

198 # insert this style tag to fix the label from breaking into the toolbar 

199 # html = super().render(name, value, attrs, renderer=renderer) 

200 # html += "<style>.field-%s label { float: none; }</style>" % name 

201 # return mark_safe(html) 

202 

203 context = self.get_context(name, value, attrs) 

204 # template = os.path.join("html", "forms", "widgets", "markdown.html") 

205 

206 return self._render(self.template_name, context, renderer) 

207 

208 

209class ReadOnlyWidget(forms.widgets.Input): 

210 """Display only the value of the field.""" 

211 

212 template_name = "html/forms/widgets/readonly.html" 

213 

214 def __init__(self, attrs=None): 

215 if attrs is None: 

216 attrs = {'disabled': True} 

217 

218 super().__init__(attrs=attrs) 

219 

220 def render(self, name, value, attrs=None, renderer=None): 

221 if hasattr(self, "initial"): 

222 value = self.initial 

223 

224 return value 

225 

226 

227class SlugFromWidget(forms.widgets.TextInput): 

228 """Supports real-time slug generation from another field.""" 

229 

230 template_name = "html/forms/widgets/slug.html" 

231 

232 def __init__(self, attrs=None, from_field="title"): 

233 self.from_field = from_field 

234 

235 _attrs = attrs or dict() 

236 _attrs['data-from-field'] = from_field 

237 

238 super().__init__(attrs=_attrs) 

239 

240 @property 

241 def media(self): 

242 return forms.Media( 

243 js=[ 

244 "superdjango/ui/js/slugify.js", 

245 ] 

246 )