class LeafletFormMixin(CascadeModelFormMixin): map_width = SizeField( label=_("Map Width"), allowed_units=['px', '%'], initial='100%', help_text=_( "Set the map width in percent relative to containing element."), ) map_height = SizeField( label=_("Adapt Map Height"), allowed_units=['px', '%'], initial='400px', help_text= _("Set a fixed height in pixels, or percent relative to the map width." ), ) map_min_height = SizeField( label=_("Adapt Map Minimum Height"), allowed_units=['px'], required=False, help_text=_("Optional, set a minimum height in pixels."), ) scroll_wheel_zoom = BooleanField( label=_("Zoom by scrolling wheel"), initial=True, required=False, help_text=_("Zoom into map on mouse over by scrolling wheel."), ) map_position = HiddenDictField( initial=app_settings.CMSPLUGIN_CASCADE['leaflet']['default_position'], ) class Meta: entangled_fields = { 'glossary': [ 'map_width', 'map_height', 'map_position', 'map_min_height', 'scroll_wheel_zoom' ] } def clean(self): cleaned_data = super().clean() try: if isinstance(cleaned_data['map_position'], str): cleaned_data['map_position'] = json.loads( cleaned_data['map_position']) elif not isinstance(cleaned_data['map_position'], dict): raise ValueError except (ValueError, KeyError): raise ValidationError( "Invalid internal position data. Check your Javascript imports." ) return cleaned_data
class BootstrapImageFormMixin(ImageFormMixin): ALIGNMENT_OPTIONS = [ ('float-left', _("Left")), ('float-right', _("Right")), ('mx-auto', _("Center")), ] image_shapes = MultipleChoiceField( label=_("Image Shapes"), choices=IMAGE_SHAPE_CHOICES, widget=widgets.CheckboxSelectMultiple, initial=['img-fluid'] ) image_width_responsive = SizeField( label=_("Responsive Image Width"), allowed_units=['%'], initial='100%', required = False, help_text=_("Set the image width in percent relative to containing element."), ) image_width_fixed = SizeField( label=_("Fixed Image Width"), allowed_units=['px'], required = False, help_text=_("Set a fixed image width in pixels."), ) image_height = SizeField( label=_("Adapt Image Height"), allowed_units=['px', '%'], required = False, help_text=_("Set a fixed height in pixels, or percent relative to the image width."), ) resize_options = MultipleChoiceField( label=_("Resize Options"), choices=IMAGE_RESIZE_OPTIONS, widget=widgets.CheckboxSelectMultiple, required = False, help_text=_("Options to use when resizing the image."), initial=['subject_location', 'high_resolution'], ) image_alignment = ChoiceField( label=_("Image Alignment"), choices=ALIGNMENT_OPTIONS, widget=widgets.RadioSelect, required = False, help_text=_("How to align a non-responsive image."), ) class Meta: entangled_fields = {'glossary': ['image_shapes', 'image_width_responsive', 'image_width_fixed', 'image_height', 'resize_options', 'image_alignment']}
class MapFormMixin(EntangledModelFormMixin): height = SizeField(help_text="Height of the map") lon = CharField(help_text="Longitude of center", label="Longitude") lat = CharField(help_text="Latitude of center", label="Latitude") zoom = IntegerField(help_text="Zoomlevel of map") layers = CharField(widget=Textarea, help_text="One Layer identifier (no blanks) per line. Should be human-readable.") class Meta: entangled_fields = {'glossary': ['height', 'lon', 'lat', 'zoom', 'layers']}
class TextImageFormMixin(ImageFormMixin): RESIZE_OPTIONS = [ ('upscale', _("Upscale image")), ('crop', _("Crop image")), ('subject_location', _("With subject location")), ('high_resolution', _("Optimized for Retina")), ] image_width = SizeField( label=_("Image Width"), allowed_units=['px'], required=True, help_text=_("Set the image width in pixels."), ) image_height = SizeField( label=_("Image Height"), allowed_units=['px'], required=False, help_text=_("Set the image height in pixels."), ) resize_options = MultipleChoiceField( label=_("Resize Options"), choices=RESIZE_OPTIONS, required=False, widget=widgets.CheckboxSelectMultiple, help_text=_("Options to use when resizing the image."), initial=['subject_location', 'high_resolution']) alignement = ChoiceField( label=_("Alignement"), choices=[('', _("Not aligned")), ('left', _("Left")), ('right', _("Right"))], required=False, widget=widgets.RadioSelect, initial='', ) class Meta: entangled_fields = { 'glossary': ['image_width', 'image_height', 'resize_options', 'alignement'] }
class FramedIconFormMixin(IconFormMixin): SIZE_CHOICES = [('{}em'.format(c), "{} em".format(c)) for c in range(1, 13)] RADIUS_CHOICES = [(None, _("Square"))] + \ [('{}px'.format(r), "{} px".format(r)) for r in (1, 2, 3, 5, 7, 10, 15, 20)] + \ [('50%', _("Circle"))] TEXT_ALIGN_CHOICES = [ (None, _("Do not align")), ('text-left', _("Left")), ('text-center', _("Center")), ('text-right', _("Right")) ] font_size = SizeField( label=_("Icon size"), allowed_units=['px', 'em'], initial='1em', ) color = ColorField( label=_("Icon color"), ) background_color = ColorField( label=_("Background color"), inherit_color=True, ) text_align = ChoiceField( choices=TEXT_ALIGN_CHOICES, label=_("Text alignment"), required=False, help_text=_("Align the icon inside the parent column.") ) border = BorderChoiceField( label=_("Set border"), ) border_radius = ChoiceField( choices=RADIUS_CHOICES, label=_("Border radius"), required=False, ) class Meta: entangled_fields = {'glossary': ['font_size', 'color', 'background_color', 'text_align', 'border', 'border_radius']}
class MarkerForm(EntangledModelForm): title = CharField( label=_("Marker Title"), widget=widgets.TextInput(attrs={'size': 60}), help_text=_( "Please choose a title, then go to the map to set a marker pin")) use_icon = BooleanField( label=_("Use customized marker icon"), initial=False, required=False, ) marker_image = AdminImageFormField( ManyToOneRel(FilerImageField, Image, 'file_ptr'), Image.objects.all(), label=_("Marker Image"), required=False, to_field_name='image_file', ) marker_width = SizeField( label=_("Marker Width"), allowed_units=['px'], required=False, help_text=_("Width of the marker icon in pixels."), ) marker_anchor = MultiSizeField( ['left', 'top'], label=_("Marker Anchor"), allowed_units=['px', '%'], required=False, help_text= _("The coordinates of the icon's anchor (relative to its top left corner)." ), ) popup_text = HTMLFormField( required=False, help_text=_("Optional rich text to display in popup."), ) position = HiddenDictField() class Meta: entangled_fields = { 'glossary': [ 'title', 'use_icon', 'marker_image', 'marker_width', 'marker_anchor', 'popup_text', 'position' ] } def clean(self): cleaned_data = super().clean() try: position = cleaned_data['position'] if isinstance(position, str): position = json.loads(position) elif not isinstance(position, dict): raise ValueError except (ValueError, KeyError): raise ValidationError( "Invalid internal position data. Check your Javascript imports." ) else: if 'lat' not in position or 'lng' not in position: # place the marker in the center of the current map position = { k: v for k, v in self.instance.cascade_element. glossary['map_position'].items() if k in ['lat', 'lng'] } cleaned_data['position'] = position popup_text = cleaned_data.pop('popup_text', '') if strip_tags(popup_text): cleaned_data['popup_text'] = strip_spaces_between_tags(popup_text) return cleaned_data