1

I am a beginner in creating Gutenberg blocks. I want to create a custom block for a button. It should have an input field inside for the button text and the user should be able to choose between two button styles and the target URL in the InspectorControls area. But somehow my code doesn't work. The editor refreshes when I am inside of the input field and I am not able to access InspectorControls. Here is my code:

const InspectorControls = wp.editor.InspectorControls;
const PanelBody = wp.components.PanelBody;
const PanelRow = wp.components.PanelRow;
const RadioControl = wp.components.RadioControl;
const TextControl = wp.components.TextControl;


wp.blocks.registerBlockType('test-blocks/primary-button', {
    title: 'Primary Button',
    icon: 'button',
    category: 'test',
    attributes: {
        buttonText: {
            type: 'string'
        },
        buttonLink: {
            type: 'string'
        },
        buttonStyle: {
            type: 'string',
            default: "btn btn-primary"
        }
    },
    edit: function (props) {
        "use strict";

        function updateText(event) {
            props.setAttributes({
                buttonText: event.target.value
            });
        }

        function updateLink(event) {
            props.setAttributes({
                buttonLink: event.target.value
            });
        }

        function updateStyle(event) {
            props.setAttributes({
                buttonStyle: event.target.value
            });
        }
        return wp.element.createElement(
            "div",
            null,
            wp.element.createElement(
                "a", {
                    type: "button",
                    href: "",
                    class: props.attributes.buttonStyle
                },
                wp.element.createElement("input", {
                    type: "text",
                    value: props.attributes.buttonText,
                    onChange: updateText
                })
            ),
            wp.element.createElement(
                InspectorControls,
                null,
                wp.element.createElement(
                    PanelBody, {
                        title: "Button Settings",
                        initialOpen: true
                    },
                    wp.element.createElement(
                        PanelRow,
                        null,
                        wp.element.createElement(RadioControl, {
                            label: "Button Style",
                            value: props.attributes.buttonStyle,
                            options: [{
                                    label: "Primary",
                                    value: "btn btn-primary"
                                },
                                {
                                    label: "Secondary",
                                    value: "btn btn-secondary"
                                }
                            ],
                            onChange: updateStyle
                        })
                    ),
                    wp.element.createElement(
                        PanelRow,
                        null,
                        wp.element.createElement(TextControl, {
                            label: "Target URL",
                            value: props.attributes.buttonLink,
                            onChange: updateLink
                        })
                    )
                )
            )
        );


    },
    save: function (props) {
        "use strict";
        return wp.element.createElement("a", {
            type: "button",
            href: props.attributes.buttonLink,
            class: props.attributes.buttonStyle
        }, props.attributes.buttonText);
    }
});
2

I'd recommend looking at how the existing Button component works to get a sense of how Gutenberg does things. Specifically it uses a <RichText/> component (instead of a native <input>) which allows you to specify the tag name while also supporting user input.

Generally I'd advice against using <input> elements whenever possible. WordPress makes available a ton of components that can dramatically simplify your work.

For block styles, you may want to look at the styles attribute you can add to a block's definition. It will automatically create the UI necessary for a user to switch styles and output CSS classes to the block for styling. It may not match exactly what you have (e.g. btn btn-primary), but it will line up with the "proper" way of doing things in Gutenberg (e.g. is-style-primary).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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