jrief / django-formset

The missing widgets and form manipulation library for Django
https://django-formset.fly.dev/
MIT License
320 stars 30 forks source link

df-show on Activator not working #165

Open lsmoker opened 5 days ago

lsmoker commented 5 days ago

For some reason, the df-show attr on an Activator field doesn't work for me. The hidden attribute is always added. For other field types, df-show works fine.

In the code below, recipients_button is always hidden regardless of the value of allow_email_download (I even hacked some js to see if it could be worked around - no go), while email_recipients behaves as expected.

class BundleForm(forms.ModelForm):
    allow_email_download = fields.BooleanField(
        required=False,
    )
    recipients_button = Activator(
        required=False,
        widget=Button(
            action='activate("apply")',
            attrs={'df-show': ".allow_email_download=='true'"},
            button_variant=ButtonVariant.SUCCESS,
        ),
    )
    email_recipients = fields.CharField(
        required=False,
        widget=widgets.TextInput(
            attrs={'df-show': ".allow_email_download=='true'"}
        )
    )

When I get time, I can do more testing for a better report.

lsmoker commented 4 days ago

allow_email_download renders to <input name="allow_email_download" value="true" form="id_bundles.0.bundle" id="id_bundles.0.bundle.allow_email_download">

lsmoker commented 4 days ago

Also, help_text is not hidden when it should be.

jrief commented 4 days ago

please also try with attrs={'df-show': ".allow_email_download"},. I am wonderning why the BooleanField is not rendered as checkbox.

lsmoker commented 3 days ago

Thanks. I tried using attrs={'df-show': ".allow_email_download"}, (which seems more correct) as well as overriding the widget to CheckboxInput (which appears to be the default for BooleanField anyway). Unfortunately, neither of those changes made it work for me.

I did find that commenting out action='activate("apply")', made the show/hide toggle work as expected (although the button became non-functional obviously) - that seems like a deep Javascript thing...

lsmoker commented 3 days ago

I did make some discoveries...

So there is more complexity in my app than my example above shows. allow_email_download is actually in a form inside a collection, so the path (of the first sibling) is bundles.0.bundle.allow_email_download. If I use attrs={'df-show': "bundles.0.bundle.allow_email_download"},, visibility works correctly(!), while only using .allow_email_download on the email_recipients field works fine...

lsmoker commented 2 days ago

I also found that if allow_email_download is hidden with widget.HiddenInput, then it's not found by evalVisibility. For now, I'm using CSS - display: None to hide it.

Stepping back, what I'm trying to do is use df-show/df-hide to respect Django permissions for certain fields/fieldsets on the form collection. I added a field (allow_email_download) to the main form and used get_initial in the collection view to set it to True if the user has the permission, then used df-show to control its visibility.

jrief commented 2 days ago

I also found that if allow_email_download is hidden with widget.HiddenInput, then it's not found by evalVisibility. For now, I'm using CSS - display: None to hide it.

Using display: none removes the possibility to focus a field and maybe other features. In such situations I therefore reduce the size to 1x1px and use invisible colors.

lsmoker commented 1 day ago

This particular field is not intended for any user interaction since I'm using it to get the permission from the view to the df-show attribute of recipients_button. Would that break needed features?

Or, is there a better way to show/hide a field based on permissions?