Detect changes to an input with changes via JS

Hi guys, I have a button created by js that is inside an agGrid cell and I have control over when this button is selected or not, this is the code in question

var dagcomponentfuncs = (window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {});

dagcomponentfuncs.launchBtn = function (props) {
    const onClick = (e) => {
        e.preventDefault();
    
        const currentButton = e.currentTarget;
        const isAlreadyClicked = currentButton.classList.contains('clicked');
        let detail = {value: props.value, clicked: !isAlreadyClicked};
    
        if (isAlreadyClicked) {
            currentButton.classList.remove('clicked');
        } else {
            document.querySelectorAll('.button-table.clicked').forEach(button => {
                button.classList.remove('clicked');
            });
            currentButton.classList.add('clicked');
        }
        
        // Disparar evento personalizado com o novo estado do botão
        window.dispatchEvent(new CustomEvent('buttonStateChange', { detail: detail }));

        // Selecionar o elemento input invisível e atualizar seu valor
        document.getElementById('invisible-input').value = JSON.stringify(detail);

        // Disparar um evento de mudança manualmente para que o Dash possa detectá-lo
        document.getElementById('invisible-input').dispatchEvent(new Event('change', { bubbles: true }));


    };

    return React.createElement('a', {
        target: '_blank',
        href:  '#',
        className: 'button-table',
        onClick: onClick,
    }, 'Ver pontos');
};

I’ll leave an image below and I’ll comment more with codes later on.

image

Note the input text changes correctly after the click but the text below doesn’t change at all, I even tried using an interval to make this work but it didn’t work:

    @dash_app.callback(
        Output('output-button-state', 'children'),
        [Input('invisible-input', 'value'),
        Input('interval-component', 'n_intervals')]
    )
    def update_output(value, n):
        print(value)
        if value:
            state = json.loads(value)
            clicked = state.get('clicked', False)
            return f"Botão clicado: {clicked}"
        return "Nenhum dado recebido."

How can I get the state of this button or get the value within the input so that it always detects the change coming from JS??

Hello @JackWtr,

This is an issue with things existing the DOM vs existing in the React, typically you cannot directly interact with each other.

However, in 2.16.0 a new clientside function was created, this allows direct interaction from JS functions to set props on a dash component.

This new function is called, dash_clienstide.set_props.

To use it, you can do this:

dash_clientside.set_props(id, {propsToSet})

So, for this example, you’d do this:

dash_clientside.set_props(‘invisible-input’, {value: newValue})

Where newValue is the new value you want to set.

3 Likes