4

I'm trying to develop a custom block for the Gutenberg editor. I'm trying to display a button and call a web service then redirect the user to the returned URL. Can anyone please help me why my click handler function is not called?

wp.blocks.registerBlockType('brad/border-box', {
    title: 'Simple Box',
    icon: 'smiley',
    category: 'common',
    attributes: {
        content: {type: 'string'},
},

/* This configures how the content and color fields will work, and sets up the necessary elements */

edit: function (props) {
    function updateContent(event) {
        props.setAttributes({content: event.target.value})
    }

    return React.createElement(
        "div",
        null,
        React.createElement(
            "h3",
            null,
            "Simple Box"
        ),
        React.createElement("input", {type: "number", value: props.attributes.content, onChange: updateContent}),
    );
},


save: function (props) {
    function clickHandler(event) {
        alert('clicked')
    }

    return wp.element.createElement(
        "button",
        {style: {padding: '4px', border: '2px solid black'}, onClick: {clickHandler}},
        "Click On Me"
    );
}
})

1 Answer 1

8

The Block Editor's save() function doesn't save JS functions to the database to be run on the front end. To run JS on the front end, you need to save it as a separate file and enqueue that file explicitly on the front end.

With that in mind, it would be easiest to rewrite your save() function so that instead of trying to call a function directly, it has a specific CSS class you can target.

save: function (props) {
    return wp.element.createElement(
        "button",
        {style: {padding: '4px', border: '2px solid black'}, class: 'clicker'},
        "Click On Me"
    );
}

Then adjust your function and save it in its own clicker.js file:

(function($) {
    $(document).ready(function(){
        // Add a click handler to just these buttons
        $('button.clicker').on('click', clickHandler);
        // Define the clickHandler function, as before
        function clickHandler(event) {
            alert('clicked')
        }
    });
})(jQuery);

Finally, to enqueue the separate JS, edit your PHP file:

add_action('init', 'wpse_add_front_end_clicker_script');
function wpse_add_front_end_clicker_script() {
    wp_enqueue_script(
        'clicker',
        plugins_url('clicker.js', __FILE__),
        array('jquery'),
        filemtime( plugin_dir_path( __FILE__ ) . 'clicker.js' ),
        true
    );
}

This will enqueue the file with a jQuery dependency, and timestamp it so if you ever update the JS, it should avoid staying cached. (You may need to tweak some of the above code as I haven't tested it all together, but this should put you on the right path!)

1
  • It's too bad wordpress doesn't alert the dev they're trying to do something that isn't supported. I imagine a lot of devs familiar with react like myself naturally expected js to work. Silently failing in this instance feels odd
    – aaaaaa
    Commented Feb 14 at 23:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.