Search code examples
javascriptdjangowagtailwagtail-streamfieldwagtail-admin

How to add custom js for select in Wagtail choice block


My goal is to have select (dropdowns) handled by custom-select js library for blocks in Wagtail Stream Field. As it is quite easy to add for normal fields when event DOMContentLoaded is triggered. But is there any event or hook for adding a block to StreamField?

I tried even calling my function in html template for block. But it seems to be called too early because styles are not applied to selects in this html.

this is my .js (typescript)

const initColorChoosers = () => {
const colorChoosers = Array.from(document.querySelectorAll('.color-chooser select')) as HTMLSelectElement[];
colorChoosers.forEach((chooser) => {
    if (!chooser.hasAttribute('custom')) {
        chooser.setAttribute("custom", "true")
        new CustomSelect(chooser, {
            customOptionClass: 'option--hero-glow-color'
        })
    }
})
}
document.addEventListener("DOMContentLoaded", function (event) {
    window.myfuncs.initColorChoosers = () => initColorChoosers();
});

and my color chooser:

class Colors(blocks.ChoiceBlock):
choices = [
    ('color1', 'color1'),
    ('color2', 'color2'),
    ('color2', 'color2'),
]
required = False,

class Meta:
    form_classname = 'color-chooser'
    icon = 'copy'

and block template at the end contains:

<script>
    window.myfuncs.initColorChoosers()
</script>

And it works.. but for already added blocks not for the current one. So if I add a block which contains ColorChooser, it won't apply logic from custom-select but when I add another one, for the first one changes will be applied.


Solution

  • You need to build a BlockAdapter (relevant to the block type - if it's a StructBlock, then StructBlockAdapter) and JavaScript Blockdefinition (same again, relevant to block type, StructBlock -> StructBlockDefinition.

    Wagtail docs: https://docs.wagtail.org/en/stable/advanced_topics/customisation/streamfield_blocks.html#additional-javascript-on-structblock-forms

    How to article: https://enzedonline.com/en/tech-blog/how-to-create-wagtail-streamfield-structblocks-with-a-customised-editor-interface/

    Wagtail will load an instance of the BlockDefintion each time you add that block to the streamfield.