class BootstrapPictureFormMixin(ImageFormMixin): responsive_heights = BootstrapMultiSizeField( label=_("Adapt Picture Heights"), required=False, require_all_fields=False, allowed_units=['px', '%'], initial='100%', help_text= _("Heights of picture in percent or pixels for distinct Bootstrap's breakpoints." ), ) responsive_zoom = BootstrapMultiSizeField( label=_("Adapt Picture Zoom"), required=False, require_all_fields=False, allowed_units=['%'], initial=['0%', '0%', '0%', '0%', '0%'], help_text= _("Magnification of picture in percent for distinct Bootstrap's breakpoints." ), ) resize_options = MultipleChoiceField( label=_("Resize Options"), choices=IMAGE_RESIZE_OPTIONS, widget=widgets.CheckboxSelectMultiple, initial=['subject_location', 'high_resolution'], help_text=_("Options to use when resizing the image."), ) image_shapes = MultipleChoiceField(label=_("Image Shapes"), choices=IMAGE_SHAPE_CHOICES, widget=widgets.CheckboxSelectMultiple, initial=['img-fluid']) class Meta: entangled_fields = { 'glossary': [ 'responsive_heights', 'responsive_zoom', 'resize_options', 'image_shapes' ] }
class CarouselSlidesFormMixin(ManageChildrenFormMixin, EntangledModelFormMixin): OPTION_CHOICES = [('slide', _("Animate")), ('pause', _("Pause")), ('wrap', _("Wrap"))] num_children = IntegerField( min_value=1, initial=1, label=_('Slides'), help_text=_('Number of slides for this carousel.'), ) interval = IntegerField( label=_("Interval"), initial=5, help_text=_("Change slide after this number of seconds."), ) options = MultipleChoiceField( label=_('Options'), choices=OPTION_CHOICES, widget=widgets.CheckboxSelectMultiple, initial=['slide', 'wrap', 'pause'], help_text=_("Adjust interval for the carousel."), ) container_max_heights = BootstrapMultiSizeField( label=_("Carousel heights"), allowed_units=['px'], initial=['100px', '150px', '200px', '250px', '300px'], help_text= _("Heights of Carousel in pixels for distinct Bootstrap's breakpoints." ), ) resize_options = MultipleChoiceField( label=_("Resize Options"), choices=IMAGE_RESIZE_OPTIONS, widget=widgets.CheckboxSelectMultiple, help_text=_("Options to use when resizing the image."), initial=['upscale', 'crop', 'subject_location', 'high_resolution'], ) class Meta: untangled_fields = ['num_children'] entangled_fields = { 'glossary': ['interval', 'options', 'container_max_heights', 'resize_options'] }
class JumbotronFormMixin(EntangledModelFormMixin): """ Form class to validate the JumbotronPlugin. """ ATTACHMENT_CHOICES = ['scroll', 'fixed', 'local'] VERTICAL_POSITION_CHOICES = ['top', '10%', '20%', '30%', '40%', 'center', '60%', '70%', '80%', '90%', 'bottom'] HORIZONTAL_POSITION_CHOICES = ['left', '10%', '20%', '30%', '40%', 'center', '60%', '70%', '80%', '90%', 'right'] REPEAT_CHOICES = ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'] SIZE_CHOICES = ['auto', 'width/height', 'cover', 'contain'] fluid = BooleanField( label=_("Is fluid"), initial=True, required=False, help_text=_("Shall this element occupy the entire horizontal space of its parent."), ) element_heights = BootstrapMultiSizeField( label=("Element Heights"), required=True, allowed_units=['rem', 'px', 'auto'], initial='300px', help_text=_("This property specifies the height for each Bootstrap breakpoint."), ) background_color = ColorField( label=_("Background color"), ) image_file = CascadeImageField( label=_("Background image"), required=False, ) background_repeat = ChoiceField( label=_("Background repeat"), choices=[(c, c) for c in REPEAT_CHOICES], widget=widgets.RadioSelect, initial='no-repeat', required=False, help_text=_("This property specifies how the background image repeates."), ) background_attachment = ChoiceField( label=_("Background attachment"), choices=[(c, c) for c in ATTACHMENT_CHOICES], widget=widgets.RadioSelect, initial='local', required=False, help_text=_("This property specifies how to move the background image relative to the viewport."), ) background_vertical_position = ChoiceField( label=_("Background vertical position"), choices=[(c, c) for c in VERTICAL_POSITION_CHOICES], initial='center', required=False, help_text=_("This property moves a background image vertically within its container."), ) background_horizontal_position = ChoiceField( label=_("Background horizontal position"), choices=[(c, c) for c in HORIZONTAL_POSITION_CHOICES], initial='center', required=False, help_text=_("This property moves a background image horizontally within its container."), ) background_size = ChoiceField( label=_("Background size"), choices=[(c, c) for c in SIZE_CHOICES], widget=widgets.RadioSelect, initial='auto', required=False, help_text=_("This property specifies how the background image is sized."), ) background_width_height = MultiSizeField( ['width', 'height'], label=_("Background width/height"), allowed_units=['px', '%'], required=False, help_text=_("This property specifies the width and height of a background image in px or %."), ) class Meta: entangled_fields = {'glossary': ['fluid', 'background_color', 'element_heights', 'image_file', 'background_repeat', 'background_attachment', 'background_vertical_position', 'background_horizontal_position', 'background_size', 'background_width_height']} def validate_optional_field(self, name): field = self.fields[name] value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) if value in field.empty_values: self.add_error(name, ValidationError(field.error_messages['required'], code='required')) else: return value def clean(self): cleaned_data = super().clean() if cleaned_data['image_file']: self.validate_optional_field('background_repeat') self.validate_optional_field('background_attachment') self.validate_optional_field('background_vertical_position') self.validate_optional_field('background_horizontal_position') if self.validate_optional_field('background_size') == 'width/height': try: cleaned_data['background_width_height']['width'] except KeyError: msg = _("You must at least set a background width.") self.add_error('background_width_height', msg) raise ValidationError(msg) return cleaned_data