zostera / django-bootstrap5

Bootstrap 5 for Django
BSD 3-Clause "New" or "Revised" License
397 stars 88 forks source link

`success_css_class` on `bootstrap_field` takes no effect #302

Open Real-Gecko opened 2 years ago

Real-Gecko commented 2 years ago

Code image

Result image

vsalvino commented 2 years ago

I'm experiencing the same problem.

From reading the docs, it seems that success_css_class has been changed between v4 and v5. Previously, if it was empty, no class was applied. However, now it functions as "extra" CSS classes to be added on top of is-valid (which is globally enabled via server_side_validation=True)

The old behavior was much more flexible, as we usually only want the error class applied and not a success class. The success class is effectively always applied, even on empty forms when they are rendered for the first time, which looks quite odd.

LauriKorpela commented 2 years ago

Having the same issue.

Any workarounds known yet?

tom-price commented 2 years ago

I've had a look into this and it appears the defaults for success_css_class and error_css_class are linked back to how form validation was handled in Bootstrap 3. In that case they were applied to the wrapper around the label and input and not a class on the input tag.

I've not tested this, but you should be able to override the get_server_side_validation_classes method in this way to change the classes from is-valid and is-invalid.

from django_bootstrap5.renderers import FieldRenderer

class CustomFieldRenderer(FieldRenderer):
    def get_server_side_validation_classes(self):
        """Return CSS classes for server-side validation."""
        if self.field_errors:
            return self.error_css_class
        elif self.field.form.is_bound:
            return self.success_css_class
        return ""

Also add to your settings roughly this

BOOTSTRAP5 = {
    'field_renderers': {
        'default': 'SOME_PATH.CustomFieldRenderer',
    },
}

I'm doing something similar to prevent the setting of is-valid in the first place to prevent validation successes on empty fields (and as a side affect all other fields).

LauriKorpela commented 2 years ago

@tom-price, Thanks! This worked out-of-the-box and I'll use it until proper fix is available.

paduszyk commented 1 year ago

@tom-price Thanks a lot for a great solution!

Real-Gecko commented 1 year ago

I've noticed that overriding success_css_class inside BOOTSTRAP5 settings dict does not work either.

RmaxTwice commented 1 year ago

I've had a look into this and it appears the defaults for success_css_class and error_css_class are linked back to how form validation was handled in Bootstrap 3. In that case they were applied to the wrapper around the label and input and not a class on the input tag.

I've not tested this, but you should be able to override the get_server_side_validation_classes method in this way to change the classes from is-valid and is-invalid.

from django_bootstrap5.renderers import FieldRenderer

class CustomFieldRenderer(FieldRenderer):
    def get_server_side_validation_classes(self):
        """Return CSS classes for server-side validation."""
        if self.field_errors:
            return self.error_css_class
        elif self.field.form.is_bound:
            return self.success_css_class
        return ""

Also add to your settings roughly this

BOOTSTRAP5 = {
    'field_renderers': {
        'default': 'SOME_PATH.CustomFieldRenderer',
    },
}

I'm doing something similar to prevent the setting of is-valid in the first place to prevent validation successes on empty fields (and as a side affect all other fields).

You are a savior! great workaround!

blag commented 1 year ago

@tom-price Do you mind crafting a PR for this?

dwgreen1 commented 10 months ago

@tom-price is there any update on this issue?