Uploadcare widget inserted more than once

This is how I insert it:

    formfield_overrides = {
        URLField: {
            'widget': forms.TextInput(attrs={
                'role': 'uploadcare-uploader',
                'size': '60',
                'data-crop': '',
            }),
        },
    }

   class Media:
        js = ('https://ucarecdn.com/libs/widget/3.2.1/uploadcare.full.min.js',)

I think I haven’t seen this problem earlier.

@fedor Can you reproduce it at Codepen, JsBin etc?

I think I’ve realized why this is happening. Although I’m sure what would be the simplest solution…

So Django admin renders hidden “template” row that is later added when “Add extra” button is pressed. This template row already has UC widget rendered and when it’s copied and becomes a visible row UC widget is added once again. Actually one of the buttons doesn’t work, I think because it reflects original “template” row.

Ideally I wouldn’t render UC widget for invisible rows. Can I override default behaviour and instead of default selector use something like [role=“uploadcare-uploader”]:visible?

EDIT: From the widget source code selector = '[role~="uploadcare-uploader"]';, which doesn’t look like the widget has capabilities to override default selector :frowning:
I’d really like to avoid writing custom javascript code, so maybe I’m fine with 2 buttons…

Uploadcare library automatically initializes all inputs with role=“uploadcare-uploader” as widget instances. Sometimes it may cause the widget button shows doubled. You can try to turn off live widget initialization using this global variable:

UPLOADCARE_LIVE = false

I think it should help.

Of course there won’t be double buttons, but visible buttons won’t work either (as they are coupled with the wrong input). I need “live” behaviour, but invisible “template” inputs shouldn’t be initialised. For this I’d need to override selector.

Disabling live initialisation is not enough, you should manually init the widget for the fields you’re interested in:

UPLOADCARE_LIVE = false;
uploadcare.initialize('my-selector');

I wasn’t able to get it working with uploadcare.initialize